X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udevd.c;h=de7cace3e191a962d5746efec0957c13436e1b4a;hp=5c51beed1e0d32d85a3d1332df28bfff19f964e9;hb=2f64aa4056835231ed297a79d39d5416e0045d0c;hpb=469aa1df95d90a047fa0030ff48fe4a06214fa5d diff --git a/udevd.c b/udevd.c index 5c51beed1..de7cace3e 100644 --- a/udevd.c +++ b/udevd.c @@ -45,6 +45,7 @@ #include "udev.h" #include "udev_rules.h" #include "udevd.h" +#include "udev_selinux.h" static struct udev_rules rules; static int udevd_sock = -1; @@ -565,6 +566,7 @@ static struct udevd_uevent_msg *get_msg_from_envbuf(const char *buf, int buf_siz int bufpos; int i; struct udevd_uevent_msg *msg; + char *physdevdriver_key = NULL; int major = 0; int minor = 0; @@ -599,6 +601,8 @@ static struct udevd_uevent_msg *get_msg_from_envbuf(const char *buf, int buf_siz msg->seqnum = strtoull(&key[7], NULL, 10); else if (strncmp(key, "PHYSDEVPATH=", 12) == 0) msg->physdevpath = &key[12]; + else if (strncmp(key, "PHYSDEVDRIVER=", 14) == 0) + physdevdriver_key = key; else if (strncmp(key, "MAJOR=", 6) == 0) major = strtoull(&key[6], NULL, 10); else if (strncmp(key, "MINOR=", 6) == 0) @@ -608,6 +612,13 @@ static struct udevd_uevent_msg *get_msg_from_envbuf(const char *buf, int buf_siz } msg->devt = makedev(major, minor); msg->envp[i++] = "UDEVD_EVENT=1"; + + if (msg->driver == NULL && msg->physdevpath == NULL && physdevdriver_key != NULL) { + /* for older kernels DRIVER is empty for a bus device, export PHYSDEVDRIVER as DRIVER */ + msg->envp[i++] = &physdevdriver_key[7]; + msg->driver = &physdevdriver_key[14]; + } + msg->envp[i] = NULL; if (msg->devpath == NULL || msg->action == NULL) { @@ -910,62 +921,56 @@ int main(int argc, char *argv[], char *envp[]) const char *value; int daemonize = 0; int i; - int rc = 0; + int rc = 1; int maxfd; - /* redirect std fd's, if the kernel forks us, we don't have them at all */ - fd = open("/dev/null", O_RDWR); - if (fd >= 0) { - if (fd != STDIN_FILENO) - dup2(fd, STDIN_FILENO); - if (fd != STDOUT_FILENO) - dup2(fd, STDOUT_FILENO); - if (fd != STDERR_FILENO) - dup2(fd, STDERR_FILENO); - if (fd > STDERR_FILENO) - close(fd); - } - logging_init("udevd"); - if (fd < 0) - err("fatal, could not open /dev/null: %s", strerror(errno)); - udev_config_init(); + selinux_init(); dbg("version %s", UDEV_VERSION); if (getuid() != 0) { - err("need to be root, exit"); + fprintf(stderr, "root privileges required\n"); + err("root privileges required"); goto exit; } /* parse commandline options */ for (i = 1 ; i < argc; i++) { char *arg = argv[i]; - if (strcmp(arg, "--daemon") == 0 || strcmp(arg, "-d") == 0) { - info("will daemonize"); + if (strcmp(arg, "--daemon") == 0 || strcmp(arg, "-d") == 0) daemonize = 1; + else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) { + printf("Usage: udevd [--help] [--daemon]\n"); + goto exit; + } else { + fprintf(stderr, "unrecognized option '%s'\n", arg); + err("unrecognized option '%s'\n", arg); } } /* init sockets to receive events */ if (init_udevd_socket() < 0) { if (errno == EADDRINUSE) { - err("another udevd running, exit"); + fprintf(stderr, "another udev daemon already running\n"); + err("another udev daemon already running"); rc = 1; } else { - err("error initializing udevd socket: %s", strerror(errno)); + fprintf(stderr, "error initializing udevd socket\n"); + err("error initializing udevd socket"); rc = 2; } goto exit; } if (init_uevent_netlink_sock() < 0) { - err("uevent socket not available"); + fprintf(stderr, "error initializing netlink socket\n"); + err("error initializing netlink socket"); rc = 3; goto exit; } - /* parse the rules and keep it in memory */ + /* parse the rules and keep them in memory */ sysfs_init(); udev_rules_init(&rules, 1); @@ -985,10 +990,22 @@ int main(int argc, char *argv[], char *envp[]) goto exit; default: dbg("child [%u] running, parent exits", pid); + rc = 0; goto exit; } } + /* redirect std fd's */ + fd = open("/dev/null", O_RDWR); + if (fd >= 0) { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + if (fd > STDERR_FILENO) + close(fd); + } else + err("error opening /dev/null: %s", strerror(errno)); + /* set scheduling priority for the daemon */ setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); @@ -1150,7 +1167,7 @@ int main(int argc, char *argv[], char *envp[]) } } - /* rules changed, set by inotify or a signal*/ + /* rules changed, set by inotify or a HUP signal */ if (reload_config) { reload_config = 0; udev_rules_cleanup(&rules); @@ -1169,6 +1186,7 @@ int main(int argc, char *argv[], char *envp[]) msg_queue_manager(); } } + rc = 0; exit: udev_rules_cleanup(&rules);