]> git.saurik.com Git - apple/syslog.git/blob - syslogd.tproj/syslogd.c
bcd1e2aff024195f82d89b008a9ef905d2bcfcb9
[apple/syslog.git] / syslogd.tproj / syslogd.c
1 /*
2 * Copyright (c) 2004-2012 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <TargetConditionals.h>
25
26 #include <assert.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <signal.h>
32 #include <mach/mach.h>
33 #include <mach/mach_error.h>
34 #include <mach/mach_time.h>
35 #include <servers/bootstrap.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/sysctl.h>
39 #include <sys/stat.h>
40 #include <sys/fcntl.h>
41 #include <sys/errno.h>
42 #include <sys/queue.h>
43 #include <sys/time.h>
44 #include <sys/un.h>
45 #include <pthread.h>
46 #include <dirent.h>
47 #include <dlfcn.h>
48 #include <libgen.h>
49 #include <notify.h>
50 #include <notify_keys.h>
51 #include <utmpx.h>
52 #include <vproc_priv.h>
53 #if !TARGET_OS_IPHONE
54 #include <quarantine.h>
55 #endif
56 #include "daemon.h"
57
58 #define SERVICE_NAME "com.apple.system.logger"
59 #define SERVER_STATUS_ERROR -1
60 #define SERVER_STATUS_INACTIVE 0
61 #define SERVER_STATUS_ACTIVE 1
62 #define SERVER_STATUS_ON_DEMAND 2
63
64 #define BILLION 1000000000
65
66 #define NOTIFY_DELAY 1
67
68 #define streq(A,B) (strcmp(A,B)==0)
69 #define forever for(;;)
70
71 extern int _malloc_no_asl_log;
72
73 #if TARGET_IPHONE_SIMULATOR
74 const char *_path_pidfile;
75 const char *_path_syslogd_log;
76 #endif
77
78 /* global */
79 struct global_s global;
80
81 #if !TARGET_IPHONE_SIMULATOR
82 /* Input Modules */
83 int klog_in_init(void);
84 int klog_in_reset(void);
85 int klog_in_close(void);
86 static int activate_klog_in = 1;
87 #endif
88
89 int bsd_in_init(void);
90 int bsd_in_reset(void);
91 int bsd_in_close(void);
92 static int activate_bsd_in = 1;
93
94 #if !TARGET_IPHONE_SIMULATOR
95 int udp_in_init(void);
96 int udp_in_reset(void);
97 int udp_in_close(void);
98 static int activate_udp_in = 1;
99
100 /* Output Modules */
101 int bsd_out_init(void);
102 int bsd_out_reset(void);
103 int bsd_out_close(void);
104 static int activate_bsd_out = 1;
105 #endif
106
107 int asl_action_init(void);
108 int asl_action_reset(void);
109 int asl_action_close(void);
110 static int activate_asl_action = 1;
111
112 #if !TARGET_IPHONE_SIMULATOR
113 /* Interactive Module */
114 int remote_init(void);
115 int remote_reset(void);
116 int remote_close(void);
117 static int remote_enabled = 0;
118 #endif
119
120 extern void database_server();
121
122 static void
123 init_modules()
124 {
125 #if !TARGET_IPHONE_SIMULATOR
126 module_t *m_klog_in, *m_bsd_out, *m_udp_in, *m_remote;
127 #endif
128 module_t *m_asl, *m_bsd_in;
129 int m = 0;
130
131 /* ASL module (configured by /etc/asl.conf) */
132 m_asl = (module_t *)calloc(1, sizeof(module_t));
133 if (m_asl == NULL)
134 {
135 asldebug("alloc failed (init_modules asl_action)\n");
136 exit(1);
137 }
138
139 m_asl->name = "asl_action";
140 m_asl->enabled = activate_asl_action;
141 m_asl->init = asl_action_init;
142 m_asl->reset = asl_action_reset;
143 m_asl->close = asl_action_close;
144
145 if (m_asl->enabled) m_asl->init();
146
147 #if !TARGET_IPHONE_SIMULATOR
148 /* BSD output module (configured by /etc/syslog.conf) */
149 m_bsd_out = (module_t *)calloc(1, sizeof(module_t));
150 if (m_bsd_out == NULL)
151 {
152 asldebug("alloc failed (init_modules bsd_out)\n");
153 exit(1);
154 }
155
156 m_bsd_out->name = "bsd_out";
157 m_bsd_out->enabled = activate_bsd_out;
158 m_bsd_out->init = bsd_out_init;
159 m_bsd_out->reset = bsd_out_reset;
160 m_bsd_out->close = bsd_out_close;
161
162 if (m_bsd_out->enabled)
163 {
164 m_bsd_out->init();
165 global.bsd_out_enabled = 1;
166 }
167
168 /* kernel input module */
169 m_klog_in = (module_t *)calloc(1, sizeof(module_t));
170 if (m_klog_in == NULL)
171 {
172 asldebug("alloc failed (init_modules klog_in)\n");
173 exit(1);
174 }
175
176 m_klog_in->name = "klog_in";
177 m_klog_in->enabled = activate_klog_in;
178 m_klog_in->init = klog_in_init;
179 m_klog_in->reset = klog_in_reset;
180 m_klog_in->close = klog_in_close;
181
182 if (m_klog_in->enabled) m_klog_in->init();
183 #endif
184
185 /* BSD (UNIX domain socket) input module */
186 m_bsd_in = (module_t *)calloc(1, sizeof(module_t));
187 if (m_bsd_in == NULL)
188 {
189 asldebug("alloc failed (init_modules bsd_in)\n");
190 exit(1);
191 }
192
193 m_bsd_in->name = "bsd_in";
194 m_bsd_in->enabled = activate_bsd_in;
195 m_bsd_in->init = bsd_in_init;
196 m_bsd_in->reset = bsd_in_reset;
197 m_bsd_in->close = bsd_in_close;
198
199 if (m_bsd_in->enabled) m_bsd_in->init();
200
201 #if !TARGET_IPHONE_SIMULATOR
202 /* network (syslog protocol) input module */
203 m_udp_in = (module_t *)calloc(1, sizeof(module_t));
204 if (m_udp_in == NULL)
205 {
206 asldebug("alloc failed (init_modules udp_in)\n");
207 exit(1);
208 }
209
210 m_udp_in->name = "udp_in";
211 m_udp_in->enabled = activate_udp_in;
212 m_udp_in->init = udp_in_init;
213 m_udp_in->reset = udp_in_reset;
214 m_udp_in->close = udp_in_close;
215
216 if (m_udp_in->enabled) m_udp_in->init();
217
218 /* remote (iOS support) module */
219 m_remote = (module_t *)calloc(1, sizeof(module_t));
220 if (m_remote == NULL)
221 {
222 asldebug("alloc failed (init_modules remote)\n");
223 exit(1);
224 }
225
226 m_remote->name = "remote";
227 m_remote->enabled = remote_enabled;
228 m_remote->init = remote_init;
229 m_remote->reset = remote_reset;
230 m_remote->close = remote_close;
231
232 if (m_remote->enabled) m_remote->init();
233 #endif /* TARGET_IPHONE_SIMULATOR */
234
235 /* save modules in global.module array */
236 #if TARGET_IPHONE_SIMULATOR
237 global.module_count = 2;
238 #else
239 global.module_count = 6;
240 #endif
241 global.module = (module_t **)calloc(global.module_count, sizeof(module_t *));
242 if (global.module == NULL)
243 {
244 asldebug("alloc failed (init_modules)\n");
245 exit(1);
246 }
247
248 global.module[m++] = m_asl;
249 global.module[m++] = m_bsd_in;
250 #if !TARGET_IPHONE_SIMULATOR
251 global.module[m++] = m_bsd_out;
252 global.module[m++] = m_klog_in;
253 global.module[m++] = m_udp_in;
254 global.module[m++] = m_remote;
255 #endif
256 }
257
258 static void
259 writepid(int *first)
260 {
261 struct stat sb;
262 FILE *fp;
263
264 if (first != NULL)
265 {
266 *first = 1;
267 memset(&sb, 0, sizeof(struct stat));
268 if (stat(_PATH_PIDFILE, &sb) == 0)
269 {
270 if (S_ISREG(sb.st_mode)) *first = 0;
271 }
272 }
273
274 fp = fopen(_PATH_PIDFILE, "w");
275 if (fp != NULL)
276 {
277 fprintf(fp, "%d\n", global.pid);
278 fclose(fp);
279 }
280 }
281
282 void
283 launch_config()
284 {
285 launch_data_t tmp, pdict;
286 kern_return_t status;
287
288 tmp = launch_data_new_string(LAUNCH_KEY_CHECKIN);
289 global.launch_dict = launch_msg(tmp);
290 launch_data_free(tmp);
291
292 if (global.launch_dict == NULL)
293 {
294 asldebug("%d launchd checkin failed\n", global.pid);
295 exit(1);
296 }
297
298 tmp = launch_data_dict_lookup(global.launch_dict, LAUNCH_JOBKEY_MACHSERVICES);
299 if (tmp == NULL)
300 {
301 asldebug("%d launchd lookup of LAUNCH_JOBKEY_MACHSERVICES failed\n", global.pid);
302 exit(1);
303 }
304
305 pdict = launch_data_dict_lookup(tmp, SERVICE_NAME);
306 if (pdict == NULL)
307 {
308 asldebug("%d launchd lookup of SERVICE_NAME failed\n", global.pid);
309 exit(1);
310 }
311
312 global.server_port = launch_data_get_machport(pdict);
313
314 /* port for receiving MACH_NOTIFY_DEAD_NAME notifications */
315 status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &(global.dead_session_port));
316 if (status != KERN_SUCCESS)
317 {
318 asldebug("mach_port_allocate dead_session_port failed: %d", status);
319 exit(1);
320 }
321
322 status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &(global.listen_set));
323 if (status != KERN_SUCCESS)
324 {
325 asldebug("mach_port_allocate listen_set failed: %d", status);
326 exit(1);
327 }
328
329 status = mach_port_move_member(mach_task_self(), global.server_port, global.listen_set);
330 if (status != KERN_SUCCESS)
331 {
332 asldebug("mach_port_move_member server_port failed: %d", status);
333 exit(1);
334 }
335
336 status = mach_port_move_member(mach_task_self(), global.dead_session_port, global.listen_set);
337 if (status != KERN_SUCCESS)
338 {
339 asldebug("mach_port_move_member dead_session_port failed (%u)", status);
340 exit(1);
341 }
342 }
343
344 void
345 config_debug(int enable, const char *path)
346 {
347 OSSpinLockLock(&global.lock);
348
349 global.debug = enable;
350 free(global.debug_file);
351 global.debug_file = NULL;
352 if (path != NULL) global.debug_file = strdup(path);
353
354 OSSpinLockUnlock(&global.lock);
355 }
356
357 void
358 config_data_store(int type, uint32_t file_max, uint32_t memory_max, uint32_t mini_max)
359 {
360 pthread_mutex_lock(global.db_lock);
361
362 if (global.dbtype & DB_TYPE_FILE)
363 {
364 asl_store_close(global.file_db);
365 global.file_db = NULL;
366 }
367
368 if (global.dbtype & DB_TYPE_MEMORY)
369 {
370 asl_memory_close(global.memory_db);
371 global.memory_db = NULL;
372 }
373
374 if (global.dbtype & DB_TYPE_MINI)
375 {
376 asl_mini_memory_close(global.mini_db);
377 global.mini_db = NULL;
378 }
379
380 global.dbtype = type;
381 global.db_file_max = file_max;
382 global.db_memory_max = memory_max;
383 global.db_mini_max = mini_max;
384
385 pthread_mutex_unlock(global.db_lock);
386 }
387
388 void
389 write_boot_log(int first)
390 {
391 int mib[2] = {CTL_KERN, KERN_BOOTTIME};
392 size_t len;
393 aslmsg msg;
394 char buf[256];
395 struct utmpx utx;
396
397 if (first == 0)
398 {
399 /* syslogd restart */
400 msg = asl_new(ASL_TYPE_MSG);
401 if (msg == NULL) return;
402
403 asl_set(msg, ASL_KEY_SENDER, "syslogd");
404 asl_set(msg, ASL_KEY_FACILITY, "daemon");
405 asl_set(msg, ASL_KEY_LEVEL, "Notice");
406 asl_set(msg, ASL_KEY_UID, "0");
407 asl_set(msg, ASL_KEY_GID, "0");
408 snprintf(buf, sizeof(buf), "%u", global.pid);
409 asl_set(msg, ASL_KEY_PID, buf);
410 asl_set(msg, ASL_KEY_MSG, "--- syslogd restarted ---");
411 process_message(msg, SOURCE_INTERNAL);
412 return;
413 }
414
415 bzero(&utx, sizeof(utx));
416 utx.ut_type = BOOT_TIME;
417 utx.ut_pid = 1;
418
419 /* get the boot time */
420 len = sizeof(struct timeval);
421 if (sysctl(mib, 2, &utx.ut_tv, &len, NULL, 0) < 0)
422 {
423 gettimeofday(&utx.ut_tv, NULL);
424 }
425
426 pututxline(&utx);
427
428 msg = asl_new(ASL_TYPE_MSG);
429 if (msg == NULL) return;
430
431 asl_set(msg, ASL_KEY_SENDER, "bootlog");
432 asl_set(msg, ASL_KEY_FACILITY, "com.apple.system.utmpx");
433 asl_set(msg, ASL_KEY_LEVEL, "Notice");
434 asl_set(msg, ASL_KEY_UID, "0");
435 asl_set(msg, ASL_KEY_GID, "0");
436 asl_set(msg, ASL_KEY_PID, "0");
437 snprintf(buf, sizeof(buf), "BOOT_TIME %lu %u", (unsigned long)utx.ut_tv.tv_sec, (unsigned int)utx.ut_tv.tv_usec);
438 asl_set(msg, ASL_KEY_MSG, buf);
439 asl_set(msg, "ut_id", "0x00 0x00 0x00 0x00");
440 asl_set(msg, "ut_pid", "1");
441 asl_set(msg, "ut_type", "2");
442 snprintf(buf, sizeof(buf), "%lu", (unsigned long)utx.ut_tv.tv_sec);
443 asl_set(msg, ASL_KEY_TIME, buf);
444 asl_set(msg, "ut_tv.tv_sec", buf);
445 snprintf(buf, sizeof(buf), "%u", (unsigned int)utx.ut_tv.tv_usec);
446 asl_set(msg, "ut_tv.tv_usec", buf);
447 snprintf(buf, sizeof(buf), "%u%s", (unsigned int)utx.ut_tv.tv_usec, (utx.ut_tv.tv_usec == 0) ? "" : "000");
448 asl_set(msg, ASL_KEY_TIME_NSEC, buf);
449
450 process_message(msg, SOURCE_INTERNAL);
451 }
452
453 int
454 main(int argc, const char *argv[])
455 {
456 int32_t i;
457 int network_change_token, asl_db_token;
458 char tstr[32];
459 time_t now;
460 int first_syslogd_start = 1;
461
462 #if TARGET_IPHONE_SIMULATOR
463 const char *sim_log_dir = getenv("IPHONE_SIMULATOR_LOG_ROOT");
464 const char *sim_resource_dir = getenv("IPHONE_SHARED_RESOURCES_DIRECTORY");
465 char *p;
466 assert(sim_log_dir && sim_resource_dir);
467
468 asprintf((char **)&_path_syslogd_log, "%s/syslogd.log", sim_log_dir);
469 assert(_path_syslogd_log);
470
471 asprintf((char **)&_path_pidfile, "%s/var/run/syslog.pid", sim_resource_dir);
472 assert(_path_pidfile);
473
474 /* Make sure the directories exists */
475 mkpath_np(sim_log_dir, 0755);
476
477 p = strrchr(_path_pidfile, '/');
478 *p = '\0';
479 mkpath_np(_path_pidfile, 0755);
480 *p = '/';
481
482 extern const char *store_path;
483 store_path = PATH_ASL_STORE;
484 #endif
485
486 /* Set I/O policy */
487 setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_PASSIVE);
488
489 #if !TARGET_OS_IPHONE
490 /* Set Quarantine */
491 qtn_proc_t qp = qtn_proc_alloc();
492 qtn_proc_set_identifier(qp, "com.apple.syslogd");
493 qtn_proc_set_flags(qp, QTN_FLAG_SANDBOX | QTN_FLAG_HARD);
494 qtn_proc_apply_to_self(qp);
495 qtn_proc_free(qp);
496 #endif
497
498 memset(&global, 0, sizeof(struct global_s));
499
500 global.db_lock = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
501 pthread_mutex_init(global.db_lock, NULL);
502
503 /*
504 * Create work queue, but suspend until output modules are initialized.
505 */
506 global.work_queue = dispatch_queue_create("Work Queue", NULL);
507 dispatch_suspend(global.work_queue);
508
509 init_globals();
510
511 #if TARGET_OS_EMBEDDED
512 remote_enabled = 1;
513 activate_bsd_out = 0;
514 #endif
515
516 /* prevent malloc from calling ASL on error */
517 _malloc_no_asl_log = 1;
518
519 /* first pass sets up default configurations */
520 for (i = 1; i < argc; i++)
521 {
522 if (streq(argv[i], "-config"))
523 {
524 if (((i + 1) < argc) && (argv[i+1][0] != '-'))
525 {
526 i++;
527 if (streq(argv[i], "mac"))
528 {
529 global.dbtype = DB_TYPE_FILE;
530 global.db_file_max = 25600000;
531 }
532 else if (streq(argv[i], "appletv"))
533 {
534 global.dbtype = DB_TYPE_FILE;
535 global.db_file_max = 10240000;
536 }
537 else if (streq(argv[i], "iphone"))
538 {
539 #if TARGET_IPHONE_SIMULATOR
540 global.dbtype = DB_TYPE_FILE;
541 global.db_file_max = 25600000;
542 #else
543 global.dbtype = DB_TYPE_MINI;
544 remote_enabled = 1;
545 #endif
546 }
547 }
548 }
549 }
550
551 for (i = 1; i < argc; i++)
552 {
553 if (streq(argv[i], "-d"))
554 {
555 global.debug = 1;
556 if (((i+1) < argc) && (argv[i+1][0] != '-')) global.debug_file = strdup(argv[++i]);
557 }
558 else if (streq(argv[i], "-db"))
559 {
560 if (((i + 1) < argc) && (argv[i+1][0] != '-'))
561 {
562 i++;
563 if (streq(argv[i], "file"))
564 {
565 global.dbtype |= DB_TYPE_FILE;
566 if (((i + 1) < argc) && (argv[i+1][0] != '-')) global.db_file_max = atol(argv[++i]);
567 }
568 else if (streq(argv[i], "memory"))
569 {
570 global.dbtype |= DB_TYPE_MEMORY;
571 if (((i + 1) < argc) && (argv[i+1][0] != '-')) global.db_memory_max = atol(argv[++i]);
572 }
573 else if (streq(argv[i], "mini"))
574 {
575 global.dbtype |= DB_TYPE_MINI;
576 if (((i + 1) < argc) && (argv[i+1][0] != '-')) global.db_mini_max = atol(argv[++i]);
577 }
578 }
579 }
580 else if (streq(argv[i], "-m"))
581 {
582 if ((i + 1) < argc) global.mark_time = 60 * atoll(argv[++i]);
583 }
584 else if (streq(argv[i], "-utmp_ttl"))
585 {
586 if ((i + 1) < argc) global.utmp_ttl = atol(argv[++i]);
587 }
588 else if (streq(argv[i], "-mps_limit"))
589 {
590 if ((i + 1) < argc) global.mps_limit = atol(argv[++i]);
591 }
592 else if (streq(argv[i], "-dup_delay"))
593 {
594 if ((i + 1) < argc) global.bsd_max_dup_time = atoll(argv[++i]);
595 }
596 #if !TARGET_IPHONE_SIMULATOR
597 else if (streq(argv[i], "-klog_in"))
598 {
599 if ((i + 1) < argc) activate_klog_in = atoi(argv[++i]);
600 }
601 else if (streq(argv[i], "-bsd_in"))
602 {
603 if ((i + 1) < argc) activate_bsd_in = atoi(argv[++i]);
604 }
605 else if (streq(argv[i], "-udp_in"))
606 {
607 if ((i + 1) < argc) activate_udp_in = atoi(argv[++i]);
608 }
609 #endif
610 else if (streq(argv[i], "-launchd_in"))
611 {
612 if ((i + 1) < argc) global.launchd_enabled = atoi(argv[++i]);
613 }
614 #if !TARGET_IPHONE_SIMULATOR
615 else if (streq(argv[i], "-bsd_out"))
616 {
617 if ((i + 1) < argc) activate_bsd_out = atoi(argv[++i]);
618 }
619 else if (streq(argv[i], "-remote"))
620 {
621 if ((i + 1) < argc) remote_enabled = atoi(argv[++i]);
622 }
623 #endif
624 }
625
626 if (global.dbtype == 0)
627 {
628 global.dbtype = DB_TYPE_FILE;
629 global.db_file_max = 25600000;
630 }
631
632 signal(SIGHUP, SIG_IGN);
633
634 memset(tstr, 0, sizeof(tstr));
635 now = time(NULL);
636 ctime_r(&now, tstr);
637 tstr[19] = '\0';
638 asldebug("\n%s syslogd PID %d starting\n", tstr, global.pid);
639
640 writepid(&first_syslogd_start);
641
642 /*
643 * Log UTMPX boot time record
644 */
645 write_boot_log(first_syslogd_start);
646
647 asldebug("reading launch plist\n");
648 launch_config();
649
650 asldebug("initializing modules\n");
651 init_modules();
652
653 #if !TARGET_IPHONE_SIMULATOR
654 asldebug("setting up notification handlers\n");
655
656 /* network change notification resets UDP and BSD modules */
657 notify_register_dispatch(kNotifySCNetworkChange, &network_change_token, global.work_queue, ^(int x){
658 if (activate_udp_in != 0) udp_in_reset();
659 if (activate_bsd_out != 0) bsd_out_reset();
660 });
661 #endif
662
663 /* SIGHUP resets all modules */
664 global.sig_hup_src = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, (uintptr_t)SIGHUP, 0, dispatch_get_main_queue());
665 dispatch_source_set_event_handler(global.sig_hup_src, ^{
666 dispatch_async(global.work_queue, ^{
667 int i;
668
669 asldebug("SIGHUP reset\n");
670 for (i = 0; i < global.module_count; i++)
671 {
672 if (global.module[i]->enabled != 0) global.module[i]->reset();
673 }
674 });
675 });
676
677 dispatch_resume(global.sig_hup_src);
678
679 /* register for DB notification (posted by dbserver) for performance */
680 notify_register_plain(kNotifyASLDBUpdate, &asl_db_token);
681
682 /* timer for MARK facility */
683 if (global.mark_time > 0)
684 {
685 global.mark_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
686 dispatch_source_set_event_handler(global.mark_timer, ^{
687 asl_mark();
688 });
689 dispatch_source_set_timer(global.mark_timer, dispatch_time(DISPATCH_TIME_NOW, global.mark_time * NSEC_PER_SEC), global.mark_time * NSEC_PER_SEC, 0);
690 dispatch_resume(global.mark_timer);
691 }
692
693 #if !TARGET_IPHONE_SIMULATOR
694 asldebug("starting launchd input channel\n");
695 /*
696 * Start launchd service
697 * This pins a thread in _vprocmgr_log_drain. Eventually we will either
698 * remove the whole stderr/stdout -> ASL mechanism entirely, or come up
699 * with a communication channel that we can trigger with a dispatch source.
700 */
701 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
702 forever _vprocmgr_log_drain(NULL, NULL, launchd_callback);
703 });
704 #endif
705
706 asldebug("starting mach service\n");
707 /*
708 * Start mach server
709 * Parks a thread in database_server. In notifyd, we found that the overhead of
710 * a dispatch source for mach calls was too high, especially on iOS.
711 */
712 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
713 database_server();
714 });
715
716 /* go to work */
717 asldebug("starting work queue\n");
718 dispatch_resume(global.work_queue);
719 dispatch_main();
720
721 /* NOTREACHED */
722 return 0;
723 }