Index: udev-128/udev/lib/libudev-device.c
===================================================================
--- udev-128.orig/udev/lib/libudev-device.c
+++ udev-128/udev/lib/libudev-device.c
@@ -53,15 +53,12 @@ struct udev_device {
 	int ignore_remove;
 };
 
-static size_t devpath_to_db_path(struct udev *udev, const char *devpath, char *filename, size_t len)
+static size_t devpath_to_db_path(struct udev_device *udev_device, char *filename, size_t len)
 {
-	size_t start;
-
 	/* translate to location of db file */
-	util_strlcpy(filename, udev_get_dev_path(udev), len);
-	start = util_strlcat(filename, "/.udev/db/", len);
-	util_strlcat(filename, devpath, len);
-	return util_path_encode(&filename[start], len - start);
+	return snprintf(filename, len, "%s/.udev/db/%s:%s",
+			udev_get_dev_path(udev_device->udev),
+			udev_device->subsystem, udev_device->sysname);
 }
 
 static int device_read_db(struct udev_device *udev_device)
@@ -72,7 +69,7 @@ static int device_read_db(struct udev_de
 	FILE *f;
 	int rc = 0;
 
-	devpath_to_db_path(udev_device->udev, udev_device->devpath, filename, sizeof(filename));
+	devpath_to_db_path(udev_device, filename, sizeof(filename));
 
 	if (lstat(filename, &stats) != 0) {
 		info(udev_device->udev, "no db file to read %s: %s\n", filename, strerror(errno));
Index: udev-128/udev/udev.h
===================================================================
--- udev-128.orig/udev/udev.h
+++ udev-128/udev/udev.h
@@ -57,6 +57,7 @@ struct sysfs_device {
 	char devpath[UTIL_PATH_SIZE];
 	char subsystem[UTIL_NAME_SIZE];
 	char kernel[UTIL_NAME_SIZE];		/* device instance name */
+	char kernel_raw[UTIL_NAME_SIZE];	/* device instance name with '!' */
 	char kernel_number[UTIL_NAME_SIZE];
 	char driver[UTIL_NAME_SIZE];
 };
@@ -143,10 +144,10 @@ extern int udev_node_remove(struct udevi
 /* udev_db.c */
 extern int udev_db_add_device(struct udevice *udevice);
 extern int udev_db_delete_device(struct udevice *udevice);
-extern int udev_db_rename(struct udev *udev, const char *devpath_old, const char *devpath);
 extern int udev_db_get_device(struct udevice *udevice, const char *devpath);
 extern int udev_db_get_devices_by_name(struct udev *udev, const char *name, struct list_head *name_list);
 extern int udev_db_get_all_entries(struct udev *udevconst, struct list_head *name_list);
+extern int udev_db_convert_all_entries(struct udev *udev);
 
 /* udev_utils.c */
 struct name_entry {
Index: udev-128/udev/udev_db.c
===================================================================
--- udev-128.orig/udev/udev_db.c
+++ udev-128/udev/udev_db.c
@@ -30,15 +30,12 @@
 
 #include "udev.h"
 
-static size_t devpath_to_db_path(struct udev *udev, const char *devpath, char *filename, size_t len)
+static size_t devpath_to_db_path(struct udevice *udevice, char *filename, size_t len)
 {
-	size_t start;
-
 	/* translate to location of db file */
-	util_strlcpy(filename, udev_get_dev_path(udev), len);
-	start = util_strlcat(filename, "/.udev/db/", len);
-	util_strlcat(filename, devpath, len);
-	return util_path_encode(&filename[start], len - start);
+	return snprintf(filename, len, "%s/.udev/db/%s:%s",
+			udev_get_dev_path(udevice->udev),
+			udevice->dev->subsystem, udevice->dev->kernel_raw);
 }
 
 /* reverse mapping from the device file name to the devpath */
@@ -114,16 +111,6 @@ out:
 	return rc;
 }
 
-int udev_db_rename(struct udev *udev, const char *devpath_old, const char *devpath)
-{
-	char filename[UTIL_PATH_SIZE];
-	char filename_old[UTIL_PATH_SIZE];
-
-	devpath_to_db_path(udev, devpath_old, filename_old, sizeof(filename_old));
-	devpath_to_db_path(udev, devpath, filename, sizeof(filename));
-	return rename(filename_old, filename);
-}
-
 int udev_db_add_device(struct udevice *udevice)
 {
 	char filename[UTIL_PATH_SIZE];
@@ -131,7 +118,7 @@ int udev_db_add_device(struct udevice *u
 	if (udevice->test_run)
 		return 0;
 
-	devpath_to_db_path(udevice->udev, udevice->dev->devpath, filename, sizeof(filename));
+	devpath_to_db_path(udevice, filename, sizeof(filename));
 	create_path(udevice->udev, filename);
 	unlink(filename);
 
@@ -200,7 +187,7 @@ int udev_db_get_device(struct udevice *u
 	size_t count;
 
 	sysfs_device_set_values(udevice->udev, udevice->dev, devpath, NULL, NULL);
-	devpath_to_db_path(udevice->udev, devpath, filename, sizeof(filename));
+	devpath_to_db_path(udevice, filename, sizeof(filename));
 
 	if (lstat(filename, &stats) != 0) {
 		info(udevice->udev, "no db file to read %s: %s\n", filename, strerror(errno));
@@ -283,7 +270,7 @@ int udev_db_delete_device(struct udevice
 	if (udevice->test_run)
 		return 0;
 
-	devpath_to_db_path(udevice->udev, udevice->dev->devpath, filename, sizeof(filename));
+	devpath_to_db_path(udevice, filename, sizeof(filename));
 	unlink(filename);
 
 	name_index(udevice->udev, udevice->dev->devpath, udevice->name, 0);
@@ -309,6 +296,8 @@ int udev_db_get_all_entries(struct udev
 	while (1) {
 		struct dirent *ent;
 		char device[UTIL_PATH_SIZE];
+		char subsys[UTIL_PATH_SIZE];
+		char *name;
 
 		ent = readdir(dir);
 		if (ent == NULL || ent->d_name[0] == '\0')
@@ -316,11 +305,70 @@ int udev_db_get_all_entries(struct udev
 		if (ent->d_name[0] == '.')
 			continue;
 
-		util_strlcpy(device, ent->d_name, sizeof(device));
-		util_path_decode(device);
+		util_strlcpy(subsys, ent->d_name, sizeof(device));
+		name = strchr(subsys, ':');
+		if (name != NULL) {
+			name[0] = '\0';
+			name = &name[1];
+			if (!sysfs_lookup_devpath_by_subsys_id(udev, device, sizeof(device), subsys, name))
+				continue;
 		name_list_add(udev, name_list, device, 1);
 		dbg(udev, "added '%s'\n", device);
 	}
+	}
+
+	closedir(dir);
+	return 0;
+}
+
+int udev_db_convert_all_entries(struct udev *udev)
+{
+	char dbpath[PATH_MAX];
+	DIR *dir;
+
+	info(udev, "converting db...\n");
+
+	util_strlcpy(dbpath, udev_get_dev_path(udev), sizeof(dbpath));
+	util_strlcat(dbpath, "/.udev/db", sizeof(dbpath));
+	dir = opendir(dbpath);
+	if (dir == NULL) {
+		info(udev, "no udev_db available '%s': %s\n", dbpath, strerror(errno));
+		return -1;
+	}
+
+	while (1) {
+		struct dirent *ent;
+		struct udevice *udevice;
+		char devpath[UTIL_PATH_SIZE];
+		char from[UTIL_PATH_SIZE];
+		char to[UTIL_PATH_SIZE];
+
+		ent = readdir(dir);
+		if (ent == NULL || ent->d_name[0] == '\0')
+			break;
+		if (ent->d_name[0] == '.')
+			continue;
+
+		if (strncmp(ent->d_name, "\\x2f", 4) != 0)
+			continue;
+
+		util_strlcpy(from, dbpath, sizeof(from));
+		util_strlcat(from, "/", sizeof(from));
+		util_strlcat(from, ent->d_name, sizeof(from));
+
+		util_strlcpy(devpath, ent->d_name, sizeof(devpath));
+		util_path_decode(devpath);
+		udevice = udev_device_init(udev);
+		if (udevice == NULL)
+			continue;
+		sysfs_device_set_values(udev, udevice->dev, devpath, NULL, NULL);
+		devpath_to_db_path(udevice, to, sizeof(to));
+
+		info(udev, "converting db from %s to %s\n", from, to);
+		rename(from, to);
+
+		udev_device_cleanup(udevice);
+	}
 
 	closedir(dir);
 	return 0;
Index: udev-128/udev/udev_device_event.c
===================================================================
--- udev-128.orig/udev/udev_device_event.c
+++ udev-128/udev/udev_device_event.c
@@ -124,10 +124,6 @@ int udev_device_event(struct udev_rules
 {
 	int retval = 0;
 
-	if (udevice->devpath_old != NULL)
-		if (udev_db_rename(udevice->udev, udevice->devpath_old, udevice->dev->devpath) == 0)
-			info(udevice->udev, "moved database from '%s' to '%s'\n", udevice->devpath_old, udevice->dev->devpath);
-
 	/* add device node */
 	if (major(udevice->devt) != 0 &&
 	    (strcmp(udevice->action, "add") == 0 || strcmp(udevice->action, "change") == 0)) {
Index: udev-128/udev/udev_sysfs.c
===================================================================
--- udev-128.orig/udev/udev_sysfs.c
+++ udev-128/udev/udev_sysfs.c
@@ -72,8 +72,27 @@ void sysfs_device_set_values(struct udev
 	char *pos;
 
 	util_strlcpy(dev->devpath, devpath, sizeof(dev->devpath));
-	if (subsystem != NULL)
+
+	if (subsystem != NULL) {
 		util_strlcpy(dev->subsystem, subsystem, sizeof(dev->subsystem));
+	} else {
+		/* retrieve subsystem from sysfs, if not provided */
+		ssize_t len;
+		char filename[UTIL_PATH_SIZE];
+		char target[UTIL_PATH_SIZE];
+
+		util_strlcpy(filename, udev_get_sys_path(udev), sizeof(filename));
+		util_strlcat(filename, devpath, sizeof(filename));
+		util_strlcat(filename, "/subsystem", sizeof(filename));
+		len = readlink(filename, target, sizeof(target));
+		if (len > 0 && len < (ssize_t)sizeof(target)) {
+			target[len] = '\0';
+			pos = strrchr(target, '/');
+			if (pos != NULL)
+				util_strlcpy(dev->subsystem, &pos[1], sizeof(dev->subsystem));
+		}
+	}
+
 	if (driver != NULL)
 		util_strlcpy(dev->driver, driver, sizeof(dev->driver));
 
@@ -81,9 +100,8 @@ void sysfs_device_set_values(struct udev
 	pos = strrchr(dev->devpath, '/');
 	if (pos == NULL)
 		return;
+	util_strlcpy(dev->kernel_raw, &pos[1], sizeof(dev->kernel));
 	util_strlcpy(dev->kernel, &pos[1], sizeof(dev->kernel));
-	dbg(udev, "kernel='%s'\n", dev->kernel);
-
 	/* some devices have '!' in their name, change that to '/' */
 	pos = dev->kernel;
 	while (pos[0] != '\0') {
@@ -91,6 +109,7 @@ void sysfs_device_set_values(struct udev
 			pos[0] = '/';
 		pos++;
 	}
+	dbg(udev, "kernel='%s'\n", dev->kernel);
 
 	/* get kernel number */
 	pos = &dev->kernel[strlen(dev->kernel)];
@@ -387,25 +406,25 @@ int sysfs_lookup_devpath_by_subsys_id(st
 	if (strcmp(subsystem, "subsystem") == 0) {
 		util_strlcpy(path, "/subsystem/", sizeof(path_full) - sysfs_len);
 		util_strlcat(path, id, sizeof(path_full) - sysfs_len);
-		if (stat(path_full, &statbuf) == 0)
+		if (lstat(path_full, &statbuf) == 0)
 			goto found;
 
 		util_strlcpy(path, "/bus/", sizeof(path_full) - sysfs_len);
 		util_strlcat(path, id, sizeof(path_full) - sysfs_len);
-		if (stat(path_full, &statbuf) == 0)
+		if (lstat(path_full, &statbuf) == 0)
 			goto found;
 		goto out;
 
 		util_strlcpy(path, "/class/", sizeof(path_full) - sysfs_len);
 		util_strlcat(path, id, sizeof(path_full) - sysfs_len);
-		if (stat(path_full, &statbuf) == 0)
+		if (lstat(path_full, &statbuf) == 0)
 			goto found;
 	}
 
 	if (strcmp(subsystem, "module") == 0) {
 		util_strlcpy(path, "/module/", sizeof(path_full) - sysfs_len);
 		util_strlcat(path, id, sizeof(path_full) - sysfs_len);
-		if (stat(path_full, &statbuf) == 0)
+		if (lstat(path_full, &statbuf) == 0)
 			goto found;
 		goto out;
 	}
@@ -423,14 +442,14 @@ int sysfs_lookup_devpath_by_subsys_id(st
 			util_strlcat(path, subsys, sizeof(path_full) - sysfs_len);
 			util_strlcat(path, "/drivers/", sizeof(path_full) - sysfs_len);
 			util_strlcat(path, driver, sizeof(path_full) - sysfs_len);
-			if (stat(path_full, &statbuf) == 0)
+			if (lstat(path_full, &statbuf) == 0)
 				goto found;
 
 			util_strlcpy(path, "/bus/", sizeof(path_full) - sysfs_len);
 			util_strlcat(path, subsys, sizeof(path_full) - sysfs_len);
 			util_strlcat(path, "/drivers/", sizeof(path_full) - sysfs_len);
 			util_strlcat(path, driver, sizeof(path_full) - sysfs_len);
-			if (stat(path_full, &statbuf) == 0)
+			if (lstat(path_full, &statbuf) == 0)
 				goto found;
 		}
 		goto out;
@@ -440,21 +459,21 @@ int sysfs_lookup_devpath_by_subsys_id(st
 	util_strlcat(path, subsystem, sizeof(path_full) - sysfs_len);
 	util_strlcat(path, "/devices/", sizeof(path_full) - sysfs_len);
 	util_strlcat(path, id, sizeof(path_full) - sysfs_len);
-	if (stat(path_full, &statbuf) == 0)
+	if (lstat(path_full, &statbuf) == 0)
 		goto found;
 
 	util_strlcpy(path, "/bus/", sizeof(path_full) - sysfs_len);
 	util_strlcat(path, subsystem, sizeof(path_full) - sysfs_len);
 	util_strlcat(path, "/devices/", sizeof(path_full) - sysfs_len);
 	util_strlcat(path, id, sizeof(path_full) - sysfs_len);
-	if (stat(path_full, &statbuf) == 0)
+	if (lstat(path_full, &statbuf) == 0)
 		goto found;
 
 	util_strlcpy(path, "/class/", sizeof(path_full) - sysfs_len);
 	util_strlcat(path, subsystem, sizeof(path_full) - sysfs_len);
 	util_strlcat(path, "/", sizeof(path_full) - sysfs_len);
 	util_strlcat(path, id, sizeof(path_full) - sysfs_len);
-	if (stat(path_full, &statbuf) == 0)
+	if (lstat(path_full, &statbuf) == 0)
 		goto found;
 out:
 	return 0;
Index: udev-128/udev/udevadm-info.c
===================================================================
--- udev-128.orig/udev/udevadm-info.c
+++ udev-128/udev/udevadm-info.c
@@ -172,9 +172,10 @@ static void export_db(struct udev *udev)
 		udevice_db = udev_device_init(udev);
 		if (udevice_db == NULL)
 			continue;
-		if (udev_db_get_device(udevice_db, name_loop->name) == 0)
+		if (udev_db_get_device(udevice_db, name_loop->name) == 0) {
 			print_record(udevice_db);
 			printf("\n");
+		}
 		udev_device_cleanup(udevice_db);
 	}
 	name_list_cleanup(udev, &name_list);
@@ -259,6 +260,7 @@ int udevadm_info(struct udev *udev, int
 		{ "query", 1, NULL, 'q' },
 		{ "attribute-walk", 0, NULL, 'a' },
 		{ "export-db", 0, NULL, 'e' },
+		{ "convert-db", 0, NULL, 'C' }, /* internally used only */
 		{ "root", 0, NULL, 'r' },
 		{ "device-id-of-file", 1, NULL, 'd' },
 		{ "export", 0, NULL, 'x' },
@@ -293,7 +295,7 @@ int udevadm_info(struct udev *udev, int
 	while (1) {
 		int option;
 
-		option = getopt_long(argc, argv, "aed:n:p:q:rxPVh", options, NULL);
+		option = getopt_long(argc, argv, "aeCd:n:p:q:rxPVh", options, NULL);
 		if (option == -1)
 			break;
 
@@ -377,6 +379,9 @@ int udevadm_info(struct udev *udev, int
 		case 'e':
 			export_db(udev);
 			goto exit;
+		case 'C':
+			udev_db_convert_all_entries(udev);
+			goto exit;
 		case 'x':
 			export = 1;
 			break;
