summaryrefslogtreecommitdiff
path: root/udev/udevd.c
diff options
context:
space:
mode:
Diffstat (limited to 'udev/udevd.c')
-rw-r--r--udev/udevd.c98
1 files changed, 97 insertions, 1 deletions
diff --git a/udev/udevd.c b/udev/udevd.c
index aa2e3657f0..fe0e3c3929 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);