chiark / gitweb /
Merge nss-myhostname
[elogind.git] / src / udev / udev-event.c
index debda61eed653ec7d561720a742fcf535a6361ae..5eedf4f0dfdad2530eb5d25462dd654930ceba71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2010 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -48,7 +48,7 @@ struct udev_event *udev_event_new(struct udev_device *dev)
         event->udev = udev;
         udev_list_init(udev, &event->run_list, false);
         event->fd_signal = -1;
-        event->birth_usec = now_usec();
+        event->birth_usec = now(CLOCK_MONOTONIC);
         event->timeout_usec = 30 * 1000 * 1000;
         return event;
 }
@@ -90,24 +90,24 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
                 const char fmt;
                 enum subst_type type;
         } map[] = {
-                { .name = "devnode",        .fmt = 'N',        .type = SUBST_DEVNODE },
-                { .name = "tempnode",        .fmt = 'N',        .type = SUBST_DEVNODE },
-                { .name = "attr",        .fmt = 's',        .type = SUBST_ATTR },
-                { .name = "sysfs",        .fmt = 's',        .type = SUBST_ATTR },
-                { .name = "env",        .fmt = 'E',        .type = SUBST_ENV },
-                { .name = "kernel",        .fmt = 'k',        .type = SUBST_KERNEL },
-                { .name = "number",        .fmt = 'n',        .type = SUBST_KERNEL_NUMBER },
-                { .name = "driver",        .fmt = 'd',        .type = SUBST_DRIVER },
-                { .name = "devpath",        .fmt = 'p',        .type = SUBST_DEVPATH },
-                { .name = "id",                .fmt = 'b',        .type = SUBST_ID },
-                { .name = "major",        .fmt = 'M',        .type = SUBST_MAJOR },
-                { .name = "minor",        .fmt = 'm',        .type = SUBST_MINOR },
-                { .name = "result",        .fmt = 'c',        .type = SUBST_RESULT },
-                { .name = "parent",        .fmt = 'P',        .type = SUBST_PARENT },
-                { .name = "name",        .fmt = 'D',        .type = SUBST_NAME },
-                { .name = "links",        .fmt = 'L',        .type = SUBST_LINKS },
-                { .name = "root",        .fmt = 'r',        .type = SUBST_ROOT },
-                { .name = "sys",        .fmt = 'S',        .type = SUBST_SYS },
+                { .name = "devnode",  .fmt = 'N', .type = SUBST_DEVNODE },
+                { .name = "tempnode", .fmt = 'N', .type = SUBST_DEVNODE },
+                { .name = "attr",     .fmt = 's', .type = SUBST_ATTR },
+                { .name = "sysfs",    .fmt = 's', .type = SUBST_ATTR },
+                { .name = "env",      .fmt = 'E', .type = SUBST_ENV },
+                { .name = "kernel",   .fmt = 'k', .type = SUBST_KERNEL },
+                { .name = "number",   .fmt = 'n', .type = SUBST_KERNEL_NUMBER },
+                { .name = "driver",   .fmt = 'd', .type = SUBST_DRIVER },
+                { .name = "devpath",  .fmt = 'p', .type = SUBST_DEVPATH },
+                { .name = "id",       .fmt = 'b', .type = SUBST_ID },
+                { .name = "major",    .fmt = 'M', .type = SUBST_MAJOR },
+                { .name = "minor",    .fmt = 'm', .type = SUBST_MINOR },
+                { .name = "result",   .fmt = 'c', .type = SUBST_RESULT },
+                { .name = "parent",   .fmt = 'P', .type = SUBST_PARENT },
+                { .name = "name",     .fmt = 'D', .type = SUBST_NAME },
+                { .name = "links",    .fmt = 'L', .type = SUBST_LINKS },
+                { .name = "root",     .fmt = 'r', .type = SUBST_ROOT },
+                { .name = "sys",      .fmt = 'S', .type = SUBST_SYS },
         };
         const char *from;
         char *s;
@@ -132,8 +132,8 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
                                         goto copy;
                                 }
 
-                                for (i = 0; i < ARRAY_SIZE(map); i++) {
-                                        if (strncmp(&from[1], map[i].name, strlen(map[i].name)) == 0) {
+                                for (i = 0; i < ELEMENTSOF(map); i++) {
+                                        if (startswith(&from[1], map[i].name)) {
                                                 type = map[i].type;
                                                 from += strlen(map[i].name)+1;
                                                 goto subst;
@@ -148,7 +148,7 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
                                         goto copy;
                                 }
 
-                                for (i = 0; i < ARRAY_SIZE(map); i++) {
+                                for (i = 0; i < ELEMENTSOF(map); i++) {
                                         if (from[1] == map[i].fmt) {
                                                 type = map[i].type;
                                                 from += 2;
@@ -318,46 +318,38 @@ subst:
                         if (dev_parent == NULL)
                                 break;
                         devnode = udev_device_get_devnode(dev_parent);
-                        if (devnode != NULL) {
-                                size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
-
-                                l = util_strpcpy(&s, l, &devnode[devlen]);
-                        }
+                        if (devnode != NULL)
+                                l = util_strpcpy(&s, l, devnode + strlen("/dev/"));
                         break;
                 }
                 case SUBST_DEVNODE:
                         if (udev_device_get_devnode(dev) != NULL)
                                 l = util_strpcpy(&s, l, udev_device_get_devnode(dev));
                         break;
-                case SUBST_NAME: {
-                        if (event->name != NULL) {
+                case SUBST_NAME:
+                        if (event->name != NULL)
                                 l = util_strpcpy(&s, l, event->name);
-                        } else if (udev_device_get_devnode(dev) != NULL) {
-                                size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
-
-                                l = util_strpcpy(&s, l, &udev_device_get_devnode(dev)[devlen]);
-                        } else {
+                        else if (udev_device_get_devnode(dev) != NULL)
+                                l = util_strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
+                        else
                                 l = util_strpcpy(&s, l, udev_device_get_sysname(dev));
-                        }
                         break;
-                }
                 case SUBST_LINKS: {
-                        size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
                         struct udev_list_entry *list_entry;
 
                         list_entry = udev_device_get_devlinks_list_entry(dev);
                         if (list_entry == NULL)
                                 break;
-                        l = util_strpcpy(&s, l, &udev_list_entry_get_name(list_entry)[devlen]);
+                        l = util_strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
                         udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
-                                l = util_strpcpyl(&s, l, " ", &udev_list_entry_get_name(list_entry)[devlen], NULL);
+                                l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
                         break;
                 }
                 case SUBST_ROOT:
-                        l = util_strpcpy(&s, l, udev_get_dev_path(event->udev));
+                        l = util_strpcpy(&s, l, "/dev");
                         break;
                 case SUBST_SYS:
-                        l = util_strpcpy(&s, l, udev_get_sys_path(event->udev));
+                        l = util_strpcpy(&s, l, "/sys");
                         break;
                 case SUBST_ENV:
                         if (attr == NULL) {
@@ -474,9 +466,9 @@ static void spawn_read(struct udev_event *event,
                 int i;
 
                 if (event->timeout_usec > 0) {
-                        unsigned long long age_usec;
+                        usec_t age_usec;
 
-                        age_usec = now_usec() - event->birth_usec;
+                        age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
                         if (age_usec >= event->timeout_usec) {
                                 log_error("timeout '%s'\n", cmd);
                                 goto out;
@@ -486,7 +478,7 @@ static void spawn_read(struct udev_event *event,
                         timeout = -1;
                 }
 
-                fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), timeout);
+                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
                 if (fdcount < 0) {
                         if (errno == EINTR)
                                 continue;
@@ -562,9 +554,9 @@ static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
                 int fdcount;
 
                 if (event->timeout_usec > 0) {
-                        unsigned long long age_usec;
+                        usec_t age_usec;
 
-                        age_usec = now_usec() - event->birth_usec;
+                        age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
                         if (age_usec >= event->timeout_usec)
                                 timeout = 1000;
                         else
@@ -715,8 +707,8 @@ int udev_event_spawn(struct udev_event *event,
 
                 log_debug("starting '%s'\n", cmd);
 
-                err = spawn_exec(event, cmd, argv, envp, sigmask,
-                                 outpipe[WRITE_END], errpipe[WRITE_END]);
+                spawn_exec(event, cmd, argv, envp, sigmask,
+                           outpipe[WRITE_END], errpipe[WRITE_END]);
 
                 _exit(2 );
         case -1:
@@ -753,32 +745,11 @@ out:
         return err;
 }
 
-static void rename_netif_kernel_log(struct ifreq ifr)
-{
-        int klog;
-        FILE *f;
-
-        klog = open("/dev/kmsg", O_WRONLY);
-        if (klog < 0)
-                return;
-
-        f = fdopen(klog, "w");
-        if (f == NULL) {
-                close(klog);
-                return;
-        }
-
-        fprintf(f, "<30>udevd[%u]: renamed network interface %s to %s\n",
-                getpid(), ifr.ifr_name, ifr.ifr_newname);
-        fclose(f);
-}
-
 static int rename_netif(struct udev_event *event)
 {
         struct udev_device *dev = event->dev;
         int sk;
         struct ifreq ifr;
-        int loop;
         int err;
 
         log_debug("changing net interface name from '%s' to '%s'\n",
@@ -795,49 +766,12 @@ static int rename_netif(struct udev_event *event)
         util_strscpy(ifr.ifr_name, IFNAMSIZ, udev_device_get_sysname(dev));
         util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name);
         err = ioctl(sk, SIOCSIFNAME, &ifr);
-        if (err == 0) {
-                rename_netif_kernel_log(ifr);
-                goto out;
-        }
-
-        /* keep trying if the destination interface name already exists */
-        err = -errno;
-        if (err != -EEXIST)
-                goto out;
-
-        /* free our own name, another process may wait for us */
-        snprintf(ifr.ifr_newname, IFNAMSIZ, "rename%u", udev_device_get_ifindex(dev));
-        err = ioctl(sk, SIOCSIFNAME, &ifr);
-        if (err < 0) {
-                err = -errno;
-                goto out;
-        }
-
-        /* log temporary name */
-        rename_netif_kernel_log(ifr);
-
-        /* wait a maximum of 90 seconds for our target to become available */
-        util_strscpy(ifr.ifr_name, IFNAMSIZ, ifr.ifr_newname);
-        util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name);
-        loop = 90 * 20;
-        while (loop--) {
-                const struct timespec duration = { 0, 1000 * 1000 * 1000 / 20 };
-
-                nanosleep(&duration, NULL);
-
-                err = ioctl(sk, SIOCSIFNAME, &ifr);
-                if (err == 0) {
-                        rename_netif_kernel_log(ifr);
-                        break;
-                }
+        if (err >= 0) {
+                print_kmsg("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname);
+        } else {
                 err = -errno;
-                if (err != -EEXIST)
-                        break;
-        }
-
-out:
-        if (err < 0)
                 log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname);
+        }
         close(sk);
         return err;
 }
@@ -863,8 +797,10 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                 if (major(udev_device_get_devnum(dev)) != 0)
                         udev_node_remove(dev);
         } else {
-                event->dev_db = udev_device_new_from_syspath(event->udev, udev_device_get_syspath(dev));
+                event->dev_db = udev_device_new(event->udev);
                 if (event->dev_db != NULL) {
+                        udev_device_set_syspath(event->dev_db, udev_device_get_syspath(dev));
+                        udev_device_set_subsystem(event->dev_db, udev_device_get_subsystem(dev));
                         udev_device_read_db(event->dev_db, NULL);
                         udev_device_set_info_loaded(event->dev_db);
 
@@ -906,6 +842,12 @@ 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);
 
+                        if (!event->owner_set)
+                                event->uid = udev_device_get_devnode_uid(dev);
+
+                        if (!event->group_set)
+                                event->gid = udev_device_get_devnode_gid(dev);
+
                         if (!event->mode_set) {
                                 if (udev_device_get_devnode_mode(dev) > 0) {
                                         /* kernel supplied value */
@@ -926,7 +868,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                 if (event->dev_db != NULL && udev_device_get_usec_initialized(event->dev_db) > 0)
                         udev_device_set_usec_initialized(event->dev, udev_device_get_usec_initialized(event->dev_db));
                 else if (udev_device_get_usec_initialized(event->dev) == 0)
-                        udev_device_set_usec_initialized(event->dev, now_usec());
+                        udev_device_set_usec_initialized(event->dev, now(CLOCK_MONOTONIC));
 
                 /* (re)write database file */
                 udev_device_update_db(dev);