chiark / gitweb /
udevd: listen for netlink events
[elogind.git] / udevd.c
1 /*
2  * udevd.c - hotplug event serializer
3  *
4  * Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
5  * Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
6  *
7  *
8  *      This program is free software; you can redistribute it and/or modify it
9  *      under the terms of the GNU General Public License as published by the
10  *      Free Software Foundation version 2 of the License.
11  *
12  *      This program is distributed in the hope that it will be useful, but
13  *      WITHOUT ANY WARRANTY; without even the implied warranty of
14  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *      General Public License for more details.
16  *
17  *      You should have received a copy of the GNU General Public License along
18  *      with this program; if not, write to the Free Software Foundation, Inc.,
19  *      675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  */
22
23 #include <stddef.h>
24 #include <signal.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <dirent.h>
32 #include <fcntl.h>
33 #include <sys/select.h>
34 #include <sys/wait.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/un.h>
39 #include <sys/sysinfo.h>
40 #include <sys/stat.h>
41 #include <linux/netlink.h>
42
43 #include "list.h"
44 #include "udev_libc_wrapper.h"
45 #include "udev.h"
46 #include "udev_version.h"
47 #include "udev_utils.h"
48 #include "udevd.h"
49 #include "logging.h"
50
51 /* global variables*/
52 static int udevsendsock;
53 static int ueventsock;
54 static pid_t sid;
55
56 static int pipefds[2];
57 static long startup_time;
58 static unsigned long long expected_seqnum = 0;
59 static volatile int sigchilds_waiting;
60 static volatile int run_msg_q;
61 static volatile int sig_flag;
62 static int run_exec_q;
63
64 static LIST_HEAD(msg_list);
65 static LIST_HEAD(exec_list);
66 static LIST_HEAD(running_list);
67
68 static void exec_queue_manager(void);
69 static void msg_queue_manager(void);
70 static void user_sighandler(void);
71 static void reap_sigchilds(void);
72 char *udev_bin;
73
74 #ifdef USE_LOG
75 void log_message (int priority, const char *format, ...)
76 {
77         va_list args;
78
79         if (priority > udev_log_priority)
80                 return;
81
82         va_start(args, format);
83         vsyslog(priority, format, args);
84         va_end(args);
85 }
86 #endif
87
88 static void msg_dump_queue(void)
89 {
90 #ifdef DEBUG
91         struct hotplug_msg *msg;
92
93         list_for_each_entry(msg, &msg_list, node)
94                 dbg("sequence %llu in queue", msg->seqnum);
95 #endif
96 }
97
98 static void run_queue_delete(struct hotplug_msg *msg)
99 {
100         list_del(&msg->node);
101         free(msg);
102 }
103
104 /* orders the message in the queue by sequence number */
105 static void msg_queue_insert(struct hotplug_msg *msg)
106 {
107         struct hotplug_msg *loop_msg;
108         struct sysinfo info;
109
110         if (msg->seqnum == 0) {
111                 dbg("no SEQNUM, move straight to the exec queue");
112                 list_add(&msg->node, &exec_list);
113                 run_exec_q = 1;
114                 return;
115         }
116
117         /* don't delay messages with timeout set */
118         if (msg->timeout) {
119                 dbg("move seq %llu with timeout %u to exec queue", msg->seqnum, msg->timeout);
120                 list_add(&msg->node, &exec_list);
121                 run_exec_q = 1;
122                 return;
123         }
124
125         /* sort message by sequence number into list */
126         list_for_each_entry_reverse(loop_msg, &msg_list, node) {
127                 if (loop_msg->seqnum < msg->seqnum)
128                         break;
129
130                 if (loop_msg->seqnum == msg->seqnum) {
131                         dbg("ignoring duplicate message seq %llu", msg->seqnum);
132                         free(msg);
133                         return;
134                 }
135         }
136
137         /* store timestamp of queuing */
138         sysinfo(&info);
139         msg->queue_time = info.uptime;
140
141         list_add(&msg->node, &loop_msg->node);
142         dbg("queued message seq %llu", msg->seqnum);
143
144         /* run msg queue manager */
145         run_msg_q = 1;
146
147         return;
148 }
149
150 /* forks event and removes event from run queue when finished */
151 static void execute_udev(struct hotplug_msg *msg)
152 {
153         char *const argv[] = { "udev", msg->subsystem, NULL };
154         pid_t pid;
155
156         pid = fork();
157         switch (pid) {
158         case 0:
159                 /* child */
160                 if (ueventsock != -1)
161                         close(ueventsock);
162                 close(udevsendsock);
163                 logging_close();
164
165                 setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY);
166                 execve(udev_bin, argv, msg->envp);
167                 err("exec of child failed");
168                 _exit(1);
169                 break;
170         case -1:
171                 err("fork of child failed");
172                 run_queue_delete(msg);
173                 break;
174         default:
175                 /* get SIGCHLD in main loop */
176                 dbg("==> exec seq %llu [%d] working at '%s'", msg->seqnum, pid, msg->devpath);
177                 msg->pid = pid;
178         }
179 }
180
181 static int running_processes(void)
182 {
183         int f;
184         static char buf[4096];
185         int len;
186         int running;
187         const char *pos;
188
189         f = open("/proc/stat", O_RDONLY);
190         if (f == -1)
191                 return -1;
192
193         len = read(f, buf, sizeof(buf));
194         close(f);
195
196         if (len <= 0)
197                 return -1;
198         else
199                 buf[len] = '\0';
200
201         pos = strstr(buf, "procs_running ");
202         if (pos == NULL)
203                 return -1;
204
205         if (sscanf(pos, "procs_running %u", &running) != 1)
206                 return -1;
207
208         return running;
209 }
210
211 /* return the number of process es in our session, count only until limit */
212 static int running_processes_in_session(pid_t session, int limit)
213 {
214         DIR *dir;
215         struct dirent *dent;
216         int running = 0;
217
218         dir = opendir("/proc");
219         if (!dir)
220                 return -1;
221
222         /* read process info from /proc */
223         for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
224                 int f;
225                 char procdir[64];
226                 char line[256];
227                 const char *pos;
228                 char state;
229                 pid_t ppid, pgrp, sess;
230                 int len;
231
232                 if (!isdigit(dent->d_name[0]))
233                         continue;
234
235                 snprintf(procdir, sizeof(procdir), "/proc/%s/stat", dent->d_name);
236                 procdir[sizeof(procdir)-1] = '\0';
237
238                 f = open(procdir, O_RDONLY);
239                 if (f == -1)
240                         continue;
241
242                 len = read(f, line, sizeof(line));
243                 close(f);
244
245                 if (len <= 0)
246                         continue;
247                 else
248                         line[len] = '\0';
249
250                 /* skip ugly program name */
251                 pos = strrchr(line, ')') + 2;
252                 if (pos == NULL)
253                         continue;
254
255                 if (sscanf(pos, "%c %d %d %d ", &state, &ppid, &pgrp, &sess) != 4)
256                         continue;
257
258                 /* count only processes in our session */
259                 if (sess != session)
260                         continue;
261
262                 /* count only running, no sleeping processes */
263                 if (state != 'R')
264                         continue;
265
266                 running++;
267                 if (limit > 0 && running >= limit)
268                         break;
269         }
270         closedir(dir);
271
272         return running;
273 }
274
275 static int compare_devpath(const char *running, const char *waiting)
276 {
277         int i;
278
279         for (i = 0; i < PATH_SIZE; i++) {
280                 /* identical device event found */
281                 if (running[i] == '\0' && waiting[i] == '\0')
282                         return 1;
283
284                 /* parent device event found */
285                 if (running[i] == '\0' && waiting[i] == '/')
286                         return 2;
287
288                 /* child device event found */
289                 if (running[i] == '/' && waiting[i] == '\0')
290                         return 3;
291
292                 /* no matching event */
293                 if (running[i] != waiting[i])
294                         break;
295         }
296
297         return 0;
298 }
299
300 /* returns still running task for the same device, its parent or its physical device */
301 static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg)
302 {
303         struct hotplug_msg *loop_msg;
304
305         if (msg->devpath == NULL)
306                 return NULL;
307
308         /* skip any events with a timeout set */
309         if (msg->timeout)
310                 return NULL;
311
312         list_for_each_entry(loop_msg, &running_list, node) {
313                 if (loop_msg->devpath == NULL)
314                         continue;
315
316                 /* return running parent/child device event */
317                 if (compare_devpath(loop_msg->devpath, msg->devpath) != 0)
318                         return loop_msg;
319
320                 /* return running physical device event */
321                 if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0)
322                         if (compare_devpath(loop_msg->devpath, msg->physdevpath) != 0)
323                                 return loop_msg;
324         }
325
326         return NULL;
327 }
328
329 /* exec queue management routine executes the events and serializes events in the same sequence */
330 static void exec_queue_manager(void)
331 {
332         struct hotplug_msg *loop_msg;
333         struct hotplug_msg *tmp_msg;
334         struct hotplug_msg *msg;
335         int running;
336
337         running = running_processes();
338         dbg("%d processes runnning on system", running);
339         if (running < 0)
340                 running = THROTTLE_MAX_RUNNING_CHILDS;
341
342         list_for_each_entry_safe(loop_msg, tmp_msg, &exec_list, node) {
343                 /* check running processes in our session and possibly throttle */
344                 if (running >= THROTTLE_MAX_RUNNING_CHILDS) {
345                         running = running_processes_in_session(sid, THROTTLE_MAX_RUNNING_CHILDS+10);
346                         dbg("%d processes running in session", running);
347                         if (running >= THROTTLE_MAX_RUNNING_CHILDS) {
348                                 dbg("delay seq %llu, cause too many processes already running", loop_msg->seqnum);
349                                 return;
350                         }
351                 }
352
353                 msg = running_with_devpath(loop_msg);
354                 if (!msg) {
355                         /* move event to run list */
356                         list_move_tail(&loop_msg->node, &running_list);
357                         execute_udev(loop_msg);
358                         running++;
359                         dbg("moved seq %llu to running list", loop_msg->seqnum);
360                 } else {
361                         dbg("delay seq %llu (%s), cause seq %llu (%s) is still running",
362                             loop_msg->seqnum, loop_msg->devpath, msg->seqnum, msg->devpath);
363                 }
364         }
365 }
366
367 static void msg_move_exec(struct hotplug_msg *msg)
368 {
369         list_move_tail(&msg->node, &exec_list);
370         run_exec_q = 1;
371         expected_seqnum = msg->seqnum+1;
372         dbg("moved seq %llu to exec, next expected is %llu",
373                 msg->seqnum, expected_seqnum);
374 }
375
376 /* msg queue management routine handles the timeouts and dispatches the events */
377 static void msg_queue_manager(void)
378 {
379         struct hotplug_msg *loop_msg;
380         struct hotplug_msg *tmp_msg;
381         struct sysinfo info;
382         long msg_age = 0;
383         static int timeout = EVENT_INIT_TIMEOUT_SEC;
384         static int init = 1;
385
386         dbg("msg queue manager, next expected is %llu", expected_seqnum);
387 recheck:
388         list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, node) {
389                 /* move event with expected sequence to the exec list */
390                 if (loop_msg->seqnum == expected_seqnum) {
391                         msg_move_exec(loop_msg);
392                         continue;
393                 }
394
395                 /* see if we are in the initialization phase and wait for the very first events */
396                 if (init && (info.uptime - startup_time >= INIT_TIME_SEC)) {
397                         init = 0;
398                         timeout = EVENT_TIMEOUT_SEC;
399                         dbg("initialization phase passed, set timeout to %i seconds", EVENT_TIMEOUT_SEC);
400                 }
401
402                 /* move event with expired timeout to the exec list */
403                 sysinfo(&info);
404                 msg_age = info.uptime - loop_msg->queue_time;
405                 dbg("seq %llu is %li seconds old", loop_msg->seqnum, msg_age);
406                 if (msg_age >= timeout) {
407                         msg_move_exec(loop_msg);
408                         goto recheck;
409                 } else {
410                         break;
411                 }
412         }
413
414         msg_dump_queue();
415
416         /* set timeout for remaining queued events */
417         if (list_empty(&msg_list) == 0) {
418                 struct itimerval itv = {{0, 0}, {timeout - msg_age, 0}};
419                 dbg("next event expires in %li seconds", timeout - msg_age);
420                 setitimer(ITIMER_REAL, &itv, NULL);
421         }
422 }
423
424 static struct hotplug_msg *get_msg_from_envbuf(const char *buf, int buf_size)
425 {
426         int bufpos;
427         int i;
428         struct hotplug_msg *msg;
429
430         msg = malloc(sizeof(struct hotplug_msg) + buf_size);
431         if (msg == NULL)
432                 return NULL;
433         memset(msg, 0x00, sizeof(struct hotplug_msg) + buf_size);
434
435         /* copy environment buffer and reconstruct envp */
436         memcpy(msg->envbuf, buf, buf_size);
437         bufpos = 0;
438         for (i = 0; (bufpos < buf_size) && (i < HOTPLUG_NUM_ENVP-2); i++) {
439                 int keylen;
440                 char *key;
441
442                 key = &msg->envbuf[bufpos];
443                 keylen = strlen(key);
444                 msg->envp[i] = key;
445                 bufpos += keylen + 1;
446                 dbg("add '%s' to msg.envp[%i]", msg->envp[i], i);
447
448                 /* remember some keys for further processing */
449                 if (strncmp(key, "ACTION=", 7) == 0)
450                         msg->action = &key[7];
451
452                 if (strncmp(key, "DEVPATH=", 8) == 0)
453                         msg->devpath = &key[8];
454
455                 if (strncmp(key, "SUBSYSTEM=", 10) == 0)
456                         msg->subsystem = &key[10];
457
458                 if (strncmp(key, "SEQNUM=", 7) == 0)
459                         msg->seqnum = strtoull(&key[7], NULL, 10);
460
461                 if (strncmp(key, "PHYSDEVPATH=", 12) == 0)
462                         msg->physdevpath = &key[12];
463
464                 if (strncmp(key, "TIMEOUT=", 8) == 0)
465                         msg->timeout = strtoull(&key[8], NULL, 10);
466         }
467         msg->envp[i++] = "UDEVD_EVENT=1";
468         msg->envp[i] = NULL;
469
470         return msg;
471 }
472
473 /* receive the udevsend message and do some sanity checks */
474 static struct hotplug_msg *get_udevsend_msg(void)
475 {
476         static struct udevsend_msg usend_msg;
477         struct hotplug_msg *msg;
478         ssize_t size;
479         struct msghdr smsg;
480         struct cmsghdr *cmsg;
481         struct iovec iov;
482         struct ucred *cred;
483         char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
484         int envbuf_size;
485
486         memset(&usend_msg, 0x00, sizeof(struct udevsend_msg));
487         iov.iov_base = &usend_msg;
488         iov.iov_len = sizeof(struct udevsend_msg);
489
490         memset(&smsg, 0x00, sizeof(struct msghdr));
491         smsg.msg_iov = &iov;
492         smsg.msg_iovlen = 1;
493         smsg.msg_control = cred_msg;
494         smsg.msg_controllen = sizeof(cred_msg);
495
496         size = recvmsg(udevsendsock, &smsg, 0);
497         if (size <  0) {
498                 if (errno != EINTR)
499                         dbg("unable to receive udevsend message");
500                 return NULL;
501         }
502         cmsg = CMSG_FIRSTHDR(&smsg);
503         cred = (struct ucred *) CMSG_DATA(cmsg);
504
505         if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
506                 info("no sender credentials received, message ignored");
507                 return NULL;
508         }
509
510         if (cred->uid != 0) {
511                 info("sender uid=%i, message ignored", cred->uid);
512                 return NULL;
513         }
514
515         if (strncmp(usend_msg.magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) {
516                 info("message magic '%s' doesn't match, ignore it", usend_msg.magic);
517                 return NULL;
518         }
519
520         envbuf_size = size - offsetof(struct udevsend_msg, envbuf);
521         dbg("envbuf_size=%i", envbuf_size);
522         msg = get_msg_from_envbuf(usend_msg.envbuf, envbuf_size);
523         if (msg == NULL)
524                 return NULL;
525
526         return msg;
527 }
528
529 /* receive the kernel user event message and do some sanity checks */
530 static struct hotplug_msg *get_uevent_msg(void)
531 {
532         struct hotplug_msg *msg;
533         int bufpos;
534         ssize_t size;
535         static char buffer[HOTPLUG_BUFFER_SIZE + 512];
536         char *pos;
537
538         size = recv(ueventsock, &buffer, sizeof(buffer), 0);
539         if (size <  0) {
540                 if (errno != EINTR)
541                         dbg("unable to receive udevsend message");
542                 return NULL;
543         }
544
545         if ((size_t)size > sizeof(buffer)-1)
546                 size = sizeof(buffer)-1;
547         buffer[size] = '\0';
548         dbg("uevent_size=%i", size);
549
550         /* start of event payload */
551         bufpos = strlen(buffer)+1;
552         msg = get_msg_from_envbuf(&buffer[bufpos], size-bufpos);
553         if (msg == NULL)
554                 return NULL;
555
556         /* validate message */
557         pos = strchr(buffer, '@');
558         if (pos == NULL) {
559                 dbg("invalid uevent '%s'", buffer);
560                 free(msg);
561                 return NULL;
562         }
563         pos[0] = '\0';
564
565         if (msg->action == NULL) {
566                 dbg("no ACTION in payload found, skip event '%s'", buffer);
567                 free(msg);
568                 return NULL;
569         }
570
571         if (strcmp(msg->action, buffer) != 0) {
572                 dbg("ACTION in payload does not match uevent, skip event '%s'", buffer);
573                 free(msg);
574                 return NULL;
575         }
576
577         return msg;
578 }
579
580 static void asmlinkage sig_handler(int signum)
581 {
582         int rc;
583
584         switch (signum) {
585                 case SIGINT:
586                 case SIGTERM:
587                         exit(20 + signum);
588                         break;
589                 case SIGALRM:
590                         /* set flag, then write to pipe if needed */
591                         run_msg_q = 1;
592                         goto do_write;
593                         break;
594                 case SIGCHLD:
595                         /* set flag, then write to pipe if needed */
596                         sigchilds_waiting = 1;
597                         goto do_write;
598                         break;
599         }
600
601 do_write:
602         /* if pipe is empty, write to pipe to force select to return
603          * immediately when it gets called
604          */
605         if (!sig_flag) {
606                 rc = write(pipefds[1],&signum,sizeof(signum));
607                 if (rc >= 0)
608                         sig_flag = 1;
609         }
610 }
611
612 static void udev_done(int pid)
613 {
614         /* find msg associated with pid and delete it */
615         struct hotplug_msg *msg;
616
617         list_for_each_entry(msg, &running_list, node) {
618                 if (msg->pid == pid) {
619                         dbg("<== exec seq %llu came back", msg->seqnum);
620                         run_queue_delete(msg);
621
622                         /* we want to run the exec queue manager since there may
623                          * be events waiting with the devpath of the one that
624                          * just finished
625                          */
626                         run_exec_q = 1;
627                         return;
628                 }
629         }
630 }
631
632 static void reap_sigchilds(void)
633 {
634         while(1) {
635                 int pid = waitpid(-1, NULL, WNOHANG);
636                 if ((pid == -1) || (pid == 0))
637                         break;
638                 udev_done(pid);
639         }
640 }
641
642 /* just read everything from the pipe and clear the flag,
643  * the flags was set in the signal handler
644  */
645 static void user_sighandler(void)
646 {
647         int sig;
648
649         while(1) {
650                 int rc = read(pipefds[0], &sig, sizeof(sig));
651                 if (rc < 0)
652                         break;
653
654                 sig_flag = 0;
655         }
656 }
657
658 static int init_udevsend_socket(void)
659 {
660         struct sockaddr_un saddr;
661         socklen_t addrlen;
662         const int feature_on = 1;
663         int retval;
664
665         memset(&saddr, 0x00, sizeof(saddr));
666         saddr.sun_family = AF_LOCAL;
667         /* use abstract namespace for socket path */
668         strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH);
669         addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1;
670
671         udevsendsock = socket(AF_LOCAL, SOCK_DGRAM, 0);
672         if (udevsendsock == -1) {
673                 err("error getting socket, %s", strerror(errno));
674                 return -1;
675         }
676
677         /* the bind takes care of ensuring only one copy running */
678         retval = bind(udevsendsock, (struct sockaddr *) &saddr, addrlen);
679         if (retval < 0) {
680                 err("bind failed, %s", strerror(errno));
681                 close(udevsendsock);
682                 return -1;
683         }
684
685         /* enable receiving of the sender credentials */
686         setsockopt(udevsendsock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on));
687
688         return 0;
689 }
690
691 static int init_uevent_socket(void)
692 {
693         struct sockaddr_nl snl;
694         int retval;
695
696         memset(&snl, 0x00, sizeof(struct sockaddr_nl));
697         snl.nl_family = AF_NETLINK;
698         snl.nl_pid = getpid();
699         snl.nl_groups = 0xffffffff;
700
701         ueventsock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
702         if (ueventsock == -1) {
703                 dbg("error getting socket, %s", strerror(errno));
704                 return -1;
705         }
706
707         retval = bind(ueventsock, (struct sockaddr *) &snl,
708                       sizeof(struct sockaddr_nl));
709         if (retval < 0) {
710                 dbg("bind failed, %s", strerror(errno));
711                 close(ueventsock);
712                 ueventsock = -1;
713                 return -1;
714         }
715
716         return 0;
717 }
718
719 int main(int argc, char *argv[], char *envp[])
720 {
721         struct sysinfo info;
722         int maxsockplus;
723         int retval;
724         int fd;
725         struct sigaction act;
726         fd_set readfds;
727         const char *udevd_expected_seqnum;
728         int uevent_active = 0;
729
730         logging_init("udevd");
731         udev_init_config();
732         dbg("version %s", UDEV_VERSION);
733
734         if (getuid() != 0) {
735                 err("need to be root, exit");
736                 goto exit;
737         }
738
739         /* daemonize on request */
740         if (argc == 2 && strcmp(argv[1], "-d") == 0) {
741                 pid_t pid;
742
743                 pid = fork();
744                 switch (pid) {
745                 case 0:
746                         dbg("damonized fork running");
747                         break;
748                 case -1:
749                         err("fork of daemon failed");
750                         goto exit;
751                 default:
752                         logging_close();
753                         exit(0);
754                 }
755         }
756
757         /* become session leader */
758         sid = setsid();
759         dbg("our session is %d", sid);
760
761         /* make sure we don't lock any path */
762         chdir("/");
763         umask(umask(077) | 022);
764
765         /*set a reasonable scheduling priority for the daemon */
766         setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY);
767
768         /* Set fds to dev/null */
769         fd = open( "/dev/null", O_RDWR );
770         if (fd >= 0)  {
771                 dup2(fd, 0);
772                 dup2(fd, 1);
773                 dup2(fd, 2);
774                 if (fd > 2)
775                         close(fd);
776         } else
777                 err("error opening /dev/null %s", strerror(errno));
778
779         /* setup signal handler pipe */
780         retval = pipe(pipefds);
781         if (retval < 0) {
782                 err("error getting pipes: %s", strerror(errno));
783                 goto exit;
784         }
785
786         retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK);
787         if (retval < 0) {
788                 err("error fcntl on read pipe: %s", strerror(errno));
789                 goto exit;
790         }
791         retval = fcntl(pipefds[0], F_SETFD, FD_CLOEXEC);
792         if (retval < 0)
793                 err("error fcntl on read pipe: %s", strerror(errno));
794
795         retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK);
796         if (retval < 0) {
797                 err("error fcntl on write pipe: %s", strerror(errno));
798                 goto exit;
799         }
800         retval = fcntl(pipefds[1], F_SETFD, FD_CLOEXEC);
801         if (retval < 0)
802                 err("error fcntl on write pipe: %s", strerror(errno));
803
804         /* set signal handlers */
805         memset(&act, 0x00, sizeof(struct sigaction));
806         act.sa_handler = (void (*)(int)) sig_handler;
807         sigemptyset(&act.sa_mask);
808         act.sa_flags = SA_RESTART;
809         sigaction(SIGINT, &act, NULL);
810         sigaction(SIGTERM, &act, NULL);
811         sigaction(SIGALRM, &act, NULL);
812         sigaction(SIGCHLD, &act, NULL);
813
814         if (init_uevent_socket() < 0) {
815                 dbg("uevent socket not available");
816         }
817
818         if (init_udevsend_socket() < 0) {
819                 if (errno == EADDRINUSE)
820                         dbg("another udevd running, exit");
821                 else
822                         dbg("error initialising udevsend socket: %s", strerror(errno));
823
824                 goto exit;
825         }
826
827         /* possible override of udev binary, used for testing */
828         udev_bin = getenv("UDEV_BIN");
829         if (udev_bin != NULL)
830                 info("udev binary is set to '%s'", udev_bin);
831         else
832                 udev_bin = UDEV_BIN;
833
834         /* possible init of expected_seqnum value */
835         udevd_expected_seqnum = getenv("UDEVD_EXPECTED_SEQNUM");
836         if (udevd_expected_seqnum != NULL) {
837                 expected_seqnum = strtoull(udevd_expected_seqnum, NULL, 10);
838                 info("initialize expected_seqnum to %llu", expected_seqnum);
839         }
840
841         /* get current time to provide shorter timeout on startup */
842         sysinfo(&info);
843         startup_time = info.uptime;
844
845         FD_ZERO(&readfds);
846         FD_SET(udevsendsock, &readfds);
847         if (ueventsock != -1)
848                 FD_SET(ueventsock, &readfds);
849         FD_SET(pipefds[0], &readfds);
850         maxsockplus = udevsendsock+1;
851         while (1) {
852                 struct hotplug_msg *msg;
853
854                 fd_set workreadfds = readfds;
855                 retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL);
856
857                 if (retval < 0) {
858                         if (errno != EINTR)
859                                 dbg("error in select: %s", strerror(errno));
860                         continue;
861                 }
862
863                 if (FD_ISSET(udevsendsock, &workreadfds)) {
864                         msg = get_udevsend_msg();
865                         if (msg) {
866                                 /* discard kernel messages if netlink is active */
867                                 if (uevent_active && msg->seqnum != 0) {
868                                         dbg("skip kernel udevsend message, netlink is active");
869                                         free(msg);
870                                         continue;
871                                 }
872                                 msg_queue_insert(msg);
873                         }
874                 }
875
876                 if (FD_ISSET(ueventsock, &workreadfds)) {
877                         msg = get_uevent_msg();
878                         if (msg) {
879                                 msg_queue_insert(msg);
880                                 /* disable udevsend with first netlink message */
881                                 if (!uevent_active) {
882                                         info("netlink message received, disable kernel udevsend messages");
883                                         uevent_active = 1;
884                                 }
885                         }
886                 }
887
888                 if (FD_ISSET(pipefds[0], &workreadfds))
889                         user_sighandler();
890
891                 if (sigchilds_waiting) {
892                         sigchilds_waiting = 0;
893                         reap_sigchilds();
894                 }
895
896                 if (run_msg_q) {
897                         run_msg_q = 0;
898                         msg_queue_manager();
899                 }
900
901                 if (run_exec_q) {
902                          /* clean up running_list before calling exec_queue_manager() */
903                         if (sigchilds_waiting) {
904                                 sigchilds_waiting = 0;
905                                 reap_sigchilds();
906                         }
907
908                         run_exec_q = 0;
909                         exec_queue_manager();
910                 }
911         }
912
913 exit:
914         logging_close();
915         return 1;
916 }