From 24f0605c1fec98b77eddb880a405289b08cb5670 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 18 Mar 2007 12:51:57 +0100 Subject: priority based symlink handling Symlinks can have priorities now, the priority is assigned to the device and specified with OPTIONS="link_priority=100". Devices with higher priorities overwrite the symlinks of devices with lower priorities. If the device, that currently owns the link goes away, the symlink will be removed, and recreated, pointing to the next device with the highest actual priority. This should solve the issue, that inserting an USB-stick may overwrite the /dev/disk/by-id/-link of another disk, and removes the entire link after the USB-stick is disconnected. If no priorities are specified, the new link will overwrite the current one, and if the device goes away, it will restore the old link. It should be possible to assign lower priorities to removable devices, if needed. In multipath setups, we see several devices, which all connect to the same volume, and therefore all try to create the same metadata-links. The different path-devices are combined into one device-mapper device, which also contains the same metadata. It should be possible, to assign multipath-table device-mapper devices a higher priority, so path-devices that appear and disappear, will not overwrite or delete the device-mapper device links. --- udev_device.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'udev_device.c') diff --git a/udev_device.c b/udev_device.c index 4cd5526dea..24f65ca045 100644 --- a/udev_device.c +++ b/udev_device.c @@ -173,28 +173,19 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) } } - /* create node and symlinks */ - retval = udev_node_add(udev, udev_old); - if (retval == 0) - udev_db_add_device(udev); + /* create node */ + retval = udev_node_add(udev); + if (retval != 0) + goto exit; - /* remove possibly left-over symlinks */ - if (udev_old != NULL) { - struct name_entry *link_loop; - struct name_entry *link_old_loop; - struct name_entry *link_old_tmp_loop; - - /* remove still valid symlinks from old list */ - list_for_each_entry_safe(link_old_loop, link_old_tmp_loop, &udev_old->symlink_list, node) - list_for_each_entry(link_loop, &udev->symlink_list, node) - if (strcmp(link_old_loop->name, link_loop->name) == 0) { - dbg("symlink '%s' still valid, keep it", link_old_loop->name); - list_del(&link_old_loop->node); - free(link_old_loop); - } - udev_node_remove_symlinks(udev_old); + /* store in database */ + udev_db_add_device(udev); + + /* create, replace, delete symlinks according to priority */ + udev_node_update_symlinks(udev, udev_old); + + if (udev_old != NULL) udev_device_cleanup(udev_old); - } goto exit; } @@ -251,7 +242,8 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) list_for_each_entry(name_loop, &udev->env_list, node) putenv(name_loop->name); } else { - dbg("'%s' not found in database, using kernel name '%s'", udev->dev->devpath, udev->dev->kernel); + dbg("'%s' not found in database, using kernel name '%s'", + udev->dev->devpath, udev->dev->kernel); strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name)); } @@ -261,7 +253,11 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) goto exit; } + /* remove the node */ retval = udev_node_remove(udev); + + /* delete or restore symlinks according to priority */ + udev_node_update_symlinks(udev, NULL); goto exit; } -- cgit v1.2.3-54-g00ecf