2 * Copyright (c) 2004-2012 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <TargetConditionals.h>
31 #include <mach/mach.h>
32 #include <mach/mach_error.h>
33 #include <mach/mach_time.h>
34 #include <servers/bootstrap.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/sysctl.h>
39 #include <sys/fcntl.h>
40 #include <sys/errno.h>
41 #include <sys/queue.h>
49 #include <notify_keys.h>
51 #include <vproc_priv.h>
52 #include <asl_private.h>
56 #include <quarantine.h>
60 #define SERVICE_NAME "com.apple.system.logger"
61 #define SERVER_STATUS_ERROR -1
62 #define SERVER_STATUS_INACTIVE 0
63 #define SERVER_STATUS_ACTIVE 1
64 #define SERVER_STATUS_ON_DEMAND 2
66 #define BILLION 1000000000
68 #define NOTIFY_DELAY 1
70 #define forever for(;;)
72 extern int _malloc_no_asl_log
;
74 #if TARGET_IPHONE_SIMULATOR
75 const char *_path_pidfile
;
76 const char *_path_syslogd_log
;
80 struct global_s global
;
82 #if !TARGET_IPHONE_SIMULATOR
84 int klog_in_init(void);
85 int klog_in_reset(void);
86 int klog_in_close(void);
87 static int activate_klog_in
= 1;
90 int bsd_in_init(void);
91 int bsd_in_reset(void);
92 int bsd_in_close(void);
93 static int activate_bsd_in
= 1;
95 #if !TARGET_IPHONE_SIMULATOR
96 int udp_in_init(void);
97 int udp_in_reset(void);
98 int udp_in_close(void);
99 static int activate_udp_in
= 1;
102 int bsd_out_init(void);
103 int bsd_out_reset(void);
104 int bsd_out_close(void);
105 static int activate_bsd_out
= 1;
108 int asl_action_init(void);
109 int asl_action_reset(void);
110 int asl_action_close(void);
111 static int activate_asl_action
= 1;
113 #if !TARGET_IPHONE_SIMULATOR
114 /* Interactive Module */
115 int remote_init(void);
116 int remote_reset(void);
117 int remote_close(void);
118 static int remote_enabled
= 0;
121 extern void database_server();
126 #if !TARGET_IPHONE_SIMULATOR
127 module_t
*m_klog_in
, *m_bsd_out
, *m_udp_in
, *m_remote
;
129 module_t
*m_asl
, *m_bsd_in
;
132 /* ASL module (configured by /etc/asl.conf) */
133 m_asl
= (module_t
*)calloc(1, sizeof(module_t
));
136 asldebug("alloc failed (init_modules asl_action)\n");
140 m_asl
->name
= "asl_action";
141 m_asl
->enabled
= activate_asl_action
;
142 m_asl
->init
= asl_action_init
;
143 m_asl
->reset
= asl_action_reset
;
144 m_asl
->close
= asl_action_close
;
146 if (m_asl
->enabled
) m_asl
->init();
148 #if !TARGET_IPHONE_SIMULATOR
149 /* BSD output module (configured by /etc/syslog.conf) */
150 m_bsd_out
= (module_t
*)calloc(1, sizeof(module_t
));
151 if (m_bsd_out
== NULL
)
153 asldebug("alloc failed (init_modules bsd_out)\n");
157 m_bsd_out
->name
= "bsd_out";
158 m_bsd_out
->enabled
= activate_bsd_out
;
159 m_bsd_out
->init
= bsd_out_init
;
160 m_bsd_out
->reset
= bsd_out_reset
;
161 m_bsd_out
->close
= bsd_out_close
;
163 if (m_bsd_out
->enabled
)
166 global
.bsd_out_enabled
= 1;
169 /* kernel input module */
170 m_klog_in
= (module_t
*)calloc(1, sizeof(module_t
));
171 if (m_klog_in
== NULL
)
173 asldebug("alloc failed (init_modules klog_in)\n");
177 m_klog_in
->name
= "klog_in";
178 m_klog_in
->enabled
= activate_klog_in
;
179 m_klog_in
->init
= klog_in_init
;
180 m_klog_in
->reset
= klog_in_reset
;
181 m_klog_in
->close
= klog_in_close
;
183 if (m_klog_in
->enabled
) m_klog_in
->init();
186 /* BSD (UNIX domain socket) input module */
187 m_bsd_in
= (module_t
*)calloc(1, sizeof(module_t
));
188 if (m_bsd_in
== NULL
)
190 asldebug("alloc failed (init_modules bsd_in)\n");
194 m_bsd_in
->name
= "bsd_in";
195 m_bsd_in
->enabled
= activate_bsd_in
;
196 m_bsd_in
->init
= bsd_in_init
;
197 m_bsd_in
->reset
= bsd_in_reset
;
198 m_bsd_in
->close
= bsd_in_close
;
200 if (m_bsd_in
->enabled
) m_bsd_in
->init();
202 #if !TARGET_IPHONE_SIMULATOR
203 /* network (syslog protocol) input module */
204 m_udp_in
= (module_t
*)calloc(1, sizeof(module_t
));
205 if (m_udp_in
== NULL
)
207 asldebug("alloc failed (init_modules udp_in)\n");
211 m_udp_in
->name
= "udp_in";
212 m_udp_in
->enabled
= activate_udp_in
;
213 m_udp_in
->init
= udp_in_init
;
214 m_udp_in
->reset
= udp_in_reset
;
215 m_udp_in
->close
= udp_in_close
;
217 if (m_udp_in
->enabled
) m_udp_in
->init();
219 /* remote (iOS support) module */
220 m_remote
= (module_t
*)calloc(1, sizeof(module_t
));
221 if (m_remote
== NULL
)
223 asldebug("alloc failed (init_modules remote)\n");
227 m_remote
->name
= "remote";
228 m_remote
->enabled
= remote_enabled
;
229 m_remote
->init
= remote_init
;
230 m_remote
->reset
= remote_reset
;
231 m_remote
->close
= remote_close
;
233 if (m_remote
->enabled
) m_remote
->init();
234 #endif /* TARGET_IPHONE_SIMULATOR */
236 /* save modules in global.module array */
237 #if TARGET_IPHONE_SIMULATOR
238 global
.module_count
= 2;
240 global
.module_count
= 6;
242 global
.module = (module_t
**)calloc(global
.module_count
, sizeof(module_t
*));
243 if (global
.module == NULL
)
245 asldebug("alloc failed (init_modules)\n");
249 global
.module[m
++] = m_asl
;
250 global
.module[m
++] = m_bsd_in
;
251 #if !TARGET_IPHONE_SIMULATOR
252 global
.module[m
++] = m_bsd_out
;
253 global
.module[m
++] = m_klog_in
;
254 global
.module[m
++] = m_udp_in
;
255 global
.module[m
++] = m_remote
;
268 memset(&sb
, 0, sizeof(struct stat
));
269 if (stat(_PATH_PIDFILE
, &sb
) == 0)
271 if (S_ISREG(sb
.st_mode
)) *first
= 0;
275 fp
= fopen(_PATH_PIDFILE
, "w");
278 fprintf(fp
, "%d\n", global
.pid
);
286 launch_data_t tmp
, pdict
;
287 kern_return_t status
;
289 tmp
= launch_data_new_string(LAUNCH_KEY_CHECKIN
);
290 global
.launch_dict
= launch_msg(tmp
);
291 launch_data_free(tmp
);
293 if (global
.launch_dict
== NULL
)
295 asldebug("%d launchd checkin failed\n", global
.pid
);
299 tmp
= launch_data_dict_lookup(global
.launch_dict
, LAUNCH_JOBKEY_MACHSERVICES
);
302 asldebug("%d launchd lookup of LAUNCH_JOBKEY_MACHSERVICES failed\n", global
.pid
);
306 pdict
= launch_data_dict_lookup(tmp
, SERVICE_NAME
);
309 asldebug("%d launchd lookup of SERVICE_NAME failed\n", global
.pid
);
313 global
.server_port
= launch_data_get_machport(pdict
);
315 /* port for receiving MACH_NOTIFY_DEAD_NAME notifications */
316 status
= mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE
, &(global
.dead_session_port
));
317 if (status
!= KERN_SUCCESS
)
319 asldebug("mach_port_allocate dead_session_port failed: %d", status
);
323 status
= mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET
, &(global
.listen_set
));
324 if (status
!= KERN_SUCCESS
)
326 asldebug("mach_port_allocate listen_set failed: %d", status
);
330 status
= mach_port_move_member(mach_task_self(), global
.server_port
, global
.listen_set
);
331 if (status
!= KERN_SUCCESS
)
333 asldebug("mach_port_move_member server_port failed: %d", status
);
337 status
= mach_port_move_member(mach_task_self(), global
.dead_session_port
, global
.listen_set
);
338 if (status
!= KERN_SUCCESS
)
340 asldebug("mach_port_move_member dead_session_port failed (%u)", status
);
346 config_debug(int enable
, const char *path
)
348 OSSpinLockLock(&global
.lock
);
350 global
.debug
= enable
;
351 free(global
.debug_file
);
352 global
.debug_file
= NULL
;
353 if (path
!= NULL
) global
.debug_file
= strdup(path
);
355 OSSpinLockUnlock(&global
.lock
);
359 config_data_store(int type
, uint32_t file_max
, uint32_t memory_max
, uint32_t str_memory_max
)
361 pthread_mutex_lock(global
.db_lock
);
363 if (global
.dbtype
& DB_TYPE_FILE
)
365 asl_store_close(global
.file_db
);
366 global
.file_db
= NULL
;
369 if (global
.dbtype
& DB_TYPE_MEMORY
)
371 asl_memory_close(global
.memory_db
);
372 global
.memory_db
= NULL
;
375 global
.dbtype
= type
;
376 global
.db_file_max
= file_max
;
377 global
.db_memory_max
= memory_max
;
378 global
.db_memory_str_max
= str_memory_max
;
380 pthread_mutex_unlock(global
.db_lock
);
384 write_boot_log(int first
)
386 int mib
[2] = {CTL_KERN
, KERN_BOOTTIME
};
394 /* syslogd restart */
395 msg
= asl_msg_new(ASL_TYPE_MSG
);
396 if (msg
== NULL
) return;
398 asl_msg_set_key_val(msg
, ASL_KEY_SENDER
, "syslogd");
399 asl_msg_set_key_val(msg
, ASL_KEY_FACILITY
, "daemon");
400 asl_msg_set_key_val(msg
, ASL_KEY_LEVEL
, "Notice");
401 asl_msg_set_key_val(msg
, ASL_KEY_UID
, "0");
402 asl_msg_set_key_val(msg
, ASL_KEY_GID
, "0");
403 snprintf(buf
, sizeof(buf
), "%u", global
.pid
);
404 asl_msg_set_key_val(msg
, ASL_KEY_PID
, buf
);
405 asl_msg_set_key_val(msg
, ASL_KEY_MSG
, "--- syslogd restarted ---");
406 process_message(msg
, SOURCE_INTERNAL
);
410 bzero(&utx
, sizeof(utx
));
411 utx
.ut_type
= BOOT_TIME
;
414 /* get the boot time */
415 len
= sizeof(struct timeval
);
416 if (sysctl(mib
, 2, &utx
.ut_tv
, &len
, NULL
, 0) < 0)
418 gettimeofday(&utx
.ut_tv
, NULL
);
423 msg
= asl_msg_new(ASL_TYPE_MSG
);
424 if (msg
== NULL
) return;
426 asl_msg_set_key_val(msg
, ASL_KEY_SENDER
, "bootlog");
427 asl_msg_set_key_val(msg
, ASL_KEY_FACILITY
, "com.apple.system.utmpx");
428 asl_msg_set_key_val(msg
, ASL_KEY_LEVEL
, "Notice");
429 asl_msg_set_key_val(msg
, ASL_KEY_UID
, "0");
430 asl_msg_set_key_val(msg
, ASL_KEY_GID
, "0");
431 asl_msg_set_key_val(msg
, ASL_KEY_PID
, "0");
432 snprintf(buf
, sizeof(buf
), "BOOT_TIME %lu %u", (unsigned long)utx
.ut_tv
.tv_sec
, (unsigned int)utx
.ut_tv
.tv_usec
);
433 asl_msg_set_key_val(msg
, ASL_KEY_MSG
, buf
);
434 asl_msg_set_key_val(msg
, "ut_id", "0x00 0x00 0x00 0x00");
435 asl_msg_set_key_val(msg
, "ut_pid", "1");
436 asl_msg_set_key_val(msg
, "ut_type", "2");
437 snprintf(buf
, sizeof(buf
), "%lu", (unsigned long)utx
.ut_tv
.tv_sec
);
438 asl_msg_set_key_val(msg
, ASL_KEY_TIME
, buf
);
439 asl_msg_set_key_val(msg
, "ut_tv.tv_sec", buf
);
440 snprintf(buf
, sizeof(buf
), "%u", (unsigned int)utx
.ut_tv
.tv_usec
);
441 asl_msg_set_key_val(msg
, "ut_tv.tv_usec", buf
);
442 snprintf(buf
, sizeof(buf
), "%u%s", (unsigned int)utx
.ut_tv
.tv_usec
, (utx
.ut_tv
.tv_usec
== 0) ? "" : "000");
443 asl_msg_set_key_val(msg
, ASL_KEY_TIME_NSEC
, buf
);
445 process_message(msg
, SOURCE_INTERNAL
);
449 main(int argc
, const char *argv
[])
453 #if !TARGET_IPHONE_SIMULATOR
454 int network_change_token
;
456 int quota_file_token
, asl_db_token
, master_token
;
457 char tstr
[32], *notify_key
;
459 int first_syslogd_start
= 1;
461 #if TARGET_IPHONE_SIMULATOR
462 const char *sim_log_dir
= getenv("SIMULATOR_LOG_ROOT");
463 const char *sim_resource_dir
= getenv("SIMULATOR_SHARED_RESOURCES_DIRECTORY");
467 assert(sim_log_dir
&& sim_resource_dir
);
469 asprintf((char **)&_path_syslogd_log
, "%s/syslogd.log", sim_log_dir
);
470 asprintf((char **)&_path_pidfile
, "%s/var/run/syslog.pid", sim_resource_dir
);
472 if (_path_syslogd_log
== NULL
) _path_syslogd_log
= "/tmp/syslogd.log";
473 else mkpath_np(sim_log_dir
, 0755);
475 if (_path_pidfile
== NULL
)
477 _path_pidfile
= "/tmp/syslog.pid";
481 p
= strrchr(_path_pidfile
, '/');
483 mkpath_np(_path_pidfile
, 0755);
490 * Reset owner, group, and permissions in /var/mobile/Library/Logs
491 * in case something created them incorrectly. syslogd was
492 * guilty of this in the past, creating them with owner root.
495 uid_t __mUserUID
= 501;
496 gid_t __mUserGID
= 501;
497 struct passwd
* pw
= getpwnam("mobile");
500 __mUserUID
= pw
->pw_uid
;
501 __mUserGID
= pw
->pw_gid
;
504 asl_secure_chown_chmod_dir("/private/var/mobile/Library/Logs", __mUserUID
, __mUserGID
, 0755);
505 asl_secure_chown_chmod_dir("/private/var/mobile/Library/Logs/CrashReporter", __mUserUID
, __mUserGID
, 0755);
506 asl_secure_chown_chmod_dir("/private/var/mobile/Library/Logs/CrashReporter/DiagnosticLogs", __mUserUID
, __mUserGID
, 0755);
510 setiopolicy_np(IOPOL_TYPE_DISK
, IOPOL_SCOPE_PROCESS
, IOPOL_PASSIVE
);
512 #if !TARGET_OS_IPHONE
514 qtn_proc_t qp
= qtn_proc_alloc();
515 qtn_proc_set_identifier(qp
, "com.apple.syslogd");
516 qtn_proc_set_flags(qp
, QTN_FLAG_SANDBOX
| QTN_FLAG_HARD
);
517 qtn_proc_apply_to_self(qp
);
521 memset(&global
, 0, sizeof(struct global_s
));
523 global
.db_lock
= (pthread_mutex_t
*)calloc(1, sizeof(pthread_mutex_t
));
524 pthread_mutex_init(global
.db_lock
, NULL
);
527 * Create work queue, but suspend until output modules are initialized.
529 global
.work_queue
= dispatch_queue_create("Work Queue", NULL
);
530 dispatch_suspend(global
.work_queue
);
534 #if TARGET_OS_EMBEDDED
536 activate_bsd_out
= 0;
539 /* prevent malloc from calling ASL on error */
540 _malloc_no_asl_log
= 1;
542 /* first pass sets up default configurations */
543 for (i
= 1; i
< argc
; i
++)
545 if (streq(argv
[i
], "-config"))
547 if (((i
+ 1) < argc
) && (argv
[i
+1][0] != '-'))
550 if (streq(argv
[i
], "mac"))
552 global
.dbtype
= DB_TYPE_FILE
;
553 global
.db_file_max
= 25600000;
555 else if (streq(argv
[i
], "appletv"))
557 global
.dbtype
= DB_TYPE_FILE
;
558 global
.db_file_max
= 10240000;
560 else if (streq(argv
[i
], "iphone"))
562 #if TARGET_IPHONE_SIMULATOR
563 global
.dbtype
= DB_TYPE_FILE
;
564 global
.db_file_max
= 25600000;
566 global
.dbtype
= DB_TYPE_MEMORY
;
574 for (i
= 1; i
< argc
; i
++)
576 if (streq(argv
[i
], "-d"))
579 if (((i
+1) < argc
) && (argv
[i
+1][0] != '-')) global
.debug_file
= strdup(argv
[++i
]);
581 else if (streq(argv
[i
], "-db"))
583 if (((i
+ 1) < argc
) && (argv
[i
+1][0] != '-'))
586 if (streq(argv
[i
], "file"))
588 global
.dbtype
|= DB_TYPE_FILE
;
589 if (((i
+ 1) < argc
) && (argv
[i
+1][0] != '-')) global
.db_file_max
= atol(argv
[++i
]);
591 else if (streq(argv
[i
], "memory"))
593 global
.dbtype
|= DB_TYPE_MEMORY
;
594 if (((i
+ 1) < argc
) && (argv
[i
+1][0] != '-')) global
.db_memory_max
= atol(argv
[++i
]);
598 else if (streq(argv
[i
], "-m"))
600 if ((i
+ 1) < argc
) global
.mark_time
= 60 * atoll(argv
[++i
]);
602 else if (streq(argv
[i
], "-utmp_ttl"))
604 if ((i
+ 1) < argc
) global
.utmp_ttl
= atol(argv
[++i
]);
606 else if (streq(argv
[i
], "-mps_limit"))
608 if ((i
+ 1) < argc
) global
.mps_limit
= atol(argv
[++i
]);
610 else if (streq(argv
[i
], "-dup_delay"))
612 if ((i
+ 1) < argc
) global
.bsd_max_dup_time
= atoll(argv
[++i
]);
614 #if !TARGET_IPHONE_SIMULATOR
615 else if (streq(argv
[i
], "-klog_in"))
617 if ((i
+ 1) < argc
) activate_klog_in
= atoi(argv
[++i
]);
619 else if (streq(argv
[i
], "-bsd_in"))
621 if ((i
+ 1) < argc
) activate_bsd_in
= atoi(argv
[++i
]);
623 else if (streq(argv
[i
], "-udp_in"))
625 if ((i
+ 1) < argc
) activate_udp_in
= atoi(argv
[++i
]);
628 else if (streq(argv
[i
], "-launchd_in"))
630 if ((i
+ 1) < argc
) global
.launchd_enabled
= atoi(argv
[++i
]);
632 #if !TARGET_IPHONE_SIMULATOR
633 else if (streq(argv
[i
], "-bsd_out"))
635 if ((i
+ 1) < argc
) activate_bsd_out
= atoi(argv
[++i
]);
637 else if (streq(argv
[i
], "-remote"))
639 if ((i
+ 1) < argc
) remote_enabled
= atoi(argv
[++i
]);
644 if (global
.dbtype
== 0)
646 global
.dbtype
= DB_TYPE_FILE
;
647 global
.db_file_max
= 25600000;
650 signal(SIGHUP
, SIG_IGN
);
652 memset(tstr
, 0, sizeof(tstr
));
656 asldebug("\n%s syslogd PID %d starting\n", tstr
, global
.pid
);
658 writepid(&first_syslogd_start
);
661 * Log UTMPX boot time record
663 write_boot_log(first_syslogd_start
);
665 /* default NOTIFY_SYSTEM_MASTER settings */
667 notify_register_plain(NOTIFY_SYSTEM_MASTER
, &master_token
);
668 notify_set_state(master_token
, master_val
);
670 asldebug("reading launch plist\n");
673 asldebug("initializing modules\n");
676 #if !TARGET_IPHONE_SIMULATOR
677 asldebug("setting up network change notification handler\n");
679 /* network change notification resets UDP and BSD modules */
680 notify_register_dispatch(kNotifySCNetworkChange
, &network_change_token
, global
.work_queue
, ^(int x
){
681 if (activate_udp_in
!= 0) udp_in_reset();
682 if (activate_bsd_out
!= 0) bsd_out_reset();
686 asldebug("setting up quota notification handler\n");
689 asprintf(¬ify_key
, "%s%s", NOTIFY_PATH_SERVICE
, NOQUOTA_FILE_PATH
);
690 if (notify_key
!= NULL
)
694 status
= notify_register_dispatch(notify_key
, "a_file_token
, dispatch_get_main_queue(), ^(int t
){
696 memset(&sb
, 0, sizeof(sb
));
697 if (stat(NOQUOTA_FILE_PATH
, &sb
) == 0)
700 asprintf(&str
, "[Sender syslogd] [Level 2] [PID %u] [Facility syslog] [Message *** MESSAGE QUOTAS DISABLED FOR ALL PROCESSES ***]", global
.pid
);
701 internal_log_message(str
);
707 asprintf(&str
, "[Sender syslogd] [Level 2] [PID %u] [Facility syslog] [Message *** MESSAGE QUOTAS ENABLED ***]", global
.pid
);
708 internal_log_message(str
);
716 /* SIGHUP resets all modules */
717 global
.sig_hup_src
= dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL
, (uintptr_t)SIGHUP
, 0, dispatch_get_main_queue());
718 dispatch_source_set_event_handler(global
.sig_hup_src
, ^{
719 dispatch_async(global
.work_queue
, ^{
722 asldebug("SIGHUP reset\n");
723 for (i
= 0; i
< global
.module_count
; i
++)
725 if (global
.module[i
]->enabled
!= 0) global
.module[i
]->reset();
730 dispatch_resume(global
.sig_hup_src
);
732 /* register for DB notification (posted by dbserver) for performance */
733 notify_register_plain(kNotifyASLDBUpdate
, &asl_db_token
);
735 /* timer for MARK facility */
736 if (global
.mark_time
> 0)
738 global
.mark_timer
= dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER
, 0, 0, dispatch_get_main_queue());
739 dispatch_source_set_event_handler(global
.mark_timer
, ^{
742 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);
743 dispatch_resume(global
.mark_timer
);
746 #if !TARGET_IPHONE_SIMULATOR
747 asldebug("starting launchd input channel\n");
749 * Start launchd service
750 * This pins a thread in _vprocmgr_log_drain. Eventually we will either
751 * remove the whole stderr/stdout -> ASL mechanism entirely, or come up
752 * with a communication channel that we can trigger with a dispatch source.
754 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0), ^{
755 forever
_vprocmgr_log_drain(NULL
, NULL
, launchd_callback
);
759 asldebug("starting mach service\n");
762 * Parks a thread in database_server. In notifyd, we found that the overhead of
763 * a dispatch source for mach calls was too high, especially on iOS.
765 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0), ^{
770 asldebug("starting work queue\n");
771 dispatch_resume(global
.work_queue
);