chiark / gitweb /
udevd: use dev_t or netif ifindex as database key
[elogind.git] / udev / udev-node.c
index 8339eb732f0bd8b42e9a57be8aed5d5a823c9a26..92634427f95ecceca96e9f27f4422164cf7b3a9c 100644 (file)
@@ -56,10 +56,17 @@ int udev_node_mknod(struct udev_device *dev, const char *file, mode_t mode, uid_
                                info(udev, "set permissions %s, %#o, uid=%u, gid=%u\n", file, mode, uid, gid);
                                chmod(file, mode);
                                chown(file, uid, gid);
-                               udev_selinux_lsetfilecon(udev, file, mode);
                        } else {
                                info(udev, "preserve permissions %s, %#o, uid=%u, gid=%u\n", file, mode, uid, gid);
                        }
+                       /*
+                        * Set initial selinux file context only on add events.
+                        * We set the proper context on bootup (triger) or for newly
+                        * added devices, but we don't change it later, in case
+                        * something else has set a custom context in the meantime.
+                        */
+                       if (strcmp(udev_device_get_action(dev), "add") == 0)
+                               udev_selinux_lsetfilecon(udev, file, mode);
                        /* always update timestamp when we re-use the node, like on media change events */
                        utimensat(AT_FDCWD, file, NULL, 0);
                } else {
@@ -291,22 +298,20 @@ 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));
-       snprintf(dirname, sizeof(dirname), "%s/.udev/links/%s", udev_get_dev_path(udev), name_enc);
-       snprintf(filename, sizeof(filename), "%s/%c%u:%u", dirname,
-                strcmp(udev_device_get_subsystem(dev), "block") == 0 ? 'b' : 'c',
-                major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
+       util_strscpyl(dirname, sizeof(dirname), udev_get_dev_path(udev), "/.udev/links/", name_enc, NULL);
+       util_strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL);
 
        if (!add) {
                dbg(udev, "removing index: '%s'\n", filename);
-               unlink(filename);
-               util_delete_path(udev, filename);
+               if (unlink(filename) == 0)
+                       rmdir(dirname);
        }
 
        target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf));
        if (target == NULL) {
                info(udev, "no reference left, remove '%s'\n", slink);
-               unlink(slink);
-               util_delete_path(udev, slink);
+               if (unlink(slink) == 0)
+                       util_delete_path(udev, slink);
        } else {
                info(udev, "creating link '%s' to '%s'\n", slink, target);
                node_symlink(udev, target, slink);
@@ -427,7 +432,8 @@ int udev_node_remove(struct udev_device *dev)
 
        info(udev, "removing device node '%s'\n", devnode);
        err = util_unlink_secure(udev, devnode);
-       util_delete_path(udev, devnode);
+       if (err == 0)
+               util_delete_path(udev, devnode);
 out:
        return err;
 }