summaryrefslogtreecommitdiff
path: root/udev
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2010-12-10 01:13:35 +0100
committerKay Sievers <kay.sievers@vrfy.org>2010-12-10 01:18:15 +0100
commit4281da1fa6fda10c15bee984825fc607a8385004 (patch)
treec92eaab4296a31bcccd754dc2b23410025158ef1 /udev
parentdc1791a9e6b59bd070a5f9c01b2214a1f8d69a82 (diff)
udevd: use dev_t or netif ifindex as database key
We need to preserve the database of network interfaces while we rename them. Use the kernel's numbers wherever possible, instead of the device names. Fix wrong database filenames which contain a '/', translated from '!' in the kernel name. Fix segfault for kobject pathes where the subsystem can not be determined from sysfs.
Diffstat (limited to 'udev')
-rw-r--r--udev/udev-event.c3
-rw-r--r--udev/udev-node.c6
-rw-r--r--udev/udev-watch.c6
-rw-r--r--udev/udevadm-info.c61
-rw-r--r--udev/udevadm.xml9
5 files changed, 76 insertions, 9 deletions
diff --git a/udev/udev-event.c b/udev/udev-event.c
index 064873531b..f41f06b16a 100644
--- a/udev/udev-event.c
+++ b/udev/udev-event.c
@@ -535,6 +535,9 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules)
struct udev_device *dev = event->dev;
int err = 0;
+ if (udev_device_get_subsystem(dev) == NULL)
+ return -1;
+
if (strcmp(udev_device_get_action(dev), "remove") == 0) {
udev_device_read_db(dev);
udev_device_delete_db(dev);
diff --git a/udev/udev-node.c b/udev/udev-node.c
index c8113f10b0..92634427f9 100644
--- a/udev/udev-node.c
+++ b/udev/udev-node.c
@@ -298,10 +298,8 @@ static void link_update(struct udev_device *dev, const char *slink, bool add)
dbg(udev, "update symlink '%s' of '%s'\n", slink, udev_device_get_syspath(dev));
util_path_encode(&slink[strlen(udev_get_dev_path(udev))+1], name_enc, sizeof(name_enc));
- snprintf(dirname, sizeof(dirname), "%s/.udev/links/%s", udev_get_dev_path(udev), name_enc);
- snprintf(filename, sizeof(filename), "%s/%c%u:%u", dirname,
- strcmp(udev_device_get_subsystem(dev), "block") == 0 ? 'b' : 'c',
- major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
+ util_strscpyl(dirname, sizeof(dirname), udev_get_dev_path(udev), "/.udev/links/", name_enc, NULL);
+ util_strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL);
if (!add) {
dbg(udev, "removing index: '%s'\n", filename);
diff --git a/udev/udev-watch.c b/udev/udev-watch.c
index 5fa60101c4..9e1b8d8553 100644
--- a/udev/udev-watch.c
+++ b/udev/udev-watch.c
@@ -109,7 +109,6 @@ unlink:
void udev_watch_begin(struct udev *udev, struct udev_device *dev)
{
char filename[UTIL_PATH_SIZE];
- char majmin[UTIL_PATH_SIZE];
int wd;
if (inotify_fd < 0)
@@ -123,13 +122,10 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev)
return;
}
- snprintf(majmin, sizeof(majmin), "%c%i:%i",
- strcmp(udev_device_get_subsystem(dev), "block") == 0 ? 'b' : 'c',
- major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
snprintf(filename, sizeof(filename), "%s/.udev/watch/%d", udev_get_dev_path(udev), wd);
util_create_path(udev, filename);
unlink(filename);
- symlink(majmin, filename);
+ symlink(udev_device_get_id_filename(dev), filename);
udev_device_set_watch_handle(dev, wd);
}
diff --git a/udev/udevadm-info.c b/udev/udevadm-info.c
index b3b31ebafe..7206f4fcf6 100644
--- a/udev/udevadm-info.c
+++ b/udev/udevadm-info.c
@@ -195,6 +195,60 @@ static int export_devices(struct udev *udev)
return 0;
}
+static int convert_db(struct udev *udev)
+{
+ struct udev_enumerate *udev_enumerate;
+ struct udev_list_entry *list_entry;
+
+ udev_enumerate = udev_enumerate_new(udev);
+ if (udev_enumerate == NULL)
+ return -1;
+ udev_enumerate_scan_devices(udev_enumerate);
+ udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
+ struct udev_device *device;
+
+ device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
+ if (device != NULL) {
+ const char *id;
+ struct stat statbuf;
+ char to[UTIL_PATH_SIZE];
+ char devpath[UTIL_PATH_SIZE];
+ char from[UTIL_PATH_SIZE];
+
+ id = udev_device_get_id_filename(device);
+ if (id == NULL)
+ goto next;
+ util_strscpyl(to, sizeof(to), udev_get_dev_path(udev), "/.udev/db/", id, NULL);
+
+ /* do not overwrite a new database file */
+ if (lstat(to, &statbuf) == 0)
+ goto next;
+
+ /* find old database with $subsys:$sysname */
+ util_strscpyl(from, sizeof(from), udev_get_dev_path(udev),
+ "/.udev/db/", udev_device_get_subsystem(device), ":",
+ udev_device_get_sysname(device), NULL);
+ if (lstat(from, &statbuf) == 0) {
+ rename(from, to);
+ goto next;
+ }
+
+ /* find old database with the encoded devpath */
+ util_path_encode(udev_device_get_devpath(device), devpath, sizeof(devpath));
+ util_strscpyl(from, sizeof(from), udev_get_dev_path(udev),
+ "/.udev/db/", devpath, NULL);
+ if (lstat(from, &statbuf) == 0) {
+ rename(from, to);
+ goto next;
+ }
+next:
+ udev_device_unref(device);
+ }
+ }
+ udev_enumerate_unref(udev_enumerate);
+ return 0;
+}
+
int udevadm_info(struct udev *udev, int argc, char *argv[])
{
struct udev_device *device = NULL;
@@ -212,6 +266,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
{ "query", required_argument, NULL, 'q' },
{ "attribute-walk", no_argument, NULL, 'a' },
{ "export-db", no_argument, NULL, 'e' },
+ { "convert-db", no_argument, NULL, 'C' },
{ "root", no_argument, NULL, 'r' },
{ "device-id-of-file", required_argument, NULL, 'd' },
{ "export", no_argument, NULL, 'x' },
@@ -336,6 +391,9 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
case 'e':
export_devices(udev);
goto exit;
+ case 'C':
+ convert_db(udev);
+ goto exit;
case 'x':
export = true;
break;
@@ -359,7 +417,10 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
" --attribute-walk print all key matches while walking along the chain\n"
" of parent devices\n"
" --device-id-of-file=<file> print major:minor of device containing this file\n"
+ " --export export key/value pairs\n"
+ " --export-prefix export the key name with a prefix\n"
" --export-db export the content of the udev database\n"
+ " --convert-db convert older version of database without a reboot\n"
" --help\n\n");
goto exit;
default:
diff --git a/udev/udevadm.xml b/udev/udevadm.xml
index cefd7763af..00f299fb73 100644
--- a/udev/udevadm.xml
+++ b/udev/udevadm.xml
@@ -144,6 +144,15 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><option>--convert-db</option></term>
+ <listitem>
+ <para>Convert the database of an earlier udev version to the current format. This
+ is only useful on udev version upgrades, where the content of the old database might
+ be needed for the running system, and it is not sufficient for it, to be re-created
+ with the next bootup.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><option>--version</option></term>
<listitem>
<para>Print version.</para>