From 5f59fa0900a5c127ce1a25d8ba3176f166662f96 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 15 Mar 2011 17:26:08 +0100 Subject: [PATCH] move /dev/.udev/ to /dev/.run/udev/ and convert old udev database at udevd startup --- Makefile.am | 2 +- NEWS | 12 ++++ extras/collect/collect.c | 2 +- extras/firmware/firmware.c | 2 +- libudev/libudev-device-private.c | 6 +- libudev/libudev-device.c | 46 ++++++++------- libudev/libudev-enumerate.c | 2 +- libudev/libudev-private.h | 2 +- libudev/libudev-queue-private.c | 10 ++-- libudev/libudev-queue.c | 4 +- udev/udev-event.c | 4 +- udev/udev-node.c | 2 +- udev/udev-rules.c | 2 +- udev/udev-watch.c | 10 ++-- udev/udev.xml | 2 +- udev/udevadm-info.c | 65 --------------------- udev/udevadm.xml | 9 --- udev/udevd.c | 98 +++++++++++++++++++++++++++++++- 18 files changed, 160 insertions(+), 120 deletions(-) diff --git a/Makefile.am b/Makefile.am index 62c3bdbd..15d1636f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,7 +35,7 @@ DISTCHECK_HOOKS = # libudev # ------------------------------------------------------------------------------ LIBUDEV_CURRENT=11 -LIBUDEV_REVISION=0 +LIBUDEV_REVISION=1 LIBUDEV_AGE=11 SUBDIRS += libudev/docs diff --git a/NEWS b/NEWS index b5008dbf..fcb6c75d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,18 @@ udev 167 ======== Bugfixes. +The udev runtime data moved from /dev/.udev/ to /dev/.run/udev/. +On new systems the tmpfs mountpoint /var/run/ will have an +"early-boot alias" /dev/.run/ where udev and a couple of other +early-boot tools will put their runtime data. +On systems with LVM used, packagers must make sure, that the +initramfs creates the /dev/.run/ mountpoint for udev to store +the data, so that the real root will not overmount it, which +would make it invisible. + +The command 'udevadm info --convert-db' is gone. The udev daemon +itself, at startup, converts any old database version if necessary. + udev 166 ======== Bugfixes. diff --git a/extras/collect/collect.c b/extras/collect/collect.c index 0069dea0..b5670516 100644 --- a/extras/collect/collect.c +++ b/extras/collect/collect.c @@ -34,7 +34,7 @@ #include "libudev.h" #include "libudev-private.h" -#define TMPFILE "/dev/.udev/collect" +#define TMPFILE "/dev/.run/udev/collect" #define BUFSIZE 16 #define UDEV_ALARM_TIMEOUT 180 diff --git a/extras/firmware/firmware.c b/extras/firmware/firmware.c index 76593bad..f7d21df6 100644 --- a/extras/firmware/firmware.c +++ b/extras/firmware/firmware.c @@ -147,7 +147,7 @@ int main(int argc, char **argv) } util_path_encode(firmware, fwencpath, sizeof(fwencpath)); - util_strscpyl(misspath, sizeof(misspath), udev_get_dev_path(udev), "/.udev/firmware-missing/", fwencpath, NULL); + util_strscpyl(misspath, sizeof(misspath), udev_get_dev_path(udev), "/.run/udev/firmware-missing/", fwencpath, NULL); util_strscpyl(loadpath, sizeof(loadpath), udev_get_sys_path(udev), devpath, "/loading", NULL); if (fwfile == NULL) { diff --git a/libudev/libudev-device-private.c b/libudev/libudev-device-private.c index 3afa82e0..7683f098 100644 --- a/libudev/libudev-device-private.c +++ b/libudev/libudev-device-private.c @@ -31,7 +31,7 @@ static void udev_device_tag(struct udev_device *dev, const char *tag, bool add) id = udev_device_get_id_filename(dev); if (id == NULL) return; - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/tags/", tag, "/", id, NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/tags/", tag, "/", id, NULL); if (add) { int fd; @@ -115,7 +115,7 @@ int udev_device_update_db(struct udev_device *udev_device) return -1; has_info = device_has_info(udev_device); - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/db/", id, NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3/", id, NULL); /* do not store anything for otherwise empty devices */ if (!has_info && @@ -176,7 +176,7 @@ int udev_device_delete_db(struct udev_device *udev_device) id = udev_device_get_id_filename(udev_device); if (id == NULL) return -1; - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/db/", id, NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3/", id, NULL); unlink(filename); return 0; } diff --git a/libudev/libudev-device.c b/libudev/libudev-device.c index c78cf9b7..dd0224ae 100644 --- a/libudev/libudev-device.c +++ b/libudev/libudev-device.c @@ -237,24 +237,30 @@ const char *udev_device_get_property_value(struct udev_device *udev_device, cons return udev_list_entry_get_value(list_entry); } -int udev_device_read_db(struct udev_device *udev_device) +int udev_device_read_db(struct udev_device *udev_device, const char *dbfile) { - const char *id; char filename[UTIL_PATH_SIZE]; char line[UTIL_LINE_SIZE]; FILE *f; - if (udev_device->db_loaded) - return 0; - udev_device->db_loaded = true; + /* providing a database file will always force-load it */ + if (dbfile == NULL) { + const char *id; - id = udev_device_get_id_filename(udev_device); - if (id == NULL) - return -1; - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/.udev/db/", id, NULL); - f = fopen(filename, "re"); + if (udev_device->db_loaded) + return 0; + udev_device->db_loaded = true; + + id = udev_device_get_id_filename(udev_device); + if (id == NULL) + return -1; + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/.run/udev/db3/", id, NULL); + dbfile = filename; + } + + f = fopen(dbfile, "re"); if (f == NULL) { - info(udev_device->udev, "no db file to read %s: %m\n", filename); + info(udev_device->udev, "no db file to read %s: %m\n", dbfile); return -1; } udev_device->is_initialized = true; @@ -908,7 +914,7 @@ const char *udev_device_get_devnode(struct udev_device *udev_device) return NULL; if (!udev_device->info_loaded) { udev_device_read_uevent_file(udev_device); - udev_device_read_db(udev_device); + udev_device_read_db(udev_device, NULL); } /* we might get called before we handled an event and have a db, use the kernel-provided name */ @@ -1002,7 +1008,7 @@ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device * if (udev_device == NULL) return NULL; if (!udev_device->info_loaded) - udev_device_read_db(udev_device); + udev_device_read_db(udev_device, NULL); return udev_list_get_entry(&udev_device->devlinks_list); } @@ -1030,7 +1036,7 @@ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device return NULL; if (!udev_device->info_loaded) { udev_device_read_uevent_file(udev_device); - udev_device_read_db(udev_device); + udev_device_read_db(udev_device, NULL); } if (!udev_device->devlinks_uptodate) { char symlinks[UTIL_PATH_SIZE]; @@ -1154,7 +1160,7 @@ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device if (udev_device == NULL) return 0; if (!udev_device->info_loaded) - udev_device_read_db(udev_device); + udev_device_read_db(udev_device, NULL); if (udev_device->usec_initialized == 0) return 0; now = usec_monotonic(); @@ -1471,7 +1477,7 @@ const char *udev_device_get_id_filename(struct udev_device *udev_device) int udev_device_get_is_initialized(struct udev_device *udev_device) { if (!udev_device->info_loaded) - udev_device_read_db(udev_device); + udev_device_read_db(udev_device, NULL); return udev_device->is_initialized; } @@ -1519,7 +1525,7 @@ int udev_device_has_tag(struct udev_device *udev_device, const char *tag) struct udev_list_entry *list_entry; if (!udev_device->info_loaded) - udev_device_read_db(udev_device); + udev_device_read_db(udev_device, NULL); list_entry = udev_device_get_tags_list_entry(udev_device); list_entry = udev_list_entry_get_by_name(list_entry, tag); if (list_entry != NULL) @@ -1689,7 +1695,7 @@ int udev_device_set_timeout(struct udev_device *udev_device, int timeout) int udev_device_get_event_timeout(struct udev_device *udev_device) { if (!udev_device->info_loaded) - udev_device_read_db(udev_device); + udev_device_read_db(udev_device, NULL); return udev_device->event_timeout; } @@ -1729,7 +1735,7 @@ int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum) int udev_device_get_devlink_priority(struct udev_device *udev_device) { if (!udev_device->info_loaded) - udev_device_read_db(udev_device); + udev_device_read_db(udev_device, NULL); return udev_device->devlink_priority; } @@ -1742,7 +1748,7 @@ int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio) int udev_device_get_watch_handle(struct udev_device *udev_device) { if (!udev_device->info_loaded) - udev_device_read_db(udev_device); + udev_device_read_db(udev_device, NULL); return udev_device->watch_handle; } diff --git a/libudev/libudev-enumerate.c b/libudev/libudev-enumerate.c index 128813c7..d3dd5c96 100644 --- a/libudev/libudev-enumerate.c +++ b/libudev/libudev-enumerate.c @@ -751,7 +751,7 @@ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate) struct dirent *dent; char path[UTIL_PATH_SIZE]; - util_strscpyl(path, sizeof(path), udev_get_dev_path(udev), "/.udev/tags/", + util_strscpyl(path, sizeof(path), udev_get_dev_path(udev), "/.run/udev/tags/", udev_list_entry_get_name(list_entry), NULL); dir = opendir(path); if (dir == NULL) diff --git a/libudev/libudev-private.h b/libudev/libudev-private.h index f95be53d..0fe6f4a6 100644 --- a/libudev/libudev-private.h +++ b/libudev/libudev-private.h @@ -78,7 +78,7 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device, int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_device); char **udev_device_get_properties_envp(struct udev_device *udev_device); ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf); -int udev_device_read_db(struct udev_device *udev_device); +int udev_device_read_db(struct udev_device *udev_device, const char *dbfile); int udev_device_read_uevent_file(struct udev_device *udev_device); int udev_device_set_action(struct udev_device *udev_device, const char *action); int udev_device_set_driver(struct udev_device *udev_device, const char *driver); diff --git a/libudev/libudev-queue-private.c b/libudev/libudev-queue-private.c index 06dc2f5e..9b02daf0 100644 --- a/libudev/libudev-queue-private.c +++ b/libudev/libudev-queue-private.c @@ -103,10 +103,10 @@ void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export) { char filename[UTIL_PATH_SIZE]; - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue_export->udev), "/.udev/queue.tmp", NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue_export->udev), "/.run/udev/queue.tmp", NULL); unlink(filename); - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue_export->udev), "/.udev/queue.bin", NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue_export->udev), "/.run/udev/queue.bin", NULL); unlink(filename); } @@ -221,7 +221,7 @@ static int rebuild_queue_file(struct udev_queue_export *udev_queue_export) } /* create new queue file */ - util_strscpyl(filename_tmp, sizeof(filename_tmp), udev_get_dev_path(udev_queue_export->udev), "/.udev/queue.tmp", NULL); + util_strscpyl(filename_tmp, sizeof(filename_tmp), udev_get_dev_path(udev_queue_export->udev), "/.run/udev/queue.tmp", NULL); new_queue_file = fopen(filename_tmp, "w+"); if (new_queue_file == NULL) goto error; @@ -255,7 +255,7 @@ static int rebuild_queue_file(struct udev_queue_export *udev_queue_export) goto error; /* rename the new file on top of the old one */ - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue_export->udev), "/.udev/queue.bin", NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue_export->udev), "/.run/udev/queue.bin", NULL); if (rename(filename_tmp, filename) != 0) goto error; @@ -401,7 +401,7 @@ static void update_failed(struct udev_queue_export *udev_queue_export, return; /* location of failed file */ - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/failed/", + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/failed/", udev_device_get_subsystem(udev_device), ":", udev_device_get_sysname(udev_device), NULL); switch (state) { diff --git a/libudev/libudev-queue.c b/libudev/libudev-queue.c index 163e6229..6f743d20 100644 --- a/libudev/libudev-queue.c +++ b/libudev/libudev-queue.c @@ -214,7 +214,7 @@ static FILE *open_queue_file(struct udev_queue *udev_queue, unsigned long long i char filename[UTIL_PATH_SIZE]; FILE *queue_file; - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue->udev), "/.udev/queue.bin", NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_queue->udev), "/.run/udev/queue.bin", NULL); queue_file = fopen(filename, "re"); if (queue_file == NULL) return NULL; @@ -484,7 +484,7 @@ struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev if (udev_queue == NULL) return NULL; udev_list_cleanup_entries(udev_queue->udev, &udev_queue->failed_list); - util_strscpyl(path, sizeof(path), udev_get_dev_path(udev_queue->udev), "/.udev/failed", NULL); + util_strscpyl(path, sizeof(path), udev_get_dev_path(udev_queue->udev), "/.run/udev/failed", NULL); dir = opendir(path); if (dir == NULL) return NULL; diff --git a/udev/udev-event.c b/udev/udev-event.c index 100a79c1..137ba367 100644 --- a/udev/udev-event.c +++ b/udev/udev-event.c @@ -539,7 +539,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules) return -1; if (strcmp(udev_device_get_action(dev), "remove") == 0) { - udev_device_read_db(dev); + udev_device_read_db(dev, NULL); udev_device_delete_db(dev); udev_device_tag_index(dev, NULL, false); @@ -553,7 +553,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules) } else { event->dev_db = udev_device_new_from_syspath(event->udev, udev_device_get_syspath(dev)); if (event->dev_db != NULL) { - udev_device_read_db(event->dev_db); + udev_device_read_db(event->dev_db, NULL); udev_device_set_info_loaded(event->dev_db); /* disable watch during event processing */ diff --git a/udev/udev-node.c b/udev/udev-node.c index 0ceb1d51..aaa2e32e 100644 --- a/udev/udev-node.c +++ b/udev/udev-node.c @@ -292,7 +292,7 @@ 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)); - util_strscpyl(dirname, sizeof(dirname), udev_get_dev_path(udev), "/.udev/links/", name_enc, NULL); + util_strscpyl(dirname, sizeof(dirname), udev_get_dev_path(udev), "/.run/udev/links/", name_enc, NULL); util_strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL); if (!add) { diff --git a/udev/udev-rules.c b/udev/udev-rules.c index 6b473c4c..4a5b8deb 100644 --- a/udev/udev-rules.c +++ b/udev/udev-rules.c @@ -1803,7 +1803,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) add_matching_files(udev, &file_list, SYSCONFDIR "/udev/rules.d", ".rules"); /* read dynamic/temporary rules */ - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/rules.d", NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/rules.d", NULL); udev_list_init(&sort_list); add_matching_files(udev, &sort_list, filename, ".rules"); diff --git a/udev/udev-watch.c b/udev/udev-watch.c index f51a10dc..47dca4c6 100644 --- a/udev/udev-watch.c +++ b/udev/udev-watch.c @@ -54,8 +54,8 @@ void udev_watch_restore(struct udev *udev) if (inotify_fd < 0) return; - util_strscpyl(oldname, sizeof(oldname), udev_get_dev_path(udev), "/.udev/watch.old", NULL); - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/watch", NULL); + util_strscpyl(oldname, sizeof(oldname), udev_get_dev_path(udev), "/.run/udev/watch.old", NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/watch", NULL); if (rename(filename, oldname) == 0) { DIR *dir; struct dirent *ent; @@ -118,7 +118,7 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev) return; } - snprintf(filename, sizeof(filename), "%s/.udev/watch/%d", udev_get_dev_path(udev), wd); + snprintf(filename, sizeof(filename), "%s/.run/udev/watch/%d", udev_get_dev_path(udev), wd); util_create_path(udev, filename); unlink(filename); symlink(udev_device_get_id_filename(dev), filename); @@ -141,7 +141,7 @@ void udev_watch_end(struct udev *udev, struct udev_device *dev) info(udev, "removing watch on '%s'\n", udev_device_get_devnode(dev)); inotify_rm_watch(inotify_fd, wd); - snprintf(filename, sizeof(filename), "%s/.udev/watch/%d", udev_get_dev_path(udev), wd); + snprintf(filename, sizeof(filename), "%s/.run/udev/watch/%d", udev_get_dev_path(udev), wd); unlink(filename); udev_device_set_watch_handle(dev, -1); @@ -158,7 +158,7 @@ struct udev_device *udev_watch_lookup(struct udev *udev, int wd) if (inotify_fd < 0 || wd < 0) return NULL; - snprintf(filename, sizeof(filename), "%s/.udev/watch/%d", udev_get_dev_path(udev), wd); + snprintf(filename, sizeof(filename), "%s/.run/udev/watch/%d", udev_get_dev_path(udev), wd); s = majmin; l = util_strpcpy(&s, sizeof(majmin), udev_get_sys_path(udev)); len = readlink(filename, s, l); diff --git a/udev/udev.xml b/udev/udev.xml index 3ef41033..452abc5c 100644 --- a/udev/udev.xml +++ b/udev/udev.xml @@ -73,7 +73,7 @@ The udev rules are read from the files located in the default rules directory /lib/udev/rules.d/, the custom rules directory /etc/udev/rules.d/ - and the temporary rules directory /dev/.udev/rules.d/. + and the temporary rules directory /var/run/udev/rules.d/. All rule files are sorted and processed in lexical order, regardless in which of these directories they live. Files in /etc/udev/rules.d/ have precedence over files with diff --git a/udev/udevadm-info.c b/udev/udevadm-info.c index 187e74d5..33d113c5 100644 --- a/udev/udevadm-info.c +++ b/udev/udevadm-info.c @@ -200,66 +200,6 @@ 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 stats; - 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) { - udev_device_unref(device); - continue; - } - util_strscpyl(to, sizeof(to), udev_get_dev_path(udev), "/.udev/db/", id, NULL); - - /* 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, &stats) == 0) { - if (lstat(to, &stats) == 0) - unlink(from); - else - rename(from, to); - } - - /* 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, &stats) == 0) { - if (lstat(to, &stats) == 0) - unlink(from); - else - rename(from, to); - } - - /* read the old database, and write out a new one */ - udev_device_read_db(device); - udev_device_update_db(device); - - 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; @@ -277,7 +217,6 @@ 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' }, @@ -402,9 +341,6 @@ 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; @@ -431,7 +367,6 @@ int udevadm_info(struct udev *udev, int argc, char *argv[]) " --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 00f299fb..cefd7763 100644 --- a/udev/udevadm.xml +++ b/udev/udevadm.xml @@ -143,15 +143,6 @@ Export the content of the udev database. - - - - 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. - - diff --git a/udev/udevd.c b/udev/udevd.c index aa2e3657..fe0e3c39 100644 --- a/udev/udevd.c +++ b/udev/udevd.c @@ -971,6 +971,99 @@ static int mem_size_mb(void) return memsize; } +static int convert_db(struct udev *udev) +{ + char filename[UTIL_PATH_SIZE]; + FILE *f; + struct udev_enumerate *udev_enumerate; + struct udev_list_entry *list_entry; + + /* current database */ + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3", NULL); + if (access(filename, F_OK) >= 0) + return 0; + + /* make sure we do not get here again */ + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3/", NULL); + util_create_path(udev, filename); + + /* old database */ + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/db", NULL); + if (access(filename, F_OK) < 0) + return 0; + + f = fopen("/dev/kmsg", "w"); + if (f != NULL) { + fprintf(f, "<6>udev[%u]: converting old udev database\n", getpid()); + fclose(f); + } + + 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) + continue; + + /* try to find the old database for devices without a current one */ + if (udev_device_read_db(device, NULL) < 0) { + bool have_db; + const char *id; + struct stat stats; + char devpath[UTIL_PATH_SIZE]; + char from[UTIL_PATH_SIZE]; + + have_db = false; + + /* find database in old location */ + id = udev_device_get_id_filename(device); + util_strscpyl(from, sizeof(from), udev_get_dev_path(udev), "/.udev/db/", id, NULL); + if (lstat(from, &stats) == 0) { + if (!have_db) { + udev_device_read_db(device, from); + have_db = true; + } + unlink(from); + } + + /* find old database with $subsys:$sysname name */ + 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, &stats) == 0) { + if (!have_db) { + udev_device_read_db(device, from); + have_db = true; + } + unlink(from); + } + + /* find old database with the encoded devpath name */ + 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, &stats) == 0) { + if (!have_db) { + udev_device_read_db(device, from); + have_db = true; + } + unlink(from); + } + + /* write out new database */ + if (have_db) + udev_device_update_db(device); + } + udev_device_unref(device); + } + udev_enumerate_unref(udev_enumerate); + return 0; +} + int main(int argc, char *argv[]) { struct udev *udev; @@ -1159,7 +1252,7 @@ int main(int argc, char *argv[]) IN_DELETE | IN_MOVE | IN_CLOSE_WRITE); /* watch dynamic rules directory */ - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/rules.d", NULL); + util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/rules.d", NULL); if (stat(filename, &statbuf) != 0) { util_create_path(udev, filename); udev_selinux_setfscreatecon(udev, filename, S_IFDIR|0755); @@ -1203,6 +1296,9 @@ int main(int argc, char *argv[]) goto exit; } + /* if needed, convert old database from earlier udev version */ + convert_db(udev); + if (!debug) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); -- 2.39.5