chiark / gitweb /
udevd: fix bogus mkdir invocation
[elogind.git] / src / udev / udevd.c
index 59e2cfac6b305661407c54e40d166be4eebcd696..a5478a754ed8ab270bf1e0a4c9f533a95ae4b834 100644 (file)
@@ -99,13 +99,9 @@ struct event {
         int ifindex;
 };
 
-static struct event *node_to_event(struct udev_list_node *node)
+static inline struct event *node_to_event(struct udev_list_node *node)
 {
-        char *event;
-
-        event = (char *)node;
-        event -= offsetof(struct event, node);
-        return (struct event *)event;
+        return container_of(node, struct event, node);
 }
 
 static void event_queue_cleanup(struct udev *udev, enum event_state type);
@@ -134,13 +130,9 @@ struct worker_message {
         int exitcode;
 };
 
-static struct worker *node_to_worker(struct udev_list_node *node)
+static inline struct worker *node_to_worker(struct udev_list_node *node)
 {
-        char *worker;
-
-        worker = (char *)node;
-        worker -= offsetof(struct worker, node);
-        return (struct worker *)worker;
+        return container_of(node, struct worker, node);
 }
 
 static void event_queue_delete(struct event *event, bool export)
@@ -270,6 +262,9 @@ static void worker_new(struct event *event)
                 /* request TERM signal if parent exits */
                 prctl(PR_SET_PDEATHSIG, SIGTERM);
 
+                /* reset OOM score, we only protect the main daemon */
+                write_one_line_file("/proc/self/oom_score_adj", "0");
+
                 for (;;) {
                         struct udev_event *udev_event;
                         struct worker_message msg;
@@ -811,7 +806,7 @@ static void static_dev_create_from_modules(struct udev *udev)
         FILE *f;
 
         uname(&kernel);
-        util_strscpyl(modules, sizeof(modules), "/lib/modules/", kernel.release, "/modules.devname", NULL);
+        util_strscpyl(modules, sizeof(modules), ROOTPREFIX "/lib/modules/", kernel.release, "/modules.devname", NULL);
         f = fopen(modules, "r");
         if (f == NULL)
                 return;
@@ -858,7 +853,7 @@ static void static_dev_create_from_modules(struct udev *udev)
                         continue;
 
                 util_strscpyl(filename, sizeof(filename), "/dev/", devname, NULL);
-                mkdir_parents(filename, 0755);
+                mkdir_parents_label(filename, 0755);
                 label_context_set(filename, mode);
                 log_debug("mknod '%s' %c%u:%u\n", filename, type, maj, min);
                 if (mknod(filename, mode, makedev(maj, min)) < 0 && errno == EEXIST)
@@ -904,8 +899,7 @@ static int convert_db(struct udev *udev)
                 return 0;
 
         /* make sure we do not get here again */
-        mkdir_parents("/run/udev/data", 0755);
-        mkdir(filename, 0755);
+        mkdir_p("/run/udev/data", 0755);
 
         /* old database */
         util_strscpyl(filename, sizeof(filename), "/dev/.udev/db", NULL);
@@ -914,7 +908,7 @@ static int convert_db(struct udev *udev)
 
         f = fopen("/dev/kmsg", "w");
         if (f != NULL) {
-                fprintf(f, "<30>udevd[%u]: converting old udev database\n", getpid());
+                fprintf(f, "<30>systemd-udevd[%u]: converting old udev database\n", getpid());
                 fclose(f);
         }
 
@@ -1018,6 +1012,48 @@ static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink)
         return 0;
 }
 
+/*
+ * read the kernel commandline, in case we need to get into debug mode
+ *   udev.log-priority=<level>              syslog priority
+ *   udev.children-max=<number of workers>  events are fully serialized if set to 1
+ *   udev.exec-delay=<number of seconds>    delay execution of every executed program
+ */
+static void kernel_cmdline_options(struct udev *udev)
+{
+        char *line, *w, *state;
+        size_t l;
+
+        if (read_one_line_file("/proc/cmdline", &line) < 0)
+                return;
+
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+                char *s, *opt;
+
+                s = strndup(w, l);
+                if (!s)
+                        break;
+
+                /* accept the same options for the initrd, prefixed with "rd." */
+                if (in_initrd() && startswith(s, "rd."))
+                        opt = s + 3;
+                else
+                        opt = s;
+
+                if (startswith(opt, "udev.log-priority="))
+                        udev_set_log_priority(udev, util_log_priority(opt + 18));
+
+                if (startswith(opt, "udev.children-max="))
+                        children_max = strtoul(opt + 18, NULL, 0);
+
+                if (startswith(opt, "udev.exec-delay="))
+                        exec_delay = strtoul(opt + 16, NULL, 0);
+
+                free(s);
+        }
+
+        free(line);
+}
+
 int main(int argc, char *argv[])
 {
         struct udev *udev;
@@ -1106,39 +1142,7 @@ int main(int argc, char *argv[])
                 }
         }
 
-        /*
-         * read the kernel commandline, in case we need to get into debug mode
-         *   udev.log-priority=<level>              syslog priority
-         *   udev.children-max=<number of workers>  events are fully serialized if set to 1
-         *
-         */
-        f = fopen("/proc/cmdline", "r");
-        if (f != NULL) {
-                char cmdline[4096];
-
-                if (fgets(cmdline, sizeof(cmdline), f) != NULL) {
-                        char *pos;
-
-                        pos = strstr(cmdline, "udev.log-priority=");
-                        if (pos != NULL) {
-                                pos += strlen("udev.log-priority=");
-                                udev_set_log_priority(udev, util_log_priority(pos));
-                        }
-
-                        pos = strstr(cmdline, "udev.children-max=");
-                        if (pos != NULL) {
-                                pos += strlen("udev.children-max=");
-                                children_max = strtoul(pos, NULL, 0);
-                        }
-
-                        pos = strstr(cmdline, "udev.exec-delay=");
-                        if (pos != NULL) {
-                                pos += strlen("udev.exec-delay=");
-                                exec_delay = strtoul(pos, NULL, 0);
-                        }
-                }
-                fclose(f);
-        }
+        kernel_cmdline_options(udev);
 
         if (getuid() != 0) {
                 fprintf(stderr, "root privileges required\n");
@@ -1238,7 +1242,6 @@ int main(int argc, char *argv[])
 
         if (daemonize) {
                 pid_t pid;
-                int fd;
 
                 pid = fork();
                 switch (pid) {
@@ -1255,18 +1258,14 @@ int main(int argc, char *argv[])
 
                 setsid();
 
-                fd = open("/proc/self/oom_score_adj", O_RDWR|O_CLOEXEC);
-                if (fd >= 0) {
-                        write(fd, "-1000", 5);
-                        close(fd);
-                }
+                write_one_line_file("/proc/self/oom_score_adj", "-1000");
         } else {
                 sd_notify(1, "READY=1");
         }
 
         f = fopen("/dev/kmsg", "w");
         if (f != NULL) {
-                fprintf(f, "<30>udevd[%u]: starting version " VERSION "\n", getpid());
+                fprintf(f, "<30>systemd-udevd[%u]: starting version " VERSION "\n", getpid());
                 fclose(f);
         }
 
@@ -1361,9 +1360,9 @@ int main(int argc, char *argv[])
 
                 /* set value depending on the amount of RAM */
                 if (memsize > 0)
-                        children_max = 128 + (memsize / 8);
+                        children_max = 16 + (memsize / 8);
                 else
-                        children_max = 128;
+                        children_max = 16;
         }
         log_debug("set children_max to %u\n", children_max);