chiark / gitweb /
libudev: device - use DEVMODE from kernel as the default mode
authorKay Sievers <kay.sievers@vrfy.org>
Mon, 16 May 2011 20:04:02 +0000 (22:04 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Mon, 16 May 2011 20:04:02 +0000 (22:04 +0200)
TODO
libudev/libudev-device.c
libudev/libudev-private.h
libudev/test-libudev.c
test/udev-test.pl
udev/udev-event.c
udev/udev-rules.c
udev/udev.h

diff --git a/TODO b/TODO
index 7416c6f670a5335b008a7020c674e442f5b3cebe..2d43162095d4e5fc8b6d27f1d5cdb2eb886ab40c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,5 +1,3 @@
- - support kernel-supplied DEVMODE=
-
  - /run/udev/control socket
 
  - read settle_timout from udev.conf
index ffde21ad57d9d5274b56ff6871a4c30cfa19dcd1..d57a9eb59717c2c6fd692979e0fafe2e98d6c1a1 100644 (file)
@@ -51,6 +51,7 @@ struct udev_device {
        char *sysname;
        const char *sysnum;
        char *devnode;
+       mode_t devnode_mode;
        char *subsystem;
        char *devtype;
        char *driver;
@@ -199,6 +200,8 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device,
                udev_device_set_timeout(udev_device, strtoull(&property[8], NULL, 10));
        } else if (strncmp(property, "IFINDEX=", 8) == 0) {
                udev_device_set_ifindex(udev_device, strtoull(&property[8], NULL, 10));
+       } else if (strncmp(property, "DEVMODE=", 8) == 0) {
+               udev_device_set_devnode_mode(udev_device, strtoul(&property[8], NULL, 8));
        } else {
                udev_device_add_property_from_string(udev_device, property);
        }
@@ -343,6 +346,8 @@ int udev_device_read_uevent_file(struct udev_device *udev_device)
                        udev_device_set_ifindex(udev_device, strtoull(&line[8], NULL, 10));
                else if (strncmp(line, "DEVNAME=", 8) == 0)
                        udev_device_set_knodename(udev_device, &line[8]);
+               else if (strncmp(line, "DEVMODE=", 8) == 0)
+                       udev_device->devnode_mode = strtoul(&line[8], NULL, 8);
 
                udev_device_add_property_from_string(udev_device, line);
        }
@@ -930,6 +935,13 @@ const char *udev_device_get_devnode(struct udev_device *udev_device)
        return udev_device->devnode;
 }
 
+mode_t udev_device_get_devnode_mode(struct udev_device *udev_device)
+{
+       if (!udev_device->info_loaded)
+               udev_device_read_uevent_file(udev_device);
+       return udev_device->devnode_mode;
+}
+
 /**
  * udev_device_get_subsystem:
  * @udev_device: udev device
@@ -1414,6 +1426,16 @@ int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode
        return 0;
 }
 
+int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t mode)
+{
+       char num[32];
+
+       udev_device->devnode_mode = mode;
+       snprintf(num, sizeof(num), "%#o", mode);
+       udev_device_add_property(udev_device, "DEVMODE", num);
+       return 0;
+}
+
 int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink, int unique)
 {
        struct udev_list_entry *list_entry;
index 2fcfe4131c03a30f62996dbf9eb00ab59fc5ba05..39b46dde3154f810a01005bdb0c99aa51f511b4f 100644 (file)
@@ -69,6 +69,8 @@ struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev);
 /* libudev-device.c */
 struct udev_device *udev_device_new(struct udev *udev);
 struct udev_device *udev_device_new_from_id_filename(struct udev *udev, char *id);
+mode_t udev_device_get_devnode_mode(struct udev_device *udev_device);
+int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t mode);
 int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath);
 int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem);
 int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype);
index 4192ba14b24db7f65b98b3f0d7357704811a884a..966a4065078f4077a37fd86cbc57302b792f9453 100644 (file)
@@ -221,7 +221,7 @@ static int test_enumerate_print_list(struct udev_enumerate *enumerate)
 
 static int test_monitor(struct udev *udev)
 {
-       struct udev_monitor *udev_monitor;
+       struct udev_monitor *udev_monitor = NULL;
        int fd_ep;
        int fd_udev = -1;
        struct epoll_event ep_udev, ep_stdin;
index 4103cf0bff673110f510c12475cff4c50a0b4b64..4322da5ecd202d0fbce2f2a6f998739b48c85a05 100755 (executable)
@@ -1487,7 +1487,7 @@ EOF
                subsys          => "block",
                devpath         => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
                exp_name        => "sda",
-               exp_perms       => "0:0:0600",
+               exp_perms       => "0:0:0440",
                exp_rem_error   => "yes",
                rules           => <<EOF
 KERNEL=="sda", MODE="440"
index 4c51ed58e58ff33fb9cad7b02e2aca43966ea979..832abbbfce097007e8e2116054b562d5b5b58e58 100644 (file)
@@ -43,7 +43,6 @@ struct udev_event *udev_event_new(struct udev_device *dev)
        event = calloc(1, sizeof(struct udev_event));
        if (event == NULL)
                return NULL;
-       event->mode = 0600;
        event->dev = dev;
        event->udev = udev_device_get_udev(dev);
        udev_list_init(&event->run_list);
@@ -1021,9 +1020,18 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                        if (event->dev_db != NULL)
                                udev_node_update_old_links(dev, event->dev_db);
 
-                       /* change default 0600 to 0660 if a group is assigned */
-                       if (event->mode == 0600 && event->gid > 0)
-                               event->mode = 0660;
+                       if (!event->mode_set) {
+                               if (udev_device_get_devnode_mode(dev) > 0) {
+                                       /* kernel supplied value */
+                                       event->mode = udev_device_get_devnode_mode(dev);
+                               } else if (event->gid > 0) {
+                                       /* default 0660 if a group is assigned */
+                                       event->mode = 0660;
+                               } else {
+                                       /* default 0600 */
+                                       event->mode = 0600;
+                               }
+                       }
 
                        err = udev_node_add(dev, event->mode, event->uid, event->gid);
                }
index 892d8f27a76b0c07dfb9c1b1bde214b104393a4f..63123e083a9a5b6fd0e56ff575c2a42e3fe2fd96 100644 (file)
@@ -2443,19 +2443,22 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                        }
                case TK_A_MODE:
                        {
-                               char mode[UTIL_NAME_SIZE];
+                               char mode_str[UTIL_NAME_SIZE];
+                               mode_t mode;
                                char *endptr;
 
                                if (event->mode_final)
                                        break;
-                               if (cur->key.op == OP_ASSIGN_FINAL)
-                                       event->mode_final = true;
-                               udev_event_apply_format(event, &rules->buf[cur->key.value_off], mode, sizeof(mode));
-                               event->mode = strtol(mode, &endptr, 8);
+                               udev_event_apply_format(event, &rules->buf[cur->key.value_off], mode_str, sizeof(mode_str));
+                               mode = strtol(mode_str, &endptr, 8);
                                if (endptr[0] != '\0') {
-                                       err(event->udev, "invalide mode '%s' set default mode 0600\n", mode);
-                                       event->mode = 0600;
+                                       err(event->udev, "ignoring invalid mode '%s'\n", mode_str);
+                                       break;
                                }
+                               if (cur->key.op == OP_ASSIGN_FINAL)
+                                       event->mode_final = true;
+                               event->mode_set = true;
+                               event->mode = mode;
                                info(event->udev, "MODE %#o %s:%u\n",
                                     event->mode,
                                     &rules->buf[rule->rule.filename_off],
@@ -2489,6 +2492,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                break;
                        if (cur->key.op == OP_ASSIGN_FINAL)
                                event->mode_final = true;
+                       event->mode_set = true;
                        event->mode = cur->key.mode;
                        info(event->udev, "MODE %#o %s:%u\n",
                             event->mode,
index 16a029e4860ee4c7ef698755b7ad4ddc280ba067..88c32ec2032c53189921c9fc93ce4956eec1061a 100644 (file)
@@ -49,6 +49,7 @@ struct udev_event {
        bool inotify_watch_final;
        bool group_final;
        bool owner_final;
+       bool mode_set;
        bool mode_final;
        bool name_final;
        bool devlink_final;