chiark / gitweb /
Docs: udev.xml: `are' -> `is'; the subject is `Access'
[elogind.git] / udev / udevd.c
index 2a42dfa765ae6979723f5507cf057a7af3510950..df5c1995bc9f06033c140b02b767b02b31986066 100644 (file)
@@ -75,7 +75,7 @@ static struct udev_rules *rules;
 static struct udev_queue_export *udev_queue_export;
 static struct udev_ctrl *udev_ctrl;
 static struct udev_monitor *monitor;
-static int worker_watch[2];
+static int worker_watch[2] = { -1, -1 };
 static pid_t settle_pid;
 static bool stop_exec_queue;
 static bool reload_config;
@@ -97,11 +97,11 @@ enum poll_fd {
 };
 
 static struct pollfd pfd[] = {
-       [FD_NETLINK] = { .events = POLLIN },
-       [FD_WORKER] =  { .events = POLLIN },
-       [FD_SIGNAL] =  { .events = POLLIN },
-       [FD_INOTIFY] = { .events = POLLIN },
-       [FD_CONTROL] = { .events = POLLIN },
+       [FD_NETLINK] = { .events = POLLIN, .fd = -1 },
+       [FD_WORKER] =  { .events = POLLIN, .fd = -1 },
+       [FD_SIGNAL] =  { .events = POLLIN, .fd = -1 },
+       [FD_INOTIFY] = { .events = POLLIN, .fd = -1 },
+       [FD_CONTROL] = { .events = POLLIN, .fd = -1 },
 };
 
 enum event_state {
@@ -822,7 +822,7 @@ static void static_dev_create_from_modules(struct udev *udev)
                        continue;
 
                util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/", devname, NULL);
-               util_create_path(udev, filename);
+               util_create_path_selinux(udev, filename);
                udev_selinux_setfscreatecon(udev, filename, mode);
                info(udev, "mknod '%s' %c%u:%u\n", filename, type, maj, min);
                if (mknod(filename, mode, makedev(maj, min)) < 0 && errno == EEXIST)
@@ -833,7 +833,7 @@ static void static_dev_create_from_modules(struct udev *udev)
        fclose(f);
 }
 
-static int copy_dir(struct udev *udev, DIR *dir_from, DIR *dir_to, int maxdepth)
+static int copy_dev_dir(struct udev *udev, DIR *dir_from, DIR *dir_to, int maxdepth)
 {
        struct dirent *dent;
 
@@ -886,7 +886,7 @@ static int copy_dir(struct udev *udev, DIR *dir_from, DIR *dir_to, int maxdepth)
                                continue;
                        }
 
-                       copy_dir(udev, dir2_from, dir2_to, maxdepth-1);
+                       copy_dev_dir(udev, dir2_from, dir2_to, maxdepth-1);
 
                        closedir(dir2_to);
                        closedir(dir2_from);
@@ -930,7 +930,7 @@ static void static_dev_create_from_devices(struct udev *udev, DIR *dir)
        dir_from = opendir(LIBEXECDIR "/devices");
        if (dir_from == NULL)
                return;
-       copy_dir(udev, dir_from, dir, 8);
+       copy_dev_dir(udev, dir_from, dir, 8);
        closedir(dir_from);
 }
 
@@ -979,13 +979,13 @@ static int convert_db(struct udev *udev)
        struct udev_list_entry *list_entry;
 
        /* current database */
-       util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3", NULL);
+       util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/data", NULL);
        if (access(filename, F_OK) >= 0)
                return 0;
 
        /* make sure we do not get here again */
-       util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/db3/", NULL);
        util_create_path(udev, filename);
+       mkdir(filename, 0755);
 
        /* old database */
        util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/db", NULL);
@@ -1044,8 +1044,7 @@ static int convert_db(struct udev *udev)
 
                        /* find old database with the encoded devpath name */
                        util_path_encode(udev_device_get_devpath(device), devpath, sizeof(devpath));
-                       util_strscpyl(from, sizeof(from), udev_get_dev_path(udev),
-                                     "/.udev/db/", devpath, NULL);
+                       util_strscpyl(from, sizeof(from), udev_get_dev_path(udev), "/.udev/db/", devpath, NULL);
                        if (lstat(from, &stats) == 0) {
                                if (!have_db) {
                                        udev_device_read_db(device, from);
@@ -1093,10 +1092,33 @@ int main(int argc, char *argv[])
        info(udev, "version %s\n", VERSION);
        udev_selinux_init(udev);
 
+       /* make sure, that our runtime dir exists and is writable */
+       if (utimensat(AT_FDCWD, udev_get_run_config_path(udev), NULL, 0) < 0) {
+               /* try to create our own subdirectory, do not create parent directories */
+               mkdir(udev_get_run_config_path(udev), 0755);
+
+               if (utimensat(AT_FDCWD, udev_get_run_config_path(udev), NULL, 0) >= 0) {
+                       /* directory seems writable now */
+                       udev_set_run_path(udev, udev_get_run_config_path(udev));
+               } else {
+                       /* fall back to /dev/.udev */
+                       char filename[UTIL_PATH_SIZE];
+
+                       util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev", NULL);
+                       if (udev_set_run_path(udev, filename) == NULL)
+                               goto exit;
+                       mkdir(udev_get_run_path(udev), 0755);
+               }
+       }
+       /* relabel runtime dir only if it resides below /dev */
+       if (strncmp(udev_get_run_path(udev), udev_get_dev_path(udev), strlen(udev_get_dev_path(udev))) == 0)
+               udev_selinux_lsetfilecon(udev, udev_get_run_path(udev), 0755);
+       info(udev, "runtime dir '%s'\n", udev_get_run_path(udev));
+
        for (;;) {
                int option;
 
-               option = getopt_long(argc, argv, "c:deDthV", options, NULL);
+               option = getopt_long(argc, argv, "c:deDtN:hV", options, NULL);
                if (option == -1)
                        break;
 
@@ -1206,16 +1228,20 @@ int main(int argc, char *argv[])
        if (write(STDERR_FILENO, 0, 0) < 0)
                dup2(fd, STDERR_FILENO);
 
-       udev_ctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
+       /* udevadm control socket */
+       if (sd_listen_fds(true) == 1 && sd_is_socket(SD_LISTEN_FDS_START, AF_LOCAL, SOCK_DGRAM, -1))
+               udev_ctrl = udev_ctrl_new_from_fd(udev, SD_LISTEN_FDS_START);
+       else
+               udev_ctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
        if (udev_ctrl == NULL) {
-               fprintf(stderr, "error initializing control socket");
-               err(udev, "error initializing udevd socket");
+               fprintf(stderr, "error initializing udev control socket");
+               err(udev, "error initializing udev control socket");
                rc = 1;
                goto exit;
        }
        if (udev_ctrl_enable_receiving(udev_ctrl) < 0) {
-               fprintf(stderr, "error binding control socket, seems udevd is already running\n");
-               err(udev, "error binding control socket, seems udevd is already running\n");
+               fprintf(stderr, "error binding udev control socket\n");
+               err(udev, "error binding udev control socket\n");
                rc = 1;
                goto exit;
        }
@@ -1252,12 +1278,10 @@ int main(int argc, char *argv[])
                                  IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
 
                /* watch dynamic rules directory */
-               util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.run/udev/rules.d", NULL);
+               util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/rules.d", NULL);
                if (stat(filename, &statbuf) != 0) {
                        util_create_path(udev, filename);
-                       udev_selinux_setfscreatecon(udev, filename, S_IFDIR|0755);
                        mkdir(filename, 0755);
-                       udev_selinux_resetfscreatecon(udev);
                }
                inotify_add_watch(pfd[FD_INOTIFY].fd, filename,
                                  IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);