udevd.c revision f503f6b22fa54d1a65156a51d8b3311190c73ae5
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Copyright (C) 2004-2008 Kay Sievers <kay.sievers@vrfy.org>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers * Copyright (C) 2009 Canonical Ltd.
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * This program is free software: you can redistribute it and/or modify
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * it under the terms of the GNU General Public License as published by
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * the Free Software Foundation, either version 2 of the License, or
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * (at your option) any later version.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * This program is distributed in the hope that it will be useful,
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * GNU General Public License for more details.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * You should have received a copy of the GNU General Public License
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * along with this program. If not, see <http://www.gnu.org/licenses/>.
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera/* maximum limit of forked childs */
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocerastatic void log_fn(struct udev *udev, int priority,
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering const char *file, int line, const char *fn,
f975e971accc4d50c73ae53167db3df7a7099cf2Lennart Poettering fprintf(stderr, "[%d] %s: ", (int) getpid(), fn);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sieversstatic void reap_sigchilds(void);
92ec4495f76a7a2a6c31f5bb2a5240f78dcfe1d2Javier Jardónstatic struct udev_queue_export *udev_queue_export;
92ec4495f76a7a2a6c31f5bb2a5240f78dcfe1d2Javier Jardónstatic volatile sig_atomic_t sigchilds_waiting;
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmekstatic volatile sig_atomic_t udev_exit;
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmekstatic volatile sig_atomic_t reload_config;
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmekstatic volatile sig_atomic_t signal_received;
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmekstatic volatile pid_t settle_pid;
f975e971accc4d50c73ae53167db3df7a7099cf2Lennart Poetteringstatic struct udev_event *node_to_event(struct udev_list_node *node)
9c4fa6ed1069e98db5f01a5d1056b443a04cc7d9Lennart Poettering event -= offsetof(struct udev_event, node);
eb2e280f9c59b66965c9316eadc4c113a13ca744Lucas De Marchistatic void event_queue_delete(struct udev_event *event)
27765dfc7a32d790badb29e6498b34edb0b60c33Lennart Poettering /* mark as failed, if "add" event returns non-zero */
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (event->exitstatus && strcmp(udev_device_get_action(event->dev), "add") == 0)
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering udev_queue_export_device_failed(udev_queue_export, event->dev);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering udev_queue_export_device_finished(udev_queue_export, event->dev);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poetteringstatic void event_fork(struct udev_event *event)
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering /* single process, no forking, just for testing/profiling */
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering err = udev_event_execute_rules(event, rules);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (err == 0 && !event->ignore_device && udev_get_run(event->udev))
8745297f9853c4a17bac69e1b7e652fe81bc1940Lennart Poettering info(event->udev, "seq %llu exit with %i\n", udev_device_get_seqnum(event->dev), err);
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri fprintf(stderr, "fork %s (%llu)\n",
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY);
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering /* set signal handlers */
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering /* reset to default */
a8348796c0d39435b1c3d85ce6e95dad1ac85fecLennart Poettering /* set timeout to prevent hanging processes */
a8348796c0d39435b1c3d85ce6e95dad1ac85fecLennart Poettering /* apply rules, create node, symlinks */
b237ef2cfac7ab0b33170809e8cb64628606207dTollef Fog Heen err = udev_event_execute_rules(event, rules);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering /* rules may change/disable the timeout */
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers if (udev_device_get_event_timeout(event->dev) >= 0)
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers alarm(udev_device_get_event_timeout(event->dev));
728beb28a713709f521d374c9f8f3da781969d26Tom Gundersen /* execute RUN= */
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers if (err == 0 && !event->ignore_device && udev_get_run(event->udev))
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu /* apply/restore inotify watch */
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu /* send processed event back to the kernel netlink socket */
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu udev_monitor_send_device(kernel_monitor, event->dev);
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu info(event->udev, "seq %llu exit with %i\n", udev_device_get_seqnum(event->dev), err);
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering err(event->udev, "fork of child failed: %m\n");
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering /* get SIGCHLD in main loop */
56cf987fe74270bde4e16c7ec9e0414a9030723bDaniel J Walsh info(event->udev, "seq %llu forked, pid [%d], '%s' '%s', %ld seconds old\n",
807e17f05e217b474af39503efb9503d81b12596Lennart Poetteringstatic void event_queue_insert(struct udev_event *event)
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering udev_queue_export_device_queued(udev_queue_export, event->dev);
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering info(event->udev, "seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(event->dev),
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering udev_device_get_action(event->dev), udev_device_get_subsystem(event->dev));
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering udev_list_node_append(&event->node, &event_list);
0213c3f8102bdc934c629d11a44ca0b408762287Lennart Poettering /* run all events with a timeout set immediately */
0213c3f8102bdc934c629d11a44ca0b408762287Lennart Poettering if (udev_device_get_timeout(event->dev) > 0) {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering while (fgets(buf, sizeof(buf), f) != NULL) {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering if (sscanf(buf, "MemTotal: %ld kB", &value) == 1) {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poetteringstatic int compare_devpath(const char *running, const char *waiting)
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering while (running[i] != '\0' && running[i] == waiting[i])
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* identical device event found */
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering if (running[i] == '\0' && waiting[i] == '\0')
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* parent device event found */
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering if (running[i] == '\0' && waiting[i] == '/')
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* child device event found */
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering if (running[i] == '/' && waiting[i] == '\0')
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* no matching event */
812cce323db081634f37e4ec6d29f2b9328a3f52Lennart Poettering/* lookup event for identical, parent, child device */
812cce323db081634f37e4ec6d29f2b9328a3f52Lennart Poetteringstatic int devpath_busy(struct udev_event *event)
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering /* check if queue contains events we depend on */
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering udev_list_node_foreach(loop, &event_list) {
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering struct udev_event *loop_event = node_to_event(loop);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers /* we already found a later event, earlier can not block us, no need to check again */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (udev_device_get_seqnum(loop_event->dev) < event->delaying_seqnum)
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering /* event we checked earlier still exists, no need to check again */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (udev_device_get_seqnum(loop_event->dev) == event->delaying_seqnum)
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering /* found ourself, no later event can block us */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (udev_device_get_seqnum(loop_event->dev) >= udev_device_get_seqnum(event->dev))
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering /* check our old name */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (udev_device_get_devpath_old(event->dev) != NULL)
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (strcmp(udev_device_get_devpath(loop_event->dev), udev_device_get_devpath_old(event->dev)) == 0) {
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering event->delaying_seqnum = udev_device_get_seqnum(loop_event->dev);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering /* check identical, parent, or child device event */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (compare_devpath(udev_device_get_devpath(loop_event->dev), udev_device_get_devpath(event->dev)) != 0) {
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering dbg(event->udev, "%llu, device event still pending %llu (%s)\n",
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering udev_device_get_devpath(loop_event->dev));
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering event->delaying_seqnum = udev_device_get_seqnum(loop_event->dev);
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering /* check for our major:minor number */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering if (major(udev_device_get_devnum(event->dev)) > 0 &&
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering udev_device_get_devnum(loop_event->dev) == udev_device_get_devnum(event->dev) &&
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering strcmp(udev_device_get_subsystem(event->dev), udev_device_get_subsystem(loop_event->dev)) == 0) {
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering dbg(event->udev, "%llu, device event still pending %llu (%d:%d)\n",
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering major(udev_device_get_devnum(loop_event->dev)), minor(udev_device_get_devnum(loop_event->dev)));
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering event->delaying_seqnum = udev_device_get_seqnum(loop_event->dev);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering/* serializes events for the identical and parent and child devices */
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poetteringstatic void event_queue_manager(struct udev *udev)
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering err(udev, "event list empty, but childs count is %i", childs);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering udev_list_node_foreach_safe(loop, tmp, &event_list) {
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering struct udev_event *loop_event = node_to_event(loop);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering info(udev, "maximum number (%i) of childs reached\n", childs);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering /* do not start event if parent or child event is still running */
4927fcae48de061393b3ce9c12d49f80d73fbf1dLennart Poettering udev_device_get_devpath(loop_event->dev));
4927fcae48de061393b3ce9c12d49f80d73fbf1dLennart Poettering dbg(udev, "moved seq %llu to running list\n", udev_device_get_seqnum(loop_event->dev));
4927fcae48de061393b3ce9c12d49f80d73fbf1dLennart Poettering /* retry if events finished in the meantime */
4927fcae48de061393b3ce9c12d49f80d73fbf1dLennart Poettering/* receive the udevd message from userspace */
4927fcae48de061393b3ce9c12d49f80d73fbf1dLennart Poetteringstatic void handle_ctrl_msg(struct udev_ctrl *uctrl)
4927fcae48de061393b3ce9c12d49f80d73fbf1dLennart Poettering struct udev *udev = udev_ctrl_get_udev(uctrl);
4927fcae48de061393b3ce9c12d49f80d73fbf1dLennart Poettering i = udev_ctrl_get_set_log_level(ctrl_msg);
4927fcae48de061393b3ce9c12d49f80d73fbf1dLennart Poettering info(udev, "udevd message (SET_LOG_PRIORITY) received, log_priority=%i\n", i);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) {
7f4e08056de0184b205a20632e62db73d299937eLennart Poettering info(udev, "udevd message (STOP_EXEC_QUEUE) received\n");
7f4e08056de0184b205a20632e62db73d299937eLennart Poettering if (udev_ctrl_get_start_exec_queue(ctrl_msg) > 0) {
7f4e08056de0184b205a20632e62db73d299937eLennart Poettering info(udev, "udevd message (START_EXEC_QUEUE) received\n");
7f4e08056de0184b205a20632e62db73d299937eLennart Poettering if (udev_ctrl_get_reload_rules(ctrl_msg) > 0) {
f6a971bc0bf1252e9614919ccca0d53db5fc53d9Lennart Poettering info(udev, "udevd message (RELOAD_RULES) received\n");
27669061f40766457db93d5cc3dfe00dce240806Miklos Vajna info(udev, "udevd message (ENV) received, unset '%s'\n", key);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers info(udev, "udevd message (ENV) received, set '%s=%s'\n", key, val);
e5e83e8362e946890ac991fc86a2c5869f9befdfLennart Poettering i = udev_ctrl_get_set_max_childs(ctrl_msg);
be31376e6c9add0786f31a38eec2ecfdb73eb115Kay Sievers info(udev, "udevd message (SET_MAX_CHILDS) received, max_childs=%i\n", i);
4de856120f252e7aa19c923c10fbf23310d623aaLennart Poettering info(udev, "udevd message (SETTLE) received\n");
4de856120f252e7aa19c923c10fbf23310d623aaLennart Poettering/* read inotify messages */
4de856120f252e7aa19c923c10fbf23310d623aaLennart Poettering if ((ioctl(inotify_fd, FIONREAD, &nbytes) < 0) || (nbytes <= 0))
2a018e83ded29c9719b2478a65ee6245c829c0f5Kay Sievers err(udev, "error getting buffer for inotify, disable watching\n");
b2e9fb99ab288e8817302851743ed1a3cddd384bMiklos Vajna for (pos = 0; pos < nbytes; pos += sizeof(struct inotify_event) + ev->len) {
b2e9fb99ab288e8817302851743ed1a3cddd384bMiklos Vajna dbg(udev, "inotify event: %x for %s\n", ev->mask, ev->name);
f47cd184c0ff80e025428e9e385e61bda1ef3d69Miklos Vajna dbg(udev, "inotify event: %x for %s\n", ev->mask, udev_device_get_devnode(dev));
4cd1eaa54507a65286413363216ad407fa7c6e50Miklos Vajna info(udev, "device %s closed, synthesising 'change'\n", udev_device_get_devnode(dev));
be31376e6c9add0786f31a38eec2ecfdb73eb115Kay Sievers util_strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers /* set flag, then write to pipe if needed */
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers /* find event associated with pid and delete it */
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers struct udev_event *loop_event = node_to_event(loop);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers info(loop_event->udev, "seq %llu cleanup, pid [%d], status %i, %ld seconds old\n",
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers udev_device_get_seqnum(loop_event->dev), loop_event->pid,
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers exitstatus, time(NULL) - loop_event->queue_time);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers /* there may be dependent events waiting */
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sieversstatic void reap_sigchilds(void)
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmekstatic void startup_log(struct udev *udev)
8401e9f91d65c3d8d49cf0d2e35d03146354e957Auke Kok fprintf(f, "<6>udev: starting version " VERSION "\n");
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering util_strscpyl(path, sizeof(path), udev_get_sys_path(udev), "/class/mem/null", NULL);
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering if (lstat(path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
c87f7103fe38434f0b88df5c2b080c7b558feabfZbigniew Jędrzejewski-Szmek "udev: missing sysfs features; please update the kernel "
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering "or disable the kernel's CONFIG_SYSFS_DEPRECATED option; "
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering "udev may fail to work correctly";
f975e971accc4d50c73ae53167db3df7a7099cf2Lennart Poettering { "debug-trace", no_argument, NULL, 't' },
858dae181bb5461201ac1c04732d3ef4c67a0256Andrew Edmunds { "resolve-names", required_argument, NULL, 'N' },
f2b4af1cd4112df6ce56f8fc1e677639935e3d0eFabian Henze option = getopt_long(argc, argv, "dDthV", options, NULL);
f975e971accc4d50c73ae53167db3df7a7099cf2Lennart Poettering } else if (strcmp (optarg, "never") == 0) {
1bd8b8184ee3bc7fc023d6d6dfb2ca99fb6612f3Koen Kooi fprintf(stderr, "resolve-names must be early, late or never\n");
1bd8b8184ee3bc7fc023d6d6dfb2ca99fb6612f3Koen Kooi err(udev, "resolve-names must be early, late or never\n");
6fdae8a6a40d6a3b5f77516abaee23b3eab002f6Dexter Morgan printf("Usage: udevd [--help] [--daemon] [--debug-trace] [--debug] "
fbf5b12653e29674b1e85c73d446b13ac3a15b38Colin Guthrie "[--resolve-names=early|late|never] [--version]\n");
be31376e6c9add0786f31a38eec2ecfdb73eb115Kay Sievers if (getuid() != 0) {
136337ff74f05be3d42a769d9f0cb99716c5c40fTollef Fog Heen /* make sure std{in,out,err} fd's are in a sane state */
07459bb6b92268beb2599f65cf195708d88c51ccFabiano Fidêncio /* init control socket, bind() ensures, that only one udevd instance is running */
f975e971accc4d50c73ae53167db3df7a7099cf2Lennart Poettering udev_ctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
07459bb6b92268beb2599f65cf195708d88c51ccFabiano Fidêncio fprintf(stderr, "error initializing control socket");
07459bb6b92268beb2599f65cf195708d88c51ccFabiano Fidêncio err(udev, "error initializing udevd socket");
a05ea46dc788929bc8b13afb4208ca29cad68572Michael Biebl if (udev_ctrl_enable_receiving(udev_ctrl) < 0) {
bef2733fae665e880da6ea011b1f918e6900bb42Lennart Poettering fprintf(stderr, "error binding control socket, seems udevd is already running\n");
bef2733fae665e880da6ea011b1f918e6900bb42Lennart Poettering err(udev, "error binding control socket, seems udevd is already running\n");
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel");
858dae181bb5461201ac1c04732d3ef4c67a0256Andrew Edmunds if (kernel_monitor == NULL || udev_monitor_enable_receiving(kernel_monitor) < 0) {
858dae181bb5461201ac1c04732d3ef4c67a0256Andrew Edmunds fprintf(stderr, "error initializing netlink socket\n");
d7c114c00030309435fc56c77c8578a25d228ebeDave Reisner err(udev, "error initializing netlink socket\n");
a338bab5d0603a179befce062bc6fc8a6521a232Alexey Shabalin udev_monitor_set_receive_buffer_size(kernel_monitor, 128*1024*1024);
d2d12cd1bfd90f3a13273d82331a7cbd36a93231Lennart Poettering udev_queue_export = udev_queue_export_new(udev);
d2d12cd1bfd90f3a13273d82331a7cbd36a93231Lennart Poettering err(udev, "error creating queue file\n");
d2d12cd1bfd90f3a13273d82331a7cbd36a93231Lennart Poettering err(udev, "fork of daemon failed: %m\n");
b8079ae19b41c9b61850c796dddc601b826850e0Kay Sievers dbg(udev, "child [%u] running, parent exits\n", pid);
ae446765eb0605d2451bb4dd7c336672bcc7ab0cKay Sievers /* redirect std{out,err} */
bc9bdbbab45ea2c10fdd8ad7c517b5e4a358bdfbMichał Górny /* set scheduling priority for the daemon */
bc9bdbbab45ea2c10fdd8ad7c517b5e4a358bdfbMichał Górny /* OOM_DISABLE == -17 */
ae446765eb0605d2451bb4dd7c336672bcc7ab0cKay Sievers /* set signal handlers */
8c4a3079a7f358c179430d1aec59de8b670b5f6eLennart Poettering memset(&act, 0x00, sizeof(struct sigaction));
a45a909fbbe11ad8c75cda5639d875476ac65453Christian Ruppert /* watch rules directory */
2c696a96a2bd63d2ff0d5595622124ef9270b172Lennart Poettering inotify_add_watch(inotify_fd, udev_get_rules_path(udev),
07459bb6b92268beb2599f65cf195708d88c51ccFabiano Fidêncio IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering inotify_add_watch(inotify_fd, UDEV_PREFIX "/lib/udev/rules.d",
5b6319dceedd81f3f1ce7eb70ea5defaef43bcecLennart Poettering IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
1271623839b5bb4f0f383a8ad5500462dda0a94aLennart Poettering inotify_add_watch(inotify_fd, SYSCONFDIR "/udev/rules.d",
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
807e17f05e217b474af39503efb9503d81b12596Lennart Poettering /* watch dynamic rules directory */
5eda94dda25bccda928c4b33c790dbe748573a22Lennart Poettering util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/rules.d", NULL);
f6a971bc0bf1252e9614919ccca0d53db5fc53d9Lennart Poettering IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
2a018e83ded29c9719b2478a65ee6245c829c0f5Kay Sievers /* in trace mode run one event after the other */
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers /* possibly overwrite maximum limit of executed events */
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers info(udev, "initialize max_childs to %u\n", max_childs);
ae446765eb0605d2451bb4dd7c336672bcc7ab0cKay Sievers struct pollfd *ctrl_poll, *monitor_poll, *inotify_poll = NULL;
2c6db6fb9b1a10184b086df0d23228c4c0205a49Lennart Poettering sigprocmask(SIG_SETMASK, &blocked_mask, &orig_mask);
5ee9f21e86bb6a06d3eb956546f85338e81395e6Lennart Poettering sigprocmask(SIG_SETMASK, &orig_mask, NULL);
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering ctrl_poll->fd = udev_ctrl_get_fd(udev_ctrl);
if (inotify_fd >= 0) {
if (fdcount < 0) {
goto handle_signals;
signal_received = 0;
if (reload_config) {
reload_config = 0;
if (sigchilds_waiting) {
sigchilds_waiting = 0;
if (run_exec_q) {
run_exec_q = 0;
if (!stop_exec_q)
if (settle_pid > 0) {
settle_pid = 0;
rc = 0;
exit:
if (inotify_fd >= 0)
return rc;