mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
don't remove symlinks if they are already there
Consecutive "add" events will not remove and recreate the same symlinks anymore. No longer valid links, like after changing a filesystem label, will still be removed.
This commit is contained in:
parent
afb66e3233
commit
fa33d857e2
@ -862,6 +862,7 @@ EOF
|
||||
devpath => "/class/tty/tty0",
|
||||
exp_name => "link",
|
||||
exp_target => "link",
|
||||
exp_add_error => "yes",
|
||||
exp_rem_error => "yes",
|
||||
option => "clean",
|
||||
rules => <<EOF
|
||||
|
@ -132,17 +132,38 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev)
|
||||
/* read current database entry, we may want to cleanup symlinks */
|
||||
udev_old = udev_device_init();
|
||||
if (udev_old != NULL) {
|
||||
if (udev_db_get_device(udev_old, udev->dev->devpath) == 0) {
|
||||
info("device '%s' already known, remove possible symlinks", udev->dev->devpath);
|
||||
udev_node_remove_symlinks(udev_old);
|
||||
}
|
||||
udev_device_cleanup(udev_old);
|
||||
if (udev_db_get_device(udev_old, udev->dev->devpath) != 0) {
|
||||
udev_device_cleanup(udev_old);
|
||||
udev_old = NULL;
|
||||
} else
|
||||
info("device '%s' already in database, validate currently present symlinks",
|
||||
udev->dev->devpath);
|
||||
}
|
||||
|
||||
/* create node and symlinks, store record in database */
|
||||
/* create node and symlinks */
|
||||
retval = udev_node_add(udev, udev_old);
|
||||
if (retval == 0)
|
||||
if (retval == 0) {
|
||||
/* store record in database */
|
||||
udev_db_add_device(udev);
|
||||
|
||||
/* 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);
|
||||
udev_device_cleanup(udev_old);
|
||||
}
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
39
udev_node.c
39
udev_node.c
@ -90,6 +90,36 @@ exit:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int udev_node_symlink(struct udevice *udev, const char *linktarget, const char *filename)
|
||||
{
|
||||
char target[PATH_SIZE];
|
||||
int len;
|
||||
|
||||
/* look if symlink already exists */
|
||||
len = readlink(filename, target, sizeof(target));
|
||||
if (len > 0) {
|
||||
target[len] = '\0';
|
||||
if (strcmp(linktarget, target) == 0) {
|
||||
info("preserving symlink '%s' to '%s'", filename, linktarget);
|
||||
selinux_setfilecon(filename, NULL, S_IFLNK);
|
||||
goto exit;
|
||||
} else {
|
||||
info("link '%s' points to different target '%s', delete it", filename, target);
|
||||
unlink(filename);
|
||||
}
|
||||
}
|
||||
|
||||
/* create link */
|
||||
info("creating symlink '%s' to '%s'", filename, linktarget);
|
||||
selinux_setfscreatecon(filename, NULL, S_IFLNK);
|
||||
if (symlink(linktarget, filename) != 0)
|
||||
err("symlink(%s, %s) failed: %s", linktarget, filename, strerror(errno));
|
||||
selinux_resetfscreatecon();
|
||||
|
||||
exit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int udev_node_add(struct udevice *udev, struct udevice *udev_old)
|
||||
{
|
||||
char filename[PATH_SIZE];
|
||||
@ -205,13 +235,8 @@ int udev_node_add(struct udevice *udev, struct udevice *udev_old)
|
||||
strlcat(linktarget, &udev->name[tail], sizeof(linktarget));
|
||||
|
||||
info("creating symlink '%s' to '%s'", filename, linktarget);
|
||||
if (!udev->test_run) {
|
||||
unlink(filename);
|
||||
selinux_setfscreatecon(filename, NULL, S_IFLNK);
|
||||
if (symlink(linktarget, filename) != 0)
|
||||
err("symlink(%s, %s) failed: %s", linktarget, filename, strerror(errno));
|
||||
selinux_resetfscreatecon();
|
||||
}
|
||||
if (!udev->test_run)
|
||||
udev_node_symlink(udev, linktarget, filename);
|
||||
|
||||
strlcat(symlinks, filename, sizeof(symlinks));
|
||||
strlcat(symlinks, " ", sizeof(symlinks));
|
||||
|
Loading…
Reference in New Issue
Block a user