]> git.ipfire.org Git - thirdparty/systemd.git/blame - udev/udevd.c
move udev_ctrl to libudev-private
[thirdparty/systemd.git] / udev / udevd.c
CommitLineData
7fafc032 1/*
b3518c16 2 * Copyright (C) 2004-2006 Kay Sievers <kay.sievers@vrfy.org>
2f6cbd19 3 * Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
7fafc032 4 *
7fafc032
KS
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
27b77df4 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
7fafc032
KS
17 *
18 */
19
01618658
KS
20#include "config.h"
21
a695feae 22#include <stddef.h>
7fafc032
KS
23#include <signal.h>
24#include <unistd.h>
25#include <errno.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
085cce37
KS
29#include <ctype.h>
30#include <dirent.h>
31#include <fcntl.h>
40caaeec 32#include <syslog.h>
0b3dfb3d 33#include <time.h>
b52a01ee 34#include <getopt.h>
138068d6
KS
35#include <sys/select.h>
36#include <sys/wait.h>
53921bfa
KS
37#include <sys/types.h>
38#include <sys/socket.h>
39#include <sys/un.h>
dc117daa 40#include <sys/stat.h>
c895fd00 41#include <sys/ioctl.h>
62821d0d 42#include <linux/types.h>
88f4b648 43#include <linux/netlink.h>
01618658
KS
44#ifdef HAVE_INOTIFY
45#include <sys/inotify.h>
46#endif
7fafc032
KS
47
48#include "udev.h"
c895fd00 49#include "udev_rules.h"
eef7c9a3 50#include "udev_selinux.h"
7fafc032 51
d59f11e1
KS
52#define UDEVD_PRIORITY -4
53#define UDEV_PRIORITY -2
54
55/* maximum limit of forked childs */
56#define UDEVD_MAX_CHILDS 256
57/* start to throttle forking if maximum number of running childs in our session is reached */
58#define UDEVD_MAX_CHILDS_RUNNING 16
59
c70560fe 60static int debug;
9e8fe79b 61
7d563a17
KS
62static void log_fn(struct udev *udev, int priority,
63 const char *file, int line, const char *fn,
64 const char *format, va_list args)
65{
66 if (debug) {
67 fprintf(stderr, "[%d] %s: ", (int) getpid(), fn);
68 vfprintf(stderr, format, args);
69 } else {
70 vsyslog(priority, format, args);
71 }
72}
73
74struct udevd_uevent_msg {
75 struct udev *udev;
76 struct list_head node;
77 pid_t pid;
78 int exitstatus;
79 time_t queue_time;
80 char *action;
81 char *devpath;
82 char *subsystem;
83 char *driver;
84 dev_t devt;
85 unsigned long long seqnum;
86 char *devpath_old;
87 char *physdevpath;
88 unsigned int timeout;
89 char *envp[UEVENT_NUM_ENVP+1];
90 char envbuf[];
91};
92
93static int debug_trace;
1aa1e248 94static struct udev_rules rules;
d59f11e1 95static struct udev_ctrl *udev_ctrl;
239cc98b
KS
96static int uevent_netlink_sock = -1;
97static int inotify_fd = -1;
085cce37 98static pid_t sid;
13f24d59 99
f1ff8d7b 100static int signal_pipe[2] = {-1, -1};
5cab7caa 101static volatile int sigchilds_waiting;
63cc8f04 102static volatile int udev_exit;
c895fd00 103static volatile int reload_config;
f27125f9 104static int run_exec_q;
3b47c739 105static int stop_exec_q;
a15f42c4
KS
106static int max_childs;
107static int max_childs_running;
7d563a17 108static char udev_log_env[32];
40caaeec 109
40caaeec
KS
110static LIST_HEAD(exec_list);
111static LIST_HEAD(running_list);
a15f42c4 112
c895fd00
KS
113static void asmlinkage udev_event_sig_handler(int signum)
114{
115 if (signum == SIGALRM)
116 exit(1);
117}
118
b3518c16 119static int udev_event_process(struct udevd_uevent_msg *msg)
c895fd00
KS
120{
121 struct sigaction act;
7d563a17 122 struct udevice *udevice;
c895fd00
KS
123 int i;
124 int retval;
125
126 /* set signal handlers */
127 memset(&act, 0x00, sizeof(act));
128 act.sa_handler = (void (*)(int)) udev_event_sig_handler;
129 sigemptyset (&act.sa_mask);
130 act.sa_flags = 0;
131 sigaction(SIGALRM, &act, NULL);
132
3e5e8332
KS
133 /* reset to default */
134 act.sa_handler = SIG_DFL;
135 sigaction(SIGINT, &act, NULL);
136 sigaction(SIGTERM, &act, NULL);
137 sigaction(SIGCHLD, &act, NULL);
138 sigaction(SIGHUP, &act, NULL);
139
c895fd00 140 /* trigger timeout to prevent hanging processes */
bf50425b 141 alarm(UDEV_EVENT_TIMEOUT);
c895fd00 142
1aa1e248 143 /* reconstruct event environment from message */
c895fd00
KS
144 for (i = 0; msg->envp[i]; i++)
145 putenv(msg->envp[i]);
146
7d563a17
KS
147 udevice = udev_device_init(msg->udev);
148 if (udevice == NULL)
1aa1e248 149 return -1;
7d563a17
KS
150 strlcpy(udevice->action, msg->action, sizeof(udevice->action));
151 sysfs_device_set_values(udevice->udev, udevice->dev, msg->devpath, msg->subsystem, msg->driver);
152 udevice->devpath_old = msg->devpath_old;
153 udevice->devt = msg->devt;
1aa1e248 154
7d563a17 155 retval = udev_device_event(&rules, udevice);
c895fd00 156
bf50425b 157 /* rules may change/disable the timeout */
7d563a17
KS
158 if (udevice->event_timeout >= 0)
159 alarm(udevice->event_timeout);
bf50425b 160
c895fd00 161 /* run programs collected by RUN-key*/
7d563a17
KS
162 if (retval == 0 && !udevice->ignore_device && udev_get_run(msg->udev))
163 retval = udev_rules_run(udevice);
c895fd00 164
7d563a17 165 udev_device_cleanup(udevice);
f4fc0136 166 return retval;
c895fd00
KS
167}
168
7a770250
KS
169enum event_state {
170 EVENT_QUEUED,
171 EVENT_FINISHED,
172 EVENT_FAILED,
173};
174
b3518c16 175static void export_event_state(struct udevd_uevent_msg *msg, enum event_state state)
7a770250
KS
176{
177 char filename[PATH_SIZE];
178 char filename_failed[PATH_SIZE];
9c6ad9fb 179 size_t start;
7a770250 180
a2f2270e 181 /* location of queue file */
7d563a17 182 snprintf(filename, sizeof(filename), "%s/.udev/queue/%llu", udev_get_dev_path(msg->udev), msg->seqnum);
7a770250 183
a2f2270e 184 /* location of failed file */
7d563a17 185 strlcpy(filename_failed, udev_get_dev_path(msg->udev), sizeof(filename_failed));
7a770250 186 strlcat(filename_failed, "/", sizeof(filename_failed));
01618658 187 start = strlcat(filename_failed, ".udev/failed/", sizeof(filename_failed));
9c6ad9fb 188 strlcat(filename_failed, msg->devpath, sizeof(filename_failed));
ce398745 189 path_encode(&filename_failed[start], sizeof(filename_failed) - start);
7a770250
KS
190
191 switch (state) {
192 case EVENT_QUEUED:
193 unlink(filename_failed);
7d563a17
KS
194 delete_path(msg->udev, filename_failed);
195 create_path(msg->udev, filename);
196 selinux_setfscreatecon(msg->udev, filename, NULL, S_IFLNK);
ce398745 197 symlink(msg->devpath, filename);
7d563a17 198 selinux_resetfscreatecon(msg->udev);
ce398745 199 break;
7a770250 200 case EVENT_FINISHED:
a2f2270e
KS
201 if (msg->devpath_old != NULL) {
202 /* "move" event - rename failed file to current name, do not delete failed */
203 char filename_failed_old[PATH_SIZE];
204
7d563a17 205 strlcpy(filename_failed_old, udev_get_dev_path(msg->udev), sizeof(filename_failed_old));
a2f2270e 206 strlcat(filename_failed_old, "/", sizeof(filename_failed_old));
01618658 207 start = strlcat(filename_failed_old, ".udev/failed/", sizeof(filename_failed_old));
a2f2270e
KS
208 strlcat(filename_failed_old, msg->devpath_old, sizeof(filename_failed_old));
209 path_encode(&filename_failed_old[start], sizeof(filename) - start);
210
211 if (rename(filename_failed_old, filename_failed) == 0)
7d563a17 212 info(msg->udev, "renamed devpath, moved failed state of '%s' to %s'\n",
a2f2270e
KS
213 msg->devpath_old, msg->devpath);
214 } else {
215 unlink(filename_failed);
7d563a17 216 delete_path(msg->udev, filename_failed);
a2f2270e 217 }
7a770250 218
ce398745 219 unlink(filename);
7d563a17 220 delete_path(msg->udev, filename);
ce398745
KS
221 break;
222 case EVENT_FAILED:
a2f2270e 223 /* move failed event to the failed directory */
7d563a17 224 create_path(msg->udev, filename_failed);
ce398745 225 rename(filename, filename_failed);
1b75f109 226
a2f2270e 227 /* clean up possibly empty queue directory */
7d563a17 228 delete_path(msg->udev, filename);
ce398745 229 break;
7a770250 230 }
ce398745
KS
231
232 return;
7a770250
KS
233}
234
b3518c16 235static void msg_queue_delete(struct udevd_uevent_msg *msg)
fc465079
KS
236{
237 list_del(&msg->node);
7a770250 238
a2f2270e 239 /* mark as failed, if "add" event returns non-zero */
7a770250
KS
240 if (msg->exitstatus && strcmp(msg->action, "add") == 0)
241 export_event_state(msg, EVENT_FAILED);
242 else
243 export_event_state(msg, EVENT_FINISHED);
244
fc465079
KS
245 free(msg);
246}
247
b3518c16 248static void udev_event_run(struct udevd_uevent_msg *msg)
7fafc032 249{
90c210eb 250 pid_t pid;
f4fc0136 251 int retval;
90c210eb
KS
252
253 pid = fork();
254 switch (pid) {
255 case 0:
33db4b8d 256 /* child */
833b3c68 257 close(uevent_netlink_sock);
d59f11e1 258 udev_ctrl_unref(udev_ctrl);
90cd961e 259 if (inotify_fd >= 0)
c895fd00 260 close(inotify_fd);
c895fd00
KS
261 close(signal_pipe[READ_END]);
262 close(signal_pipe[WRITE_END]);
f602ccf0 263 logging_close();
c895fd00 264 logging_init("udevd-event");
085cce37 265 setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY);
b437ec95 266
f4fc0136 267 retval = udev_event_process(msg);
7d563a17 268 info(msg->udev, "seq %llu finished with %i\n", msg->seqnum, retval);
c895fd00
KS
269
270 logging_close();
f4fc0136
KS
271 if (retval)
272 exit(1);
c895fd00 273 exit(0);
90c210eb 274 case -1:
7d563a17 275 err(msg->udev, "fork of child failed: %s\n", strerror(errno));
ebfc1acd 276 msg_queue_delete(msg);
2f6cbd19 277 break;
90c210eb 278 default:
2f6cbd19 279 /* get SIGCHLD in main loop */
7d563a17 280 info(msg->udev, "seq %llu forked, pid [%d], '%s' '%s', %ld seconds old\n",
0b3dfb3d 281 msg->seqnum, pid, msg->action, msg->subsystem, time(NULL) - msg->queue_time);
2f6cbd19 282 msg->pid = pid;
90c210eb 283 }
7fafc032
KS
284}
285
b3518c16 286static void msg_queue_insert(struct udevd_uevent_msg *msg)
fc465079 287{
7baada47
KS
288 char filename[PATH_SIZE];
289 int fd;
290
fc465079 291 msg->queue_time = time(NULL);
7baada47 292
0f624f16 293 export_event_state(msg, EVENT_QUEUED);
7d563a17 294 info(msg->udev, "seq %llu queued, '%s' '%s'\n", msg->seqnum, msg->action, msg->subsystem);
0f624f16 295
7d563a17 296 strlcpy(filename, udev_get_dev_path(msg->udev), sizeof(filename));
01618658 297 strlcat(filename, "/.udev/uevent_seqnum", sizeof(filename));
7baada47 298 fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644);
90cd961e 299 if (fd >= 0) {
7baada47
KS
300 char str[32];
301 int len;
302
303 len = sprintf(str, "%llu\n", msg->seqnum);
304 write(fd, str, len);
305 close(fd);
306 }
fc465079 307
c7c00276
KS
308 /* run one event after the other in debug mode */
309 if (debug_trace) {
310 list_add_tail(&msg->node, &running_list);
311 udev_event_run(msg);
312 waitpid(msg->pid, NULL, 0);
313 msg_queue_delete(msg);
314 return;
315 }
316
fc465079
KS
317 /* run all events with a timeout set immediately */
318 if (msg->timeout != 0) {
319 list_add_tail(&msg->node, &running_list);
320 udev_event_run(msg);
321 return;
322 }
323
324 list_add_tail(&msg->node, &exec_list);
325 run_exec_q = 1;
326}
327
f051e340
KS
328static int mem_size_mb(void)
329{
9f1f67b1
KS
330 FILE* f;
331 char buf[4096];
332 long int memsize = -1;
f051e340 333
9f1f67b1
KS
334 f = fopen("/proc/meminfo", "r");
335 if (f == NULL)
f051e340 336 return -1;
f051e340 337
9f1f67b1
KS
338 while (fgets(buf, sizeof(buf), f) != NULL) {
339 long int value;
f051e340 340
9f1f67b1
KS
341 if (sscanf(buf, "MemTotal: %ld kB", &value) == 1) {
342 memsize = value / 1024;
343 break;
344 }
345 }
f051e340 346
fdc9a0b5 347 fclose(f);
9f1f67b1 348 return memsize;
f051e340
KS
349}
350
351static int cpu_count(void)
352{
9f1f67b1
KS
353 FILE* f;
354 char buf[4096];
f051e340
KS
355 int count = 0;
356
9f1f67b1
KS
357 f = fopen("/proc/stat", "r");
358 if (f == NULL)
f051e340 359 return -1;
f051e340 360
9f1f67b1
KS
361 while (fgets(buf, sizeof(buf), f) != NULL) {
362 if (strncmp(buf, "cpu", 3) == 0 && isdigit(buf[3]))
f051e340 363 count++;
f051e340
KS
364 }
365
9f1f67b1 366 fclose(f);
f051e340
KS
367 if (count == 0)
368 return -1;
369 return count;
370}
371
085cce37
KS
372static int running_processes(void)
373{
9f1f67b1
KS
374 FILE* f;
375 char buf[4096];
376 int running = -1;
085cce37 377
9f1f67b1
KS
378 f = fopen("/proc/stat", "r");
379 if (f == NULL)
085cce37 380 return -1;
085cce37 381
9f1f67b1
KS
382 while (fgets(buf, sizeof(buf), f) != NULL) {
383 int value;
085cce37 384
9f1f67b1
KS
385 if (sscanf(buf, "procs_running %u", &value) == 1) {
386 running = value;
387 break;
388 }
389 }
085cce37 390
9f1f67b1 391 fclose(f);
085cce37
KS
392 return running;
393}
394
395/* return the number of process es in our session, count only until limit */
396static int running_processes_in_session(pid_t session, int limit)
397{
398 DIR *dir;
399 struct dirent *dent;
400 int running = 0;
401
402 dir = opendir("/proc");
403 if (!dir)
404 return -1;
405
406 /* read process info from /proc */
407 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
408 int f;
409 char procdir[64];
410 char line[256];
411 const char *pos;
412 char state;
413 pid_t ppid, pgrp, sess;
414 int len;
415
416 if (!isdigit(dent->d_name[0]))
417 continue;
418
419 snprintf(procdir, sizeof(procdir), "/proc/%s/stat", dent->d_name);
420 procdir[sizeof(procdir)-1] = '\0';
421
422 f = open(procdir, O_RDONLY);
423 if (f == -1)
424 continue;
425
b4f192f0 426 len = read(f, line, sizeof(line)-1);
085cce37
KS
427 close(f);
428
429 if (len <= 0)
430 continue;
431 else
432 line[len] = '\0';
433
434 /* skip ugly program name */
435 pos = strrchr(line, ')') + 2;
436 if (pos == NULL)
437 continue;
438
439 if (sscanf(pos, "%c %d %d %d ", &state, &ppid, &pgrp, &sess) != 4)
440 continue;
441
442 /* count only processes in our session */
443 if (sess != session)
444 continue;
445
446 /* count only running, no sleeping processes */
447 if (state != 'R')
448 continue;
449
450 running++;
451 if (limit > 0 && running >= limit)
452 break;
453 }
454 closedir(dir);
455
456 return running;
457}
458
7b6571a9
KS
459static int compare_devpath(const char *running, const char *waiting)
460{
461 int i;
462
63f61c5c 463 for (i = 0; i < PATH_SIZE; i++) {
7b6571a9
KS
464 /* identical device event found */
465 if (running[i] == '\0' && waiting[i] == '\0')
466 return 1;
467
468 /* parent device event found */
469 if (running[i] == '\0' && waiting[i] == '/')
470 return 2;
471
472 /* child device event found */
473 if (running[i] == '/' && waiting[i] == '\0')
474 return 3;
475
476 /* no matching event */
477 if (running[i] != waiting[i])
478 break;
479 }
480
481 return 0;
482}
483
fc630eda
KS
484/* lookup event for identical, parent, child, or physical device */
485static int devpath_busy(struct udevd_uevent_msg *msg, int limit)
7fafc032 486{
b3518c16 487 struct udevd_uevent_msg *loop_msg;
a15f42c4 488 int childs_count = 0;
7b6571a9 489
fc630eda
KS
490 /* check exec-queue which may still contain delayed events we depend on */
491 list_for_each_entry(loop_msg, &exec_list, node) {
492 /* skip ourself and all later events */
493 if (loop_msg->seqnum >= msg->seqnum)
494 break;
495
a2f2270e
KS
496 /* check our old name */
497 if (msg->devpath_old != NULL)
498 if (strcmp(loop_msg->devpath , msg->devpath_old) == 0)
499 return 2;
500
fc630eda
KS
501 /* check identical, parent, or child device event */
502 if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) {
7d563a17 503 dbg(msg->udev, "%llu, device event still pending %llu (%s)\n",
fc630eda 504 msg->seqnum, loop_msg->seqnum, loop_msg->devpath);
a2f2270e 505 return 3;
fc630eda
KS
506 }
507
c3b145a3
MK
508 /* check for our major:minor number */
509 if (msg->devt && loop_msg->devt == msg->devt &&
510 strcmp(msg->subsystem, loop_msg->subsystem) == 0) {
7d563a17 511 dbg(msg->udev, "%llu, device event still pending %llu (%d:%d)\n", msg->seqnum,
c3b145a3
MK
512 loop_msg->seqnum, major(loop_msg->devt), minor(loop_msg->devt));
513 return 4;
514 }
515
fc630eda
KS
516 /* check physical device event (special case of parent) */
517 if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0)
518 if (compare_devpath(loop_msg->devpath, msg->physdevpath) != 0) {
7d563a17 519 dbg(msg->udev, "%llu, physical device event still pending %llu (%s)\n",
fc630eda 520 msg->seqnum, loop_msg->seqnum, loop_msg->devpath);
c3b145a3 521 return 5;
fc630eda
KS
522 }
523 }
524
1113044b 525 /* check run queue for still running events */
f8a178a3 526 list_for_each_entry(loop_msg, &running_list, node) {
a15f42c4 527 if (limit && childs_count++ > limit) {
7d563a17 528 dbg(msg->udev, "%llu, maximum number (%i) of childs reached\n", msg->seqnum, childs_count);
a15f42c4
KS
529 return 1;
530 }
80513ea3 531
a2f2270e
KS
532 /* check our old name */
533 if (msg->devpath_old != NULL)
534 if (strcmp(loop_msg->devpath , msg->devpath_old) == 0)
535 return 2;
536
fc630eda 537 /* check identical, parent, or child device event */
a15f42c4 538 if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) {
7d563a17 539 dbg(msg->udev, "%llu, device event still running %llu (%s)\n",
a15f42c4 540 msg->seqnum, loop_msg->seqnum, loop_msg->devpath);
a2f2270e 541 return 3;
a15f42c4 542 }
79721e0a 543
c3b145a3
MK
544 /* check for our major:minor number */
545 if (msg->devt && loop_msg->devt == msg->devt &&
546 strcmp(msg->subsystem, loop_msg->subsystem) == 0) {
7d563a17 547 dbg(msg->udev, "%llu, device event still running %llu (%d:%d)\n", msg->seqnum,
c3b145a3
MK
548 loop_msg->seqnum, major(loop_msg->devt), minor(loop_msg->devt));
549 return 4;
550 }
551
fc630eda 552 /* check physical device event (special case of parent) */
79721e0a 553 if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0)
a15f42c4 554 if (compare_devpath(loop_msg->devpath, msg->physdevpath) != 0) {
7d563a17 555 dbg(msg->udev, "%llu, physical device event still running %llu (%s)\n",
a15f42c4 556 msg->seqnum, loop_msg->seqnum, loop_msg->devpath);
c3b145a3 557 return 5;
a15f42c4 558 }
80513ea3 559 }
a15f42c4 560 return 0;
7fafc032
KS
561}
562
fc630eda 563/* serializes events for the identical and parent and child devices */
7d563a17 564static void msg_queue_manager(struct udev *udev)
7fafc032 565{
b3518c16
KS
566 struct udevd_uevent_msg *loop_msg;
567 struct udevd_uevent_msg *tmp_msg;
085cce37
KS
568 int running;
569
8ab44e3f
KS
570 if (list_empty(&exec_list))
571 return;
572
085cce37 573 running = running_processes();
7d563a17 574 dbg(udev, "%d processes runnning on system\n", running);
085cce37 575 if (running < 0)
a15f42c4 576 running = max_childs_running;
53921bfa 577
f8a178a3 578 list_for_each_entry_safe(loop_msg, tmp_msg, &exec_list, node) {
085cce37 579 /* check running processes in our session and possibly throttle */
a15f42c4
KS
580 if (running >= max_childs_running) {
581 running = running_processes_in_session(sid, max_childs_running+10);
7d563a17 582 dbg(udev, "at least %d processes running in session\n", running);
a15f42c4 583 if (running >= max_childs_running) {
7d563a17 584 dbg(udev, "delay seq %llu, too many processes already running\n", loop_msg->seqnum);
085cce37
KS
585 return;
586 }
587 }
588
fc630eda
KS
589 /* serialize and wait for parent or child events */
590 if (devpath_busy(loop_msg, max_childs) != 0) {
7d563a17 591 dbg(udev, "delay seq %llu (%s)\n", loop_msg->seqnum, loop_msg->devpath);
fc465079
KS
592 continue;
593 }
594
595 /* move event to run list */
596 list_move_tail(&loop_msg->node, &running_list);
597 udev_event_run(loop_msg);
598 running++;
7d563a17 599 dbg(udev, "moved seq %llu to running list\n", loop_msg->seqnum);
53921bfa
KS
600 }
601}
602
7d563a17 603static struct udevd_uevent_msg *get_msg_from_envbuf(struct udev *udev, const char *buf, int buf_size)
88f4b648
KS
604{
605 int bufpos;
606 int i;
b3518c16 607 struct udevd_uevent_msg *msg;
220dac4c 608 char *physdevdriver_key = NULL;
5780be9e
KS
609 int maj = 0;
610 int min = 0;
88f4b648 611
b3518c16 612 msg = malloc(sizeof(struct udevd_uevent_msg) + buf_size);
88f4b648
KS
613 if (msg == NULL)
614 return NULL;
b3518c16 615 memset(msg, 0x00, sizeof(struct udevd_uevent_msg) + buf_size);
7d563a17 616 msg->udev = udev;
88f4b648
KS
617
618 /* copy environment buffer and reconstruct envp */
619 memcpy(msg->envbuf, buf, buf_size);
620 bufpos = 0;
3b47c739 621 for (i = 0; (bufpos < buf_size) && (i < UEVENT_NUM_ENVP-2); i++) {
88f4b648
KS
622 int keylen;
623 char *key;
624
625 key = &msg->envbuf[bufpos];
626 keylen = strlen(key);
627 msg->envp[i] = key;
628 bufpos += keylen + 1;
7d563a17 629 dbg(udev, "add '%s' to msg.envp[%i]\n", msg->envp[i], i);
88f4b648
KS
630
631 /* remember some keys for further processing */
632 if (strncmp(key, "ACTION=", 7) == 0)
633 msg->action = &key[7];
ebfc1acd 634 else if (strncmp(key, "DEVPATH=", 8) == 0)
88f4b648 635 msg->devpath = &key[8];
ebfc1acd 636 else if (strncmp(key, "SUBSYSTEM=", 10) == 0)
88f4b648 637 msg->subsystem = &key[10];
254efc14
KS
638 else if (strncmp(key, "DRIVER=", 7) == 0)
639 msg->driver = &key[7];
ebfc1acd 640 else if (strncmp(key, "SEQNUM=", 7) == 0)
88f4b648 641 msg->seqnum = strtoull(&key[7], NULL, 10);
a2f2270e
KS
642 else if (strncmp(key, "DEVPATH_OLD=", 12) == 0)
643 msg->devpath_old = &key[12];
ebfc1acd 644 else if (strncmp(key, "PHYSDEVPATH=", 12) == 0)
88f4b648 645 msg->physdevpath = &key[12];
220dac4c
KS
646 else if (strncmp(key, "PHYSDEVDRIVER=", 14) == 0)
647 physdevdriver_key = key;
ebfc1acd 648 else if (strncmp(key, "MAJOR=", 6) == 0)
5780be9e 649 maj = strtoull(&key[6], NULL, 10);
ebfc1acd 650 else if (strncmp(key, "MINOR=", 6) == 0)
5780be9e 651 min = strtoull(&key[6], NULL, 10);
ebfc1acd 652 else if (strncmp(key, "TIMEOUT=", 8) == 0)
88f4b648
KS
653 msg->timeout = strtoull(&key[8], NULL, 10);
654 }
5780be9e 655 msg->devt = makedev(maj, min);
88f4b648 656 msg->envp[i++] = "UDEVD_EVENT=1";
220dac4c
KS
657
658 if (msg->driver == NULL && msg->physdevpath == NULL && physdevdriver_key != NULL) {
659 /* for older kernels DRIVER is empty for a bus device, export PHYSDEVDRIVER as DRIVER */
660 msg->envp[i++] = &physdevdriver_key[7];
661 msg->driver = &physdevdriver_key[14];
662 }
663
88f4b648
KS
664 msg->envp[i] = NULL;
665
0ec819d9 666 if (msg->devpath == NULL || msg->action == NULL) {
7d563a17 667 info(udev, "DEVPATH or ACTION missing, ignore message\n");
e825b59b
KS
668 free(msg);
669 return NULL;
670 }
88f4b648
KS
671 return msg;
672}
673
3b47c739 674/* receive the udevd message from userspace */
d59f11e1 675static void handle_ctrl_msg(struct udev_ctrl *uctrl)
7fafc032 676{
d59f11e1
KS
677 struct udev *udev = udev_ctrl_get_udev(uctrl);
678 struct udev_ctrl_msg *ctrl_msg;
679 const char *str;
680 int i;
7b1cbec9 681
d59f11e1
KS
682 ctrl_msg = udev_ctrl_receive_msg(uctrl);
683 if (ctrl_msg == NULL)
b437ec95 684 return;
4a231017 685
d59f11e1
KS
686 i = udev_ctrl_get_set_log_level(ctrl_msg);
687 if (i >= 0) {
688 info(udev, "udevd message (SET_LOG_PRIORITY) received, log_priority=%i\n", i);
689 udev_set_log_priority(udev, i);
690 sprintf(udev_log_env, "UDEV_LOG=%i", i);
691 putenv(udev_log_env);
0028653c
KS
692 }
693
d59f11e1 694 if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) {
7d563a17 695 info(udev, "udevd message (STOP_EXEC_QUEUE) received\n");
3b47c739 696 stop_exec_q = 1;
d59f11e1
KS
697 }
698
699 if (udev_ctrl_get_start_exec_queue(ctrl_msg) > 0) {
7d563a17 700 info(udev, "udevd message (START_EXEC_QUEUE) received\n");
3b47c739 701 stop_exec_q = 0;
7d563a17 702 msg_queue_manager(udev);
d59f11e1
KS
703 }
704
705 if (udev_ctrl_get_reload_rules(ctrl_msg) > 0) {
7d563a17 706 info(udev, "udevd message (RELOAD_RULES) received\n");
c895fd00 707 reload_config = 1;
3b47c739 708 }
d59f11e1
KS
709
710 str = udev_ctrl_get_set_env(ctrl_msg);
711 if (str != NULL) {
712 char *key = strdup(str);
713 char *val;
714
715 val = strchr(str, '=');
716 if (val != NULL) {
717 val[0] = '\0';
718 val = &val[1];
719 if (val[0] == '\0') {
720 info(udev, "udevd message (ENV) received, unset '%s'\n", key);
721 unsetenv(str);
722 } else {
723 info(udev, "udevd message (ENV) received, set '%s=%s'\n", key, val);
724 setenv(key, val, 1);
725 }
726 } else {
727 err(udev, "wrong key format '%s'\n", key);
728 }
729 free(key);
730 }
731
732 i = udev_ctrl_get_set_max_childs(ctrl_msg);
733 if (i >= 0) {
734 info(udev, "udevd message (SET_MAX_CHILDS) received, max_childs=%i\n", i);
735 max_childs = i;
736 }
737
738 i = udev_ctrl_get_set_max_childs_running(ctrl_msg);
739 if (i > 0) {
740 info(udev, "udevd message (SET_MAX_CHILDS_RUNNING) received, max_childs_running=%i\n", i);
741 max_childs_running = i;
742 }
743
744 udev_ctrl_msg_unref(ctrl_msg);
88f4b648 745}
4a231017 746
88f4b648 747/* receive the kernel user event message and do some sanity checks */
7d563a17 748static struct udevd_uevent_msg *get_netlink_msg(struct udev *udev)
88f4b648 749{
b3518c16 750 struct udevd_uevent_msg *msg;
88f4b648
KS
751 int bufpos;
752 ssize_t size;
7d1e179f 753 static char buffer[UEVENT_BUFFER_SIZE+512];
88f4b648 754 char *pos;
4a231017 755
8ab44e3f 756 size = recv(uevent_netlink_sock, &buffer, sizeof(buffer), 0);
88f4b648
KS
757 if (size < 0) {
758 if (errno != EINTR)
7d563a17 759 err(udev, "unable to receive kernel netlink message: %s\n", strerror(errno));
88f4b648
KS
760 return NULL;
761 }
4a231017 762
88f4b648
KS
763 if ((size_t)size > sizeof(buffer)-1)
764 size = sizeof(buffer)-1;
765 buffer[size] = '\0';
7d563a17 766 dbg(udev, "uevent_size=%zi\n", size);
4a231017 767
88f4b648
KS
768 /* start of event payload */
769 bufpos = strlen(buffer)+1;
7d563a17 770 msg = get_msg_from_envbuf(udev, &buffer[bufpos], size-bufpos);
88f4b648
KS
771 if (msg == NULL)
772 return NULL;
4a231017 773
88f4b648
KS
774 /* validate message */
775 pos = strchr(buffer, '@');
776 if (pos == NULL) {
7d563a17 777 err(udev, "invalid uevent '%s'\n", buffer);
88f4b648
KS
778 free(msg);
779 return NULL;
780 }
781 pos[0] = '\0';
79721e0a 782
88f4b648 783 if (msg->action == NULL) {
7d563a17 784 info(udev, "no ACTION in payload found, skip event '%s'\n", buffer);
88f4b648
KS
785 free(msg);
786 return NULL;
787 }
7f7ae03a 788
88f4b648 789 if (strcmp(msg->action, buffer) != 0) {
7d563a17 790 err(udev, "ACTION in payload does not match uevent, skip event '%s'\n", buffer);
88f4b648
KS
791 free(msg);
792 return NULL;
53921bfa 793 }
a695feae 794
021a294c 795 return msg;
a695feae 796}
1c5c245e 797
e5a5b54a 798static void asmlinkage sig_handler(int signum)
7fafc032 799{
53921bfa
KS
800 switch (signum) {
801 case SIGINT:
802 case SIGTERM:
63cc8f04 803 udev_exit = 1;
53921bfa 804 break;
2f6cbd19 805 case SIGCHLD:
f27125f9 806 /* set flag, then write to pipe if needed */
5cab7caa 807 sigchilds_waiting = 1;
2f6cbd19 808 break;
c895fd00
KS
809 case SIGHUP:
810 reload_config = 1;
811 break;
f27125f9 812 }
5a73b25f 813
c6303c13
KS
814 /* write to pipe, which will wakeup select() in our mainloop */
815 write(signal_pipe[WRITE_END], "", 1);
33db4b8d 816}
7fafc032 817
f4fc0136 818static void udev_done(int pid, int exitstatus)
2f6cbd19
KS
819{
820 /* find msg associated with pid and delete it */
b3518c16 821 struct udevd_uevent_msg *msg;
2f6cbd19 822
f8a178a3 823 list_for_each_entry(msg, &running_list, node) {
2f6cbd19 824 if (msg->pid == pid) {
7d563a17 825 info(msg->udev, "seq %llu, pid [%d] exit with %i, %ld seconds old\n", msg->seqnum, msg->pid,
f4fc0136
KS
826 exitstatus, time(NULL) - msg->queue_time);
827 msg->exitstatus = exitstatus;
ebfc1acd 828 msg_queue_delete(msg);
3169e8d1 829
fc465079 830 /* there may be events waiting with the same devpath */
f27125f9 831 run_exec_q = 1;
2f6cbd19
KS
832 return;
833 }
834 }
835}
836
5cab7caa 837static void reap_sigchilds(void)
f27125f9 838{
40caaeec 839 pid_t pid;
f4fc0136 840 int status;
ce043f85 841
40caaeec 842 while (1) {
f4fc0136 843 pid = waitpid(-1, &status, WNOHANG);
40caaeec 844 if (pid <= 0)
f27125f9 845 break;
f4fc0136
KS
846 if (WIFEXITED(status))
847 status = WEXITSTATUS(status);
82de5983
KS
848 else if (WIFSIGNALED(status))
849 status = WTERMSIG(status) + 128;
f4fc0136
KS
850 else
851 status = 0;
852 udev_done(pid, status);
f27125f9 853 }
854}
855
7d563a17 856static int init_uevent_netlink_sock(struct udev *udev)
88f4b648
KS
857{
858 struct sockaddr_nl snl;
a5c606f6 859 const int buffersize = 16 * 1024 * 1024;
88f4b648
KS
860 int retval;
861
862 memset(&snl, 0x00, sizeof(struct sockaddr_nl));
863 snl.nl_family = AF_NETLINK;
864 snl.nl_pid = getpid();
733f070d 865 snl.nl_groups = 1;
88f4b648 866
8ab44e3f
KS
867 uevent_netlink_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
868 if (uevent_netlink_sock == -1) {
7d563a17 869 err(udev, "error getting socket: %s\n", strerror(errno));
88f4b648
KS
870 return -1;
871 }
872
cbbde2ba 873 /* set receive buffersize */
a5c606f6 874 setsockopt(uevent_netlink_sock, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize));
cbbde2ba 875
833b3c68 876 retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl));
88f4b648 877 if (retval < 0) {
7d563a17 878 err(udev, "bind failed: %s\n", strerror(errno));
8ab44e3f
KS
879 close(uevent_netlink_sock);
880 uevent_netlink_sock = -1;
88f4b648
KS
881 return -1;
882 }
88f4b648
KS
883 return 0;
884}
885
7d563a17 886static void export_initial_seqnum(struct udev *udev)
90cd961e
KS
887{
888 char filename[PATH_SIZE];
889 int fd;
890 char seqnum[32];
891 ssize_t len = 0;
892
7d563a17 893 strlcpy(filename, udev_get_sys_path(udev), sizeof(filename));
90cd961e
KS
894 strlcat(filename, "/kernel/uevent_seqnum", sizeof(filename));
895 fd = open(filename, O_RDONLY);
896 if (fd >= 0) {
897 len = read(fd, seqnum, sizeof(seqnum)-1);
898 close(fd);
899 }
900 if (len <= 0) {
901 strcpy(seqnum, "0\n");
902 len = 3;
903 }
7d563a17 904 strlcpy(filename, udev_get_dev_path(udev), sizeof(filename));
01618658 905 strlcat(filename, "/.udev/uevent_seqnum", sizeof(filename));
7d563a17 906 create_path(udev, filename);
90cd961e
KS
907 fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644);
908 if (fd >= 0) {
909 write(fd, seqnum, len);
910 close(fd);
911 }
912}
913
59345311 914int main(int argc, char *argv[])
c2cf4012 915{
7d563a17 916 struct udev *udev;
c2cf4012 917 int retval;
3904a758 918 int fd;
f8911dbb 919 struct sigaction act;
f27125f9 920 fd_set readfds;
a15f42c4 921 const char *value;
561d4c5a 922 int daemonize = 0;
b52a01ee
KS
923 static const struct option options[] = {
924 { "daemon", 0, NULL, 'd' },
c7c00276 925 { "debug-trace", 0, NULL, 't' },
c70560fe 926 { "debug", 0, NULL, 'D' },
b52a01ee 927 { "help", 0, NULL, 'h' },
841e168c 928 { "version", 0, NULL, 'V' },
b52a01ee
KS
929 {}
930 };
e3396a2d 931 int rc = 1;
0b3dfb3d 932 int maxfd;
53921bfa 933
7d563a17
KS
934 udev = udev_new();
935 if (udev == NULL)
936 goto exit;
937
7257cb18 938 logging_init("udevd");
7d563a17
KS
939 udev_set_log_fn(udev, log_fn);
940
941 selinux_init(udev);
942 dbg(udev, "version %s\n", VERSION);
95a6f4c8 943
b52a01ee 944 while (1) {
7d563a17
KS
945 int option;
946
c70560fe 947 option = getopt_long(argc, argv, "dDthV", options, NULL);
b52a01ee
KS
948 if (option == -1)
949 break;
950
951 switch (option) {
952 case 'd':
561d4c5a 953 daemonize = 1;
b52a01ee 954 break;
c7c00276
KS
955 case 't':
956 debug_trace = 1;
957 break;
c70560fe
KS
958 case 'D':
959 debug = 1;
7d563a17
KS
960 if (udev_get_log_priority(udev) < LOG_INFO)
961 udev_set_log_priority(udev, LOG_INFO);
9e8fe79b 962 break;
b52a01ee 963 case 'h':
c70560fe 964 printf("Usage: udevd [--help] [--daemon] [--debug-trace] [--debug] [--version]\n");
841e168c
MS
965 goto exit;
966 case 'V':
01618658 967 printf("%s\n", VERSION);
e3396a2d 968 goto exit;
b52a01ee
KS
969 default:
970 goto exit;
561d4c5a 971 }
561d4c5a 972 }
40caaeec 973
fc89fe7e
KS
974 if (getuid() != 0) {
975 fprintf(stderr, "root privileges required\n");
7d563a17 976 err(udev, "root privileges required\n");
fc89fe7e
KS
977 goto exit;
978 }
979
5edec024
MS
980 /* make sure std{in,out,err} fd's are in a sane state */
981 fd = open("/dev/null", O_RDWR);
982 if (fd < 0) {
983 fprintf(stderr, "cannot open /dev/null\n");
7d563a17 984 err(udev, "cannot open /dev/null\n");
5edec024
MS
985 }
986 if (fd > STDIN_FILENO)
987 dup2(fd, STDIN_FILENO);
988 if (write(STDOUT_FILENO, 0, 0) < 0)
989 dup2(fd, STDOUT_FILENO);
990 if (write(STDERR_FILENO, 0, 0) < 0)
991 dup2(fd, STDERR_FILENO);
992
d59f11e1
KS
993 /* init control socket, bind() ensures, that only one udevd instance is running */
994 udev_ctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
995 if (udev_ctrl == NULL) {
996 fprintf(stderr, "error initializing control socket");
997 err(udev, "error initializing udevd socket");
998 rc = 1;
999 goto exit;
1000 }
1001
1002 if (udev_ctrl_enable_receiving(udev_ctrl) < 0) {
1003 fprintf(stderr, "error binding control socket, seems udevd is already running\n");
1004 err(udev, "error binding control socket, seems udevd is already running\n");
1005 rc = 1;
833b3c68
KS
1006 goto exit;
1007 }
1008
7d563a17 1009 if (init_uevent_netlink_sock(udev) < 0) {
e3396a2d 1010 fprintf(stderr, "error initializing netlink socket\n");
7d563a17 1011 err(udev, "error initializing netlink socket\n");
833b3c68
KS
1012 rc = 3;
1013 goto exit;
1014 }
1015
ff2eecef
SV
1016 retval = pipe(signal_pipe);
1017 if (retval < 0) {
7d563a17 1018 err(udev, "error getting pipes: %s\n", strerror(errno));
ff2eecef
SV
1019 goto exit;
1020 }
1021
1022 retval = fcntl(signal_pipe[READ_END], F_GETFL, 0);
1023 if (retval < 0) {
7d563a17 1024 err(udev, "error fcntl on read pipe: %s\n", strerror(errno));
ff2eecef
SV
1025 goto exit;
1026 }
1027 retval = fcntl(signal_pipe[READ_END], F_SETFL, retval | O_NONBLOCK);
1028 if (retval < 0) {
7d563a17 1029 err(udev, "error fcntl on read pipe: %s\n", strerror(errno));
ff2eecef
SV
1030 goto exit;
1031 }
1032
1033 retval = fcntl(signal_pipe[WRITE_END], F_GETFL, 0);
1034 if (retval < 0) {
7d563a17 1035 err(udev, "error fcntl on write pipe: %s\n", strerror(errno));
ff2eecef
SV
1036 goto exit;
1037 }
1038 retval = fcntl(signal_pipe[WRITE_END], F_SETFL, retval | O_NONBLOCK);
1039 if (retval < 0) {
7d563a17 1040 err(udev, "error fcntl on write pipe: %s\n", strerror(errno));
ff2eecef
SV
1041 goto exit;
1042 }
1043
e3396a2d 1044 /* parse the rules and keep them in memory */
1aa1e248 1045 sysfs_init();
7d563a17 1046 udev_rules_init(udev, &rules, 1);
833b3c68 1047
7d563a17 1048 export_initial_seqnum(udev);
90cd961e 1049
561d4c5a 1050 if (daemonize) {
f15515b5
KS
1051 pid_t pid;
1052
1053 pid = fork();
1054 switch (pid) {
1055 case 0:
7d563a17 1056 dbg(udev, "daemonized fork running\n");
f15515b5
KS
1057 break;
1058 case -1:
7d563a17 1059 err(udev, "fork of daemon failed: %s\n", strerror(errno));
833b3c68 1060 rc = 4;
f15515b5
KS
1061 goto exit;
1062 default:
7d563a17 1063 dbg(udev, "child [%u] running, parent exits\n", pid);
2f64aa40 1064 rc = 0;
833b3c68 1065 goto exit;
f15515b5
KS
1066 }
1067 }
1068
d59f11e1
KS
1069 /* redirect std{out,err} */
1070 if (!debug) {
5edec024 1071 dup2(fd, STDOUT_FILENO);
d59f11e1
KS
1072 dup2(fd, STDERR_FILENO);
1073 }
5edec024
MS
1074 if (fd > STDERR_FILENO)
1075 close(fd);
e3396a2d 1076
3904a758 1077 /* set scheduling priority for the daemon */
085cce37
KS
1078 setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY);
1079
3904a758 1080 chdir("/");
74adec7d 1081 umask(022);
3904a758
KS
1082
1083 /* become session leader */
1084 sid = setsid();
7d563a17 1085 dbg(udev, "our session is %d\n", sid);
3904a758
KS
1086
1087 /* OOM_DISABLE == -17 */
1088 fd = open("/proc/self/oom_adj", O_RDWR);
1089 if (fd < 0)
7d563a17 1090 err(udev, "error disabling OOM: %s\n", strerror(errno));
3904a758
KS
1091 else {
1092 write(fd, "-17", 3);
1093 close(fd);
1094 }
1095
798d7ab6
KS
1096 fd = open("/dev/kmsg", O_WRONLY);
1097 if (fd > 0) {
01618658 1098 const char *str = "<6>udevd version " VERSION " started\n";
798d7ab6
KS
1099
1100 write(fd, str, strlen(str));
1101 close(fd);
1102 }
1103
f27125f9 1104 /* set signal handlers */
0786e8e5 1105 memset(&act, 0x00, sizeof(struct sigaction));
6b493a20 1106 act.sa_handler = (void (*)(int)) sig_handler;
f27125f9 1107 sigemptyset(&act.sa_mask);
f8911dbb
KS
1108 act.sa_flags = SA_RESTART;
1109 sigaction(SIGINT, &act, NULL);
1110 sigaction(SIGTERM, &act, NULL);
f8911dbb 1111 sigaction(SIGCHLD, &act, NULL);
63cc8f04 1112 sigaction(SIGHUP, &act, NULL);
7fafc032 1113
c895fd00
KS
1114 /* watch rules directory */
1115 inotify_fd = inotify_init();
254d6d3c 1116 if (inotify_fd >= 0) {
7d563a17
KS
1117 if (udev_get_rules_path(udev) != NULL) {
1118 inotify_add_watch(inotify_fd, udev_get_rules_path(udev),
282988c4
KS
1119 IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
1120 } else {
1121 char filename[PATH_MAX];
1122
01618658 1123 inotify_add_watch(inotify_fd, UDEV_PREFIX "/lib/udev/rules.d",
282988c4 1124 IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
01618658 1125 inotify_add_watch(inotify_fd, SYSCONFDIR "/udev/rules.d",
282988c4
KS
1126 IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
1127
1128 /* watch dynamic rules directory */
7d563a17 1129 strlcpy(filename, udev_get_dev_path(udev), sizeof(filename));
01618658 1130 strlcat(filename, "/.udev/rules.d", sizeof(filename));
282988c4
KS
1131 inotify_add_watch(inotify_fd, filename,
1132 IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
1133 }
254d6d3c 1134 } else if (errno == ENOSYS)
7d563a17 1135 err(udev, "the kernel does not support inotify, udevd can't monitor rules file changes\n");
750d10da 1136 else
7d563a17 1137 err(udev, "inotify_init failed: %s\n", strerror(errno));
0028653c 1138
a15f42c4
KS
1139 /* maximum limit of forked childs */
1140 value = getenv("UDEVD_MAX_CHILDS");
1141 if (value)
1142 max_childs = strtoul(value, NULL, 10);
f051e340
KS
1143 else {
1144 int memsize = mem_size_mb();
1145 if (memsize > 0)
1146 max_childs = 128 + (memsize / 4);
1147 else
1148 max_childs = UDEVD_MAX_CHILDS;
1149 }
7d563a17 1150 info(udev, "initialize max_childs to %u\n", max_childs);
a15f42c4
KS
1151
1152 /* start to throttle forking if maximum number of _running_ childs is reached */
1153 value = getenv("UDEVD_MAX_CHILDS_RUNNING");
1154 if (value)
1155 max_childs_running = strtoull(value, NULL, 10);
f051e340
KS
1156 else {
1157 int cpus = cpu_count();
1158 if (cpus > 0)
1159 max_childs_running = 8 + (8 * cpus);
1160 else
1161 max_childs_running = UDEVD_MAX_CHILDS_RUNNING;
1162 }
7d563a17 1163 info(udev, "initialize max_childs_running to %u\n", max_childs_running);
8b726878 1164
c895fd00
KS
1165 /* clear environment for forked event processes */
1166 clearenv();
1167
40caaeec 1168 /* export log_priority , as called programs may want to follow that setting */
7d563a17
KS
1169 sprintf(udev_log_env, "UDEV_LOG=%i", udev_get_log_priority(udev));
1170 putenv(udev_log_env);
c7c00276
KS
1171 if (debug_trace)
1172 putenv("DEBUG=1");
40caaeec 1173
d59f11e1 1174 maxfd = udev_ctrl_get_fd(udev_ctrl);
0b3dfb3d
KS
1175 maxfd = UDEV_MAX(maxfd, uevent_netlink_sock);
1176 maxfd = UDEV_MAX(maxfd, signal_pipe[READ_END]);
1177 maxfd = UDEV_MAX(maxfd, inotify_fd);
1178
63cc8f04 1179 while (!udev_exit) {
b3518c16 1180 struct udevd_uevent_msg *msg;
40caaeec 1181 int fdcount;
021a294c 1182
40caaeec 1183 FD_ZERO(&readfds);
f1ff8d7b 1184 FD_SET(signal_pipe[READ_END], &readfds);
d59f11e1 1185 FD_SET(udev_ctrl_get_fd(udev_ctrl), &readfds);
833b3c68 1186 FD_SET(uevent_netlink_sock, &readfds);
90cd961e 1187 if (inotify_fd >= 0)
c895fd00 1188 FD_SET(inotify_fd, &readfds);
e5a2989e 1189
0b3dfb3d 1190 fdcount = select(maxfd+1, &readfds, NULL, NULL, NULL);
40caaeec 1191 if (fdcount < 0) {
e5a2989e 1192 if (errno != EINTR)
7d563a17 1193 err(udev, "error in select: %s\n", strerror(errno));
f27125f9 1194 continue;
2f6cbd19 1195 }
e5a2989e 1196
b3518c16 1197 /* get control message */
d59f11e1
KS
1198 if (FD_ISSET(udev_ctrl_get_fd(udev_ctrl), &readfds))
1199 handle_ctrl_msg(udev_ctrl);
88f4b648 1200
b3518c16 1201 /* get netlink message */
833b3c68 1202 if (FD_ISSET(uevent_netlink_sock, &readfds)) {
7d563a17 1203 msg = get_netlink_msg(udev);
0b3dfb3d 1204 if (msg)
021a294c
KS
1205 msg_queue_insert(msg);
1206 }
e5a2989e 1207
63cc8f04 1208 /* received a signal, clear our notification pipe */
c6303c13
KS
1209 if (FD_ISSET(signal_pipe[READ_END], &readfds)) {
1210 char buf[256];
1211
1212 read(signal_pipe[READ_END], &buf, sizeof(buf));
40caaeec 1213 }
e5a2989e 1214
c895fd00 1215 /* rules directory inotify watch */
90cd961e 1216 if ((inotify_fd >= 0) && FD_ISSET(inotify_fd, &readfds)) {
c895fd00
KS
1217 int nbytes;
1218
1219 /* discard all possible events, we can just reload the config */
254d6d3c 1220 if ((ioctl(inotify_fd, FIONREAD, &nbytes) == 0) && nbytes > 0) {
c895fd00
KS
1221 char *buf;
1222
1223 reload_config = 1;
1224 buf = malloc(nbytes);
f4dce170 1225 if (buf == NULL) {
7d563a17 1226 err(udev, "error getting buffer for inotify, disable watching\n");
c895fd00
KS
1227 close(inotify_fd);
1228 inotify_fd = -1;
1229 }
1230 read(inotify_fd, buf, nbytes);
1231 free(buf);
1232 }
1233 }
1234
e3396a2d 1235 /* rules changed, set by inotify or a HUP signal */
c895fd00
KS
1236 if (reload_config) {
1237 reload_config = 0;
1aa1e248 1238 udev_rules_cleanup(&rules);
7d563a17 1239 udev_rules_init(udev, &rules, 1);
c895fd00
KS
1240 }
1241
0b3dfb3d 1242 /* forked child has returned */
5cab7caa
KS
1243 if (sigchilds_waiting) {
1244 sigchilds_waiting = 0;
1245 reap_sigchilds();
f27125f9 1246 }
e5a2989e 1247
f27125f9 1248 if (run_exec_q) {
f27125f9 1249 run_exec_q = 0;
3b47c739 1250 if (!stop_exec_q)
7d563a17 1251 msg_queue_manager(udev);
53921bfa 1252 }
53921bfa 1253 }
e3396a2d 1254 rc = 0;
ec9cc012 1255
53921bfa 1256exit:
1aa1e248
KS
1257 udev_rules_cleanup(&rules);
1258 sysfs_cleanup();
7d563a17 1259 selinux_exit(udev);
c895fd00 1260
90cd961e 1261 if (signal_pipe[READ_END] >= 0)
f1ff8d7b 1262 close(signal_pipe[READ_END]);
90cd961e 1263 if (signal_pipe[WRITE_END] >= 0)
f1ff8d7b 1264 close(signal_pipe[WRITE_END]);
2b996ad1 1265
d59f11e1 1266 udev_ctrl_unref(udev_ctrl);
90cd961e 1267 if (inotify_fd >= 0)
c895fd00 1268 close(inotify_fd);
90cd961e 1269 if (uevent_netlink_sock >= 0)
63cc8f04
KS
1270 close(uevent_netlink_sock);
1271
7257cb18 1272 logging_close();
833b3c68 1273 return rc;
7fafc032 1274}