summaryrefslogtreecommitdiff
path: root/src/udev/udevd.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2018-11-06 17:35:33 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2018-11-17 21:45:03 +0900
commit7443654e5f0ee918438d7159304ad25672b2c327 (patch)
tree2d77f061bbbca704b75eb434721f96cf73b927c7 /src/udev/udevd.c
parentabde5ea854d9ac0b4962af1e5671ecb2a3d9f3e6 (diff)
downloadsystemd-7443654e5f0ee918438d7159304ad25672b2c327.tar.gz
systemd-7443654e5f0ee918438d7159304ad25672b2c327.tar.bz2
systemd-7443654e5f0ee918438d7159304ad25672b2c327.zip
udevd: use safe_fork() to spawn worker process
Diffstat (limited to 'src/udev/udevd.c')
-rw-r--r--src/udev/udevd.c47
1 files changed, 20 insertions, 27 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 16b1846415..0878ccae7b 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -474,10 +474,6 @@ static int worker_main(Manager *_manager, struct udev_monitor *monitor, struct u
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_monitor, &ep_monitor) < 0)
return log_error_errno(errno, "fail to add fds to epoll: %m");
- /* Request TERM signal if parent exits.
- * Ignore error, not much we can do in that case. */
- (void) prctl(PR_SET_PDEATHSIG, SIGTERM);
-
/* Reset OOM score, we only protect the main daemon. */
r = set_oom_score_adjust(0);
if (r < 0)
@@ -535,46 +531,43 @@ static int worker_main(Manager *_manager, struct udev_monitor *monitor, struct u
}
}
-static void worker_spawn(Manager *manager, struct event *event) {
+static int worker_spawn(Manager *manager, struct event *event) {
_cleanup_(udev_monitor_unrefp) struct udev_monitor *worker_monitor = NULL;
+ struct worker *worker;
pid_t pid;
- int r = 0;
+ int r;
/* listen for new events */
worker_monitor = udev_monitor_new_from_netlink(NULL, NULL);
- if (worker_monitor == NULL)
- return;
+ if (!worker_monitor)
+ return -errno;
+
/* allow the main daemon netlink address to send devices to the worker */
udev_monitor_allow_unicast_sender(worker_monitor, manager->monitor);
r = udev_monitor_enable_receiving(worker_monitor);
if (r < 0)
- log_error_errno(r, "worker: could not enable receiving of device: %m");
+ return log_error_errno(r, "Worker: could not enable receiving of device: %m");
- pid = fork();
- switch (pid) {
- case 0: {
+ r = safe_fork(NULL, FORK_DEATHSIG, &pid);
+ if (r < 0) {
+ event->state = EVENT_QUEUED;
+ return log_error_errno(r, "Failed to fork() worker: %m");
+ }
+ if (r == 0) {
+ /* Worker process */
r = worker_main(manager, worker_monitor, TAKE_PTR(event->dev));
log_close();
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
- case -1:
- event->state = EVENT_QUEUED;
- log_error_errno(errno, "fork of child failed: %m");
- break;
- default:
- {
- struct worker *worker;
- r = worker_new(&worker, manager, worker_monitor, pid);
- if (r < 0)
- return;
+ r = worker_new(&worker, manager, worker_monitor, pid);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create worker object: %m");
- worker_attach_event(worker, event);
+ worker_attach_event(worker, event);
- log_debug("seq %llu forked new worker ["PID_FMT"]", udev_device_get_seqnum(event->dev), pid);
- break;
- }
- }
+ log_device_debug(event->dev->device, "seq %llu forked new worker ["PID_FMT"]", event->seqnum, pid);
+ return 0;
}
static void event_run(Manager *manager, struct event *event) {