void runtime·initsig(int32 queue) { static Sigaction sa; runtime·siginit(); int32 i; sa.sa_flags |= SA_ONSTACK | SA_SIGINFO; sa.sa_mask = ~0x0ull; for(i = 0; i < NSIG; i++) { if(runtime·sigtab[i].flags) { if((runtime·sigtab[i].flags & SigQueue) != queue) continue; if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) sa.__sigaction_u.__sa_sigaction = (void*) runtime·sigtramp; else sa.__sigaction_u.__sa_sigaction = (void*) runtime·sigignore; if(runtime·sigtab[i].flags & SigRestart) sa.sa_flags |= SA_RESTART; else sa.sa_flags &= ~SA_RESTART; runtime·sigaction(i, &sa, nil); } } }
void initsig(void) { int32 i; static Sigaction sa; siginit(); sa.sa_flags |= SA_SIGINFO|SA_ONSTACK; sa.sa_mask = 0xFFFFFFFFU; sa.sa_tramp = sigtramp; // sigtramp's job is to call into real handler for(i = 0; i<NSIG; i++) { if(sigtab[i].flags) { if(sigtab[i].flags & (SigCatch | SigQueue)) { sa.__sigaction_u.__sa_sigaction = sighandler; } else { sa.__sigaction_u.__sa_sigaction = sigignore; } if(sigtab[i].flags & SigRestart) sa.sa_flags |= SA_RESTART; else sa.sa_flags &= ~SA_RESTART; sigaction(i, &sa, nil); } } }
void runtime·initsig(int32 queue) { static Sigaction sa; runtime·siginit(); int32 i; sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; sa.sa_mask = 0xFFFFFFFFFFFFFFFFULL; sa.sa_restorer = (void*)runtime·sigreturn; for(i = 0; i<NSIG; i++) { if(runtime·sigtab[i].flags) { if((runtime·sigtab[i].flags & SigQueue) != queue) continue; if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) sa.sa_handler = (void*)runtime·sigtramp; else sa.sa_handler = (void*)runtime·sigignore; if(runtime·sigtab[i].flags & SigRestart) sa.sa_flags |= SA_RESTART; else sa.sa_flags &= ~SA_RESTART; runtime·rt_sigaction(i, &sa, nil, 8); } } }
SIGCASTF usignal::signal(int signo, SIGCASTF func) { struct sigaction act, oact; if (!intercept_set) siginit(); if (immediate){ act.sa_handler = func; act.sa_flags = 0; ::sigemptyset(&act.sa_mask); ::sigaction(signo, &act, &oact); return (SIGCASTF)oact.sa_handler; } switch (signo){ case SIGHUP: case SIGINT: case SIGQUIT: case SIGALRM: case SIGTERM: case SIGUSR1: case SIGUSR2: break; default: act.sa_handler = func; act.sa_flags = 0; ::sigemptyset(&act.sa_mask); ::sigaction(signo, &act, &oact); return (SIGCASTF)oact.sa_handler; } oact.sa_handler = (SIGCASTF)sigs[signo].func; sigs[signo].func = (SIGCASTF)func; if (func == (SIGCASTF)SIG_IGN) { // if signal is to be ignored, pass it thru immediately act.sa_handler = (SIGCASTF)SIG_IGN; act.sa_flags = (signo == SIGCHLD) ? SA_NOCLDWAIT : 0; ::sigemptyset(&act.sa_mask); ::sigaction(signo, &act, NULL); sigs[signo].num_sigs = 0; } else { // if signal had been ignored, now intercept it if (oact.sa_handler == (SIGCASTF)SIG_IGN){ act.sa_handler = (SIGCASTF)intercept; act.sa_flags = 0; ::sigemptyset(&act.sa_mask); ::sigaction(signo, &act, NULL); } } return (SIGCASTF)oact.sa_handler; }
static void run_worker(const pid_t parent) { struct mog_queue *q = mog_queue_new(); mog_notify_init(); siginit(worker_wakeup_handler); mog_thrpool_start(&q->thrpool, nthr, mog_queue_loop, q); have_mgmt = false; mog_svc_each(svc_start_each, q); /* this will set have_mgmt */ if (have_mgmt) { iostat_running = mog_iostat_respawn(0); if (!iostat_running) syslog(LOG_WARNING, "iostat(1) not available/running"); } main_worker_loop(parent); }
void runtime·initsig(int32 queue) { int32 i; void *fn; runtime·siginit(); for(i = 0; i<NSIG; i++) { if(runtime·sigtab[i].flags) { if((runtime·sigtab[i].flags & SigQueue) != queue) continue; if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) fn = runtime·sighandler; else fn = runtime·sigignore; sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0); } } }
static void run_master(void) { unsigned id; size_t running = worker_processes; master_selfwake = mog_selfwake_new(); siginit(master_wakeup_handler); for (id = 0; id < worker_processes; id++) fork_worker(id); while (running > 0) { mog_selfwake_wait(master_selfwake); if (sigchld_hit) sigchld_handler(); if (do_upgrade) upgrade_handler(); if (do_exit) running = mog_kill_each_worker(SIGQUIT); } }
void __initsig () { struct sigaction sa; int i; siginit (); memset (&sa, 0, sizeof sa); sa.sa_handler = sighandler; i = sigfillset (&sa.sa_mask); __go_assert (i == 0); for (i = 0; signals[i].sig != -1; ++i) { sa.sa_flags = signals[i].restart ? SA_RESTART : 0; if (sigaction (signals[i].sig, &sa, NULL) != 0) __go_assert (0); } }
int client_main(struct client_ctx *cctx) { struct pollfd pfd; char *error; int xtimeout; /* Yay for ncurses namespace! */ siginit(); logfile("client"); error = NULL; while (!sigterm) { if (sigchld) { waitpid(WAIT_ANY, NULL, WNOHANG); sigchld = 0; } if (sigwinch) client_handle_winch(cctx); if (sigcont) { siginit(); client_write_server(cctx, MSG_WAKEUP, NULL, 0); sigcont = 0; } switch (client_msg_dispatch(cctx, &error)) { case -1: goto out; case 0: /* May be more in buffer, don't let poll block. */ xtimeout = 0; break; default: /* Out of data, poll may block. */ xtimeout = INFTIM; break; } pfd.fd = cctx->srv_fd; pfd.events = POLLIN; if (BUFFER_USED(cctx->srv_out) > 0) pfd.events |= POLLOUT; if (poll(&pfd, 1, xtimeout) == -1) { if (errno == EAGAIN || errno == EINTR) continue; fatal("poll failed"); } if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0) goto server_dead; } out: if (sigterm) { printf("[terminated]\n"); return (1); } if (cctx->flags & CCTX_SHUTDOWN) { printf("[server exited]\n"); return (0); } if (cctx->flags & CCTX_EXIT) { printf("[exited]\n"); return (0); } if (cctx->flags & CCTX_DETACH) { printf("[detached]\n"); return (0); } printf("[error: %s]\n", error); return (1); server_dead: printf("[lost server]\n"); return (0); }
int main(int argc, char **argv) { struct client_ctx cctx; struct msg_command_data cmddata; struct buffer *b; struct cmd_list *cmdlist; struct cmd *cmd; struct pollfd pfd; struct hdr hdr; const char *shell; struct passwd *pw; char *path, *label, *cause, *home, *pass = NULL; char cwd[MAXPATHLEN]; int retcode, opt, flags, unlock, start_server; unlock = flags = 0; label = path = NULL; while ((opt = getopt(argc, argv, "28df:L:qS:uUVv")) != -1) { switch (opt) { case '2': flags |= IDENTIFY_256COLOURS; flags &= ~IDENTIFY_88COLOURS; break; case '8': flags |= IDENTIFY_88COLOURS; flags &= ~IDENTIFY_256COLOURS; break; case 'f': cfg_file = xstrdup(optarg); break; case 'L': if (path != NULL) { log_warnx("-L and -S cannot be used together"); exit(1); } if (label != NULL) xfree(label); label = xstrdup(optarg); break; case 'S': if (label != NULL) { log_warnx("-L and -S cannot be used together"); exit(1); } if (path != NULL) xfree(path); path = xstrdup(optarg); break; case 'q': be_quiet = 1; break; case 'u': flags |= IDENTIFY_UTF8; break; case 'U': unlock = 1; break; case 'd': flags |= IDENTIFY_HASDEFAULTS; break; case 'v': debug_level++; break; case 'V': printf("%s " BUILD "\n", __progname); exit(0); default: usage(); } } argc -= optind; argv += optind; log_open_tty(debug_level); siginit(); options_init(&global_options, NULL); options_set_number(&global_options, "bell-action", BELL_ANY); options_set_number(&global_options, "buffer-limit", 9); options_set_number(&global_options, "display-time", 750); options_set_number(&global_options, "history-limit", 2000); options_set_number(&global_options, "message-bg", 3); options_set_number(&global_options, "message-fg", 0); options_set_number(&global_options, "message-attr", GRID_ATTR_REVERSE); options_set_number(&global_options, "prefix", META); options_set_number(&global_options, "repeat-time", 500); options_set_number(&global_options, "set-titles", 1); options_set_number(&global_options, "lock-after-time", 0); options_set_number(&global_options, "set-remain-on-exit", 0); options_set_number(&global_options, "status", 1); options_set_number(&global_options, "status-bg", 2); options_set_number(&global_options, "status-fg", 0); options_set_number(&global_options, "status-attr", GRID_ATTR_REVERSE); options_set_number(&global_options, "status-interval", 15); options_set_number(&global_options, "status-left-length", 10); options_set_number(&global_options, "status-right-length", 40); options_set_string(&global_options, "status-left", "[#S]"); options_set_string( &global_options, "status-right", "\"#24T\" %%H:%%M %%d-%%b-%%y"); options_set_number(&global_options, "status-keys", MODEKEY_EMACS); options_init(&global_window_options, NULL); options_set_number(&global_window_options, "aggressive-resize", 0); options_set_number(&global_window_options, "clock-mode-colour", 4); options_set_number(&global_window_options, "clock-mode-style", 1); options_set_number(&global_window_options, "force-height", 0); options_set_number(&global_window_options, "force-width", 0); options_set_number(&global_window_options, "automatic-rename", 1); options_set_number(&global_window_options, "mode-bg", 3); options_set_number(&global_window_options, "mode-fg", 0); options_set_number( &global_window_options, "mode-attr", GRID_ATTR_REVERSE); options_set_number(&global_window_options, "mode-keys", MODEKEY_EMACS); options_set_number(&global_window_options, "monitor-activity", 0); options_set_number(&global_window_options, "utf8", 0); options_set_number(&global_window_options, "xterm-keys", 0); options_set_number(&global_window_options, "remain-on-exit", 0); options_set_number(&global_window_options, "window-status-bg", 8); options_set_number(&global_window_options, "window-status-fg", 8); options_set_number(&global_window_options, "window-status-attr", 0); if (cfg_file == NULL) { home = getenv("HOME"); if (home == NULL || *home == '\0') { pw = getpwuid(getuid()); if (pw != NULL) home = pw->pw_dir; endpwent(); } xasprintf(&cfg_file, "%s/%s", home, DEFAULT_CFG); if (access(cfg_file, R_OK) != 0) { xfree(cfg_file); cfg_file = NULL; } } else { if (access(cfg_file, R_OK) != 0) { log_warn("%s", cfg_file); exit(1); } } if (label == NULL) label = xstrdup("default"); if (path == NULL && (path = makesockpath(label)) == NULL) { log_warn("can't create socket"); exit(1); } xfree(label); shell = getenv("SHELL"); if (shell == NULL || *shell == '\0') { pw = getpwuid(getuid()); if (pw != NULL) shell = pw->pw_shell; endpwent(); if (shell == NULL || *shell == '\0') shell = _PATH_BSHELL; } options_set_string( &global_options, "default-command", "exec %s", shell); if (getcwd(cwd, sizeof cwd) == NULL) { log_warn("getcwd"); exit(1); } options_set_string(&global_options, "default-path", "%s", cwd); if (unlock) { if (argc != 0) { log_warnx("can't specify a command when unlocking"); exit(1); } cmdlist = NULL; if ((pass = getpass("Password: "******"%s", cause); exit(1); } } start_server = 0; TAILQ_FOREACH(cmd, cmdlist, qentry) { if (cmd->entry->flags & CMD_STARTSERVER) { start_server = 1; break; } } } memset(&cctx, 0, sizeof cctx); if (client_init(path, &cctx, start_server, flags) != 0) exit(1); xfree(path); b = buffer_create(BUFSIZ); if (unlock) { cmd_send_string(b, pass); client_write_server( &cctx, MSG_UNLOCK, BUFFER_OUT(b), BUFFER_USED(b)); } else { cmd_list_send(cmdlist, b); cmd_list_free(cmdlist); client_fill_session(&cmddata); client_write_server2(&cctx, MSG_COMMAND, &cmddata, sizeof cmddata, BUFFER_OUT(b), BUFFER_USED(b)); } buffer_destroy(b); retcode = 0; for (;;) { pfd.fd = cctx.srv_fd; pfd.events = POLLIN; if (BUFFER_USED(cctx.srv_out) > 0) pfd.events |= POLLOUT; if (poll(&pfd, 1, INFTIM) == -1) { if (errno == EAGAIN || errno == EINTR) continue; fatal("poll failed"); } if (buffer_poll(&pfd, cctx.srv_in, cctx.srv_out) != 0) goto out; restart: if (BUFFER_USED(cctx.srv_in) < sizeof hdr) continue; memcpy(&hdr, BUFFER_OUT(cctx.srv_in), sizeof hdr); if (BUFFER_USED(cctx.srv_in) < (sizeof hdr) + hdr.size) continue; buffer_remove(cctx.srv_in, sizeof hdr); switch (hdr.type) { case MSG_EXIT: case MSG_SHUTDOWN: goto out; case MSG_ERROR: retcode = 1; /* FALLTHROUGH */ case MSG_PRINT: if (hdr.size > INT_MAX - 1) fatalx("bad MSG_PRINT size"); log_info("%.*s", (int) hdr.size, BUFFER_OUT(cctx.srv_in)); if (hdr.size != 0) buffer_remove(cctx.srv_in, hdr.size); goto restart; case MSG_READY: retcode = client_main(&cctx); goto out; default: fatalx("unexpected command"); } } out: options_free(&global_options); options_free(&global_window_options); close(cctx.srv_fd); buffer_destroy(cctx.srv_in); buffer_destroy(cctx.srv_out); #ifdef DEBUG xmalloc_report(getpid(), "client"); #endif return (retcode); }
void bsd_init(void) { struct uthread *ut; unsigned int i; struct vfs_context context; kern_return_t ret; struct ucred temp_cred; struct posix_cred temp_pcred; #if NFSCLIENT || CONFIG_IMAGEBOOT boolean_t netboot = FALSE; #endif #define bsd_init_kprintf(x...) /* kprintf("bsd_init: " x) */ throttle_init(); printf(copyright); bsd_init_kprintf("calling kmeminit\n"); kmeminit(); bsd_init_kprintf("calling parse_bsd_args\n"); parse_bsd_args(); #if CONFIG_DEV_KMEM bsd_init_kprintf("calling dev_kmem_init\n"); dev_kmem_init(); #endif /* Initialize kauth subsystem before instancing the first credential */ bsd_init_kprintf("calling kauth_init\n"); kauth_init(); /* Initialize process and pgrp structures. */ bsd_init_kprintf("calling procinit\n"); procinit(); /* Initialize the ttys (MUST be before kminit()/bsd_autoconf()!)*/ tty_init(); kernproc = &proc0; /* implicitly bzero'ed */ /* kernel_task->proc = kernproc; */ set_bsdtask_info(kernel_task,(void *)kernproc); /* give kernproc a name */ bsd_init_kprintf("calling process_name\n"); process_name("kernel_task", kernproc); /* allocate proc lock group attribute and group */ bsd_init_kprintf("calling lck_grp_attr_alloc_init\n"); proc_lck_grp_attr= lck_grp_attr_alloc_init(); proc_lck_grp = lck_grp_alloc_init("proc", proc_lck_grp_attr); #if CONFIG_FINE_LOCK_GROUPS proc_slock_grp = lck_grp_alloc_init("proc-slock", proc_lck_grp_attr); proc_fdmlock_grp = lck_grp_alloc_init("proc-fdmlock", proc_lck_grp_attr); proc_ucred_mlock_grp = lck_grp_alloc_init("proc-ucred-mlock", proc_lck_grp_attr); proc_mlock_grp = lck_grp_alloc_init("proc-mlock", proc_lck_grp_attr); #endif /* Allocate proc lock attribute */ proc_lck_attr = lck_attr_alloc_init(); #if 0 #if __PROC_INTERNAL_DEBUG lck_attr_setdebug(proc_lck_attr); #endif #endif #if CONFIG_FINE_LOCK_GROUPS proc_list_mlock = lck_mtx_alloc_init(proc_mlock_grp, proc_lck_attr); proc_klist_mlock = lck_mtx_alloc_init(proc_mlock_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_mlock, proc_mlock_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_fdmlock, proc_fdmlock_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_ucred_mlock, proc_ucred_mlock_grp, proc_lck_attr); lck_spin_init(&kernproc->p_slock, proc_slock_grp, proc_lck_attr); #else proc_list_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); proc_klist_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_mlock, proc_lck_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_fdmlock, proc_lck_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_ucred_mlock, proc_lck_grp, proc_lck_attr); lck_spin_init(&kernproc->p_slock, proc_lck_grp, proc_lck_attr); #endif assert(bsd_simul_execs != 0); execargs_cache_lock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); execargs_cache_size = bsd_simul_execs; execargs_free_count = bsd_simul_execs; execargs_cache = (vm_offset_t *)kalloc(bsd_simul_execs * sizeof(vm_offset_t)); bzero(execargs_cache, bsd_simul_execs * sizeof(vm_offset_t)); if (current_task() != kernel_task) printf("bsd_init: We have a problem, " "current task is not kernel task\n"); bsd_init_kprintf("calling get_bsdthread_info\n"); ut = (uthread_t)get_bsdthread_info(current_thread()); #if CONFIG_MACF /* * Initialize the MAC Framework */ mac_policy_initbsd(); kernproc->p_mac_enforce = 0; #if defined (__i386__) || defined (__x86_64__) /* * We currently only support this on i386/x86_64, as that is the * only lock code we have instrumented so far. */ check_policy_init(policy_check_flags); #endif #endif /* MAC */ /* Initialize System Override call */ init_system_override(); /* * Create process 0. */ proc_list_lock(); LIST_INSERT_HEAD(&allproc, kernproc, p_list); kernproc->p_pgrp = &pgrp0; LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); LIST_INIT(&pgrp0.pg_members); #ifdef CONFIG_FINE_LOCK_GROUPS lck_mtx_init(&pgrp0.pg_mlock, proc_mlock_grp, proc_lck_attr); #else lck_mtx_init(&pgrp0.pg_mlock, proc_lck_grp, proc_lck_attr); #endif /* There is no other bsd thread this point and is safe without pgrp lock */ LIST_INSERT_HEAD(&pgrp0.pg_members, kernproc, p_pglist); kernproc->p_listflag |= P_LIST_INPGRP; kernproc->p_pgrpid = 0; kernproc->p_uniqueid = 0; pgrp0.pg_session = &session0; pgrp0.pg_membercnt = 1; session0.s_count = 1; session0.s_leader = kernproc; session0.s_listflags = 0; #ifdef CONFIG_FINE_LOCK_GROUPS lck_mtx_init(&session0.s_mlock, proc_mlock_grp, proc_lck_attr); #else lck_mtx_init(&session0.s_mlock, proc_lck_grp, proc_lck_attr); #endif LIST_INSERT_HEAD(SESSHASH(0), &session0, s_hash); proc_list_unlock(); kernproc->task = kernel_task; kernproc->p_stat = SRUN; kernproc->p_flag = P_SYSTEM; kernproc->p_lflag = 0; kernproc->p_ladvflag = 0; #if DEVELOPMENT || DEBUG if (bootarg_disable_aslr) kernproc->p_flag |= P_DISABLE_ASLR; #endif kernproc->p_nice = NZERO; kernproc->p_pptr = kernproc; TAILQ_INIT(&kernproc->p_uthlist); TAILQ_INSERT_TAIL(&kernproc->p_uthlist, ut, uu_list); kernproc->sigwait = FALSE; kernproc->sigwait_thread = THREAD_NULL; kernproc->exit_thread = THREAD_NULL; kernproc->p_csflags = CS_VALID; /* * Create credential. This also Initializes the audit information. */ bsd_init_kprintf("calling bzero\n"); bzero(&temp_cred, sizeof(temp_cred)); bzero(&temp_pcred, sizeof(temp_pcred)); temp_pcred.cr_ngroups = 1; /* kern_proc, shouldn't call up to DS for group membership */ temp_pcred.cr_flags = CRF_NOMEMBERD; temp_cred.cr_audit.as_aia_p = audit_default_aia_p; bsd_init_kprintf("calling kauth_cred_create\n"); /* * We have to label the temp cred before we create from it to * properly set cr_ngroups, or the create will fail. */ posix_cred_label(&temp_cred, &temp_pcred); kernproc->p_ucred = kauth_cred_create(&temp_cred); /* update cred on proc */ PROC_UPDATE_CREDS_ONPROC(kernproc); /* give the (already exisiting) initial thread a reference on it */ bsd_init_kprintf("calling kauth_cred_ref\n"); kauth_cred_ref(kernproc->p_ucred); ut->uu_context.vc_ucred = kernproc->p_ucred; ut->uu_context.vc_thread = current_thread(); TAILQ_INIT(&kernproc->p_aio_activeq); TAILQ_INIT(&kernproc->p_aio_doneq); kernproc->p_aio_total_count = 0; kernproc->p_aio_active_count = 0; bsd_init_kprintf("calling file_lock_init\n"); file_lock_init(); #if CONFIG_MACF mac_cred_label_associate_kernel(kernproc->p_ucred); #endif /* Create the file descriptor table. */ kernproc->p_fd = &filedesc0; filedesc0.fd_cmask = cmask; filedesc0.fd_knlistsize = -1; filedesc0.fd_knlist = NULL; filedesc0.fd_knhash = NULL; filedesc0.fd_knhashmask = 0; /* Create the limits structures. */ kernproc->p_limit = &limit0; for (i = 0; i < sizeof(kernproc->p_rlimit)/sizeof(kernproc->p_rlimit[0]); i++) limit0.pl_rlimit[i].rlim_cur = limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = maxprocperuid; limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; limit0.pl_rlimit[RLIMIT_STACK] = vm_initial_limit_stack; limit0.pl_rlimit[RLIMIT_DATA] = vm_initial_limit_data; limit0.pl_rlimit[RLIMIT_CORE] = vm_initial_limit_core; limit0.pl_refcnt = 1; kernproc->p_stats = &pstats0; kernproc->p_sigacts = &sigacts0; /* * Charge root for one process: launchd. */ bsd_init_kprintf("calling chgproccnt\n"); (void)chgproccnt(0, 1); /* * Allocate a kernel submap for pageable memory * for temporary copying (execve()). */ { vm_offset_t minimum; bsd_init_kprintf("calling kmem_suballoc\n"); assert(bsd_pageable_map_size != 0); ret = kmem_suballoc(kernel_map, &minimum, (vm_size_t)bsd_pageable_map_size, TRUE, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_BSD), &bsd_pageable_map); if (ret != KERN_SUCCESS) panic("bsd_init: Failed to allocate bsd pageable map"); } /* * Initialize buffers and hash links for buffers * * SIDE EFFECT: Starts a thread for bcleanbuf_thread(), so must * happen after a credential has been associated with * the kernel task. */ bsd_init_kprintf("calling bsd_bufferinit\n"); bsd_bufferinit(); /* Initialize the execve() semaphore */ bsd_init_kprintf("calling semaphore_create\n"); if (ret != KERN_SUCCESS) panic("bsd_init: Failed to create execve semaphore"); /* * Initialize the calendar. */ bsd_init_kprintf("calling IOKitInitializeTime\n"); IOKitInitializeTime(); bsd_init_kprintf("calling ubc_init\n"); ubc_init(); /* * Initialize device-switches. */ bsd_init_kprintf("calling devsw_init() \n"); devsw_init(); /* Initialize the file systems. */ bsd_init_kprintf("calling vfsinit\n"); vfsinit(); #if CONFIG_PROC_UUID_POLICY /* Initial proc_uuid_policy subsystem */ bsd_init_kprintf("calling proc_uuid_policy_init()\n"); proc_uuid_policy_init(); #endif #if SOCKETS /* Initialize per-CPU cache allocator */ mcache_init(); /* Initialize mbuf's. */ bsd_init_kprintf("calling mbinit\n"); mbinit(); net_str_id_init(); /* for mbuf tags */ #endif /* SOCKETS */ /* * Initializes security event auditing. * XXX: Should/could this occur later? */ #if CONFIG_AUDIT bsd_init_kprintf("calling audit_init\n"); audit_init(); #endif /* Initialize kqueues */ bsd_init_kprintf("calling knote_init\n"); knote_init(); /* Initialize for async IO */ bsd_init_kprintf("calling aio_init\n"); aio_init(); /* Initialize pipes */ bsd_init_kprintf("calling pipeinit\n"); pipeinit(); /* Initialize SysV shm subsystem locks; the subsystem proper is * initialized through a sysctl. */ #if SYSV_SHM bsd_init_kprintf("calling sysv_shm_lock_init\n"); sysv_shm_lock_init(); #endif #if SYSV_SEM bsd_init_kprintf("calling sysv_sem_lock_init\n"); sysv_sem_lock_init(); #endif #if SYSV_MSG bsd_init_kprintf("sysv_msg_lock_init\n"); sysv_msg_lock_init(); #endif bsd_init_kprintf("calling pshm_lock_init\n"); pshm_lock_init(); bsd_init_kprintf("calling psem_lock_init\n"); psem_lock_init(); pthread_init(); /* POSIX Shm and Sem */ bsd_init_kprintf("calling pshm_cache_init\n"); pshm_cache_init(); bsd_init_kprintf("calling psem_cache_init\n"); psem_cache_init(); bsd_init_kprintf("calling time_zone_slock_init\n"); time_zone_slock_init(); bsd_init_kprintf("calling select_waitq_init\n"); select_waitq_init(); /* * Initialize protocols. Block reception of incoming packets * until everything is ready. */ bsd_init_kprintf("calling sysctl_register_fixed\n"); sysctl_register_fixed(); bsd_init_kprintf("calling sysctl_mib_init\n"); sysctl_mib_init(); #if NETWORKING bsd_init_kprintf("calling dlil_init\n"); dlil_init(); bsd_init_kprintf("calling proto_kpi_init\n"); proto_kpi_init(); #endif /* NETWORKING */ #if SOCKETS bsd_init_kprintf("calling socketinit\n"); socketinit(); bsd_init_kprintf("calling domaininit\n"); domaininit(); iptap_init(); #if FLOW_DIVERT flow_divert_init(); #endif /* FLOW_DIVERT */ #endif /* SOCKETS */ kernproc->p_fd->fd_cdir = NULL; kernproc->p_fd->fd_rdir = NULL; #if CONFIG_FREEZE #ifndef CONFIG_MEMORYSTATUS #error "CONFIG_FREEZE defined without matching CONFIG_MEMORYSTATUS" #endif /* Initialise background freezing */ bsd_init_kprintf("calling memorystatus_freeze_init\n"); memorystatus_freeze_init(); #endif #if CONFIG_MEMORYSTATUS /* Initialize kernel memory status notifications */ bsd_init_kprintf("calling memorystatus_init\n"); memorystatus_init(); #endif /* CONFIG_MEMORYSTATUS */ bsd_init_kprintf("calling macx_init\n"); macx_init(); bsd_init_kprintf("calling acct_init\n"); acct_init(); #ifdef GPROF /* Initialize kernel profiling. */ kmstartup(); #endif bsd_init_kprintf("calling bsd_autoconf\n"); bsd_autoconf(); #if CONFIG_DTRACE dtrace_postinit(); #endif /* * We attach the loopback interface *way* down here to ensure * it happens after autoconf(), otherwise it becomes the * "primary" interface. */ #include <loop.h> #if NLOOP > 0 bsd_init_kprintf("calling loopattach\n"); loopattach(); /* XXX */ #endif #if NGIF /* Initialize gif interface (after lo0) */ gif_init(); #endif #if PFLOG /* Initialize packet filter log interface */ pfloginit(); #endif /* PFLOG */ #if NETHER > 0 /* Register the built-in dlil ethernet interface family */ bsd_init_kprintf("calling ether_family_init\n"); ether_family_init(); #endif /* ETHER */ #if NETWORKING /* Call any kext code that wants to run just after network init */ bsd_init_kprintf("calling net_init_run\n"); net_init_run(); #if CONTENT_FILTER cfil_init(); #endif #if PACKET_MANGLER pkt_mnglr_init(); #endif #if NECP /* Initialize Network Extension Control Policies */ necp_init(); #endif netagent_init(); /* register user tunnel kernel control handler */ utun_register_control(); #if IPSEC ipsec_register_control(); #endif /* IPSEC */ netsrc_init(); nstat_init(); tcp_cc_init(); #if MPTCP mptcp_control_register(); #endif /* MPTCP */ #endif /* NETWORKING */ bsd_init_kprintf("calling vnode_pager_bootstrap\n"); vnode_pager_bootstrap(); bsd_init_kprintf("calling inittodr\n"); inittodr(0); /* Mount the root file system. */ while( TRUE) { int err; bsd_init_kprintf("calling setconf\n"); setconf(); #if NFSCLIENT netboot = (mountroot == netboot_mountroot); #endif bsd_init_kprintf("vfs_mountroot\n"); if (0 == (err = vfs_mountroot())) break; rootdevice[0] = '\0'; #if NFSCLIENT if (netboot) { PE_display_icon( 0, "noroot"); /* XXX a netboot-specific icon would be nicer */ vc_progress_set(FALSE, 0); for (i=1; 1; i*=2) { printf("bsd_init: failed to mount network root, error %d, %s\n", err, PE_boot_args()); printf("We are hanging here...\n"); IOSleep(i*60*1000); } /*NOTREACHED*/ } #endif printf("cannot mount root, errno = %d\n", err); boothowto |= RB_ASKNAME; } IOSecureBSDRoot(rootdevice); context.vc_thread = current_thread(); context.vc_ucred = kernproc->p_ucred; mountlist.tqh_first->mnt_flag |= MNT_ROOTFS; bsd_init_kprintf("calling VFS_ROOT\n"); /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ if (VFS_ROOT(mountlist.tqh_first, &rootvnode, &context)) panic("bsd_init: cannot find root vnode: %s", PE_boot_args()); rootvnode->v_flag |= VROOT; (void)vnode_ref(rootvnode); (void)vnode_put(rootvnode); filedesc0.fd_cdir = rootvnode; #if NFSCLIENT if (netboot) { int err; netboot = TRUE; /* post mount setup */ if ((err = netboot_setup()) != 0) { PE_display_icon( 0, "noroot"); /* XXX a netboot-specific icon would be nicer */ vc_progress_set(FALSE, 0); for (i=1; 1; i*=2) { printf("bsd_init: NetBoot could not find root, error %d: %s\n", err, PE_boot_args()); printf("We are hanging here...\n"); IOSleep(i*60*1000); } /*NOTREACHED*/ } } #endif #if CONFIG_IMAGEBOOT /* * See if a system disk image is present. If so, mount it and * switch the root vnode to point to it */ if (netboot == FALSE && imageboot_needed()) { /* * An image was found. No turning back: we're booted * with a kernel from the disk image. */ imageboot_setup(); } #endif /* CONFIG_IMAGEBOOT */ /* set initial time; all other resource data is already zero'ed */ microtime_with_abstime(&kernproc->p_start, &kernproc->p_stats->ps_start); #if DEVFS { char mounthere[] = "/dev"; /* !const because of internal casting */ bsd_init_kprintf("calling devfs_kernel_mount\n"); devfs_kernel_mount(mounthere); } #endif /* DEVFS */ /* Initialize signal state for process 0. */ bsd_init_kprintf("calling siginit\n"); siginit(kernproc); bsd_init_kprintf("calling bsd_utaskbootstrap\n"); bsd_utaskbootstrap(); #if defined(__LP64__) kernproc->p_flag |= P_LP64; #endif pal_kernel_announce(); bsd_init_kprintf("calling mountroot_post_hook\n"); /* invoke post-root-mount hook */ if (mountroot_post_hook != NULL) mountroot_post_hook(); #if 0 /* not yet */ consider_zone_gc(FALSE); #endif bsd_init_kprintf("done\n"); }
/* * Initialization code. * Called from cold start routine as * soon as a stack and segmentation * have been established. * Functions: * clear and free user core * turn on clock * hand craft 0th process * call all initialization routines * fork - process 0 to schedule * - process 1 execute bootstrap */ int main() { register struct proc *p; register int i; register struct fs *fs = NULL; char inbuf[4]; char inch; int s __attribute__((unused)); startup(); printf ("\n%s", version); cpuidentify(); cnidentify(); /* * Set up system process 0 (swapper). */ p = &proc[0]; p->p_addr = (size_t) &u; p->p_stat = SRUN; p->p_flag |= SLOAD | SSYS; p->p_nice = NZERO; u.u_procp = p; /* init user structure */ u.u_cmask = CMASK; u.u_lastfile = -1; for (i = 1; i < NGROUPS; i++) u.u_groups[i] = NOGROUP; for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++) u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max = RLIM_INFINITY; /* Initialize signal state for process 0 */ siginit (p); /* * Initialize tables, protocols, and set up well-known inodes. */ #ifdef LOG_ENABLED loginit(); #endif coutinit(); cinit(); pqinit(); ihinit(); bhinit(); binit(); nchinit(); clkstart(); s = spl0(); rdisk_init(); pipedev = rootdev = get_boot_device(); swapdev = get_swap_device(); /* Mount a root filesystem. */ for (;;) { if(rootdev!=-1) { fs = mountfs (rootdev, (boothowto & RB_RDONLY) ? MNT_RDONLY : 0, (struct inode*) 0); } if (fs) break; printf ("No root filesystem available!\n"); // rdisk_list_partitions(RDISK_FS); retry: printf ("Please enter device to boot from (press ? to list): "); inch=0; inbuf[0] = inbuf[1] = inbuf[2] = inbuf[3] = 0; while((inch=cngetc()) != '\r') { switch(inch) { case '?': printf("?\n"); rdisk_list_partitions(RDISK_FS); printf ("Please enter device to boot from (press ? to list): "); break; default: printf("%c",inch); inbuf[0] = inbuf[1]; inbuf[1] = inbuf[2]; inbuf[2] = inbuf[3]; inbuf[3] = inch; break; } } inch = 0; if(inbuf[0]=='r' && inbuf[1]=='d') { if(inbuf[2]>='0' && inbuf[2] < '0'+rdisk_num_disks()) { if(inbuf[3]>='a' && inbuf[3]<='d') { rootdev=makedev(inbuf[2]-'0',inbuf[3]-'a'+1); inch = 1; } } } else if(inbuf[1]=='r' && inbuf[2]=='d') { if(inbuf[3]>='0' && inbuf[3] < '0'+rdisk_num_disks()) { rootdev=makedev(inbuf[3]-'0',0); inch = 1; } } else if(inbuf[3] == 0) { inch = 1; } if(inch==0) { printf("\nUnknown device.\n\n"); goto retry; } printf ("\n\n"); } printf ("phys mem = %u kbytes\n", physmem / 1024); printf ("user mem = %u kbytes\n", MAXMEM / 1024); if(minor(rootdev)==0) { printf ("root dev = rd%d (%d,%d)\n", major(rootdev), major(rootdev), minor(rootdev) ); } else { printf ("root dev = rd%d%c (%d,%d)\n", major(rootdev), 'a'+minor(rootdev)-1, major(rootdev), minor(rootdev) ); } printf ("root size = %u kbytes\n", fs->fs_fsize * DEV_BSIZE / 1024); mount[0].m_inodp = (struct inode*) 1; /* XXX */ mount_updname (fs, "/", "root", 1, 4); time.tv_sec = fs->fs_time; boottime = time; /* Find a swap file. */ swapstart = 1; while(swapdev == -1) { printf("Please enter swap device (press ? to list): "); inbuf[0] = inbuf[1] = inbuf[2] = inbuf[3] = 0; while((inch = cngetc())!='\r') { switch(inch) { case '?': printf("?\n"); rdisk_list_partitions(RDISK_SWAP); printf("Please enter swap device (press ? to list): "); break; default: printf("%c",inch); inbuf[0] = inbuf[1]; inbuf[1] = inbuf[2]; inbuf[2] = inbuf[3]; inbuf[3] = inch; break; } } inch = 0; if(inbuf[0]=='r' && inbuf[1]=='d') { if(inbuf[2]>='0' && inbuf[2] < '0'+rdisk_num_disks()) { if(inbuf[3]>='a' && inbuf[3]<='d') { swapdev=makedev(inbuf[2]-'0',inbuf[3]-'a'+1); inch = 1; } } } else if(inbuf[1]=='r' && inbuf[2]=='d') { if(inbuf[3]>='0' && inbuf[3] < '0'+rdisk_num_disks()) { swapdev=makedev(inbuf[3]-'0',0); inch = 1; } } if(minor(swapdev)!=0) { if(partition_type(swapdev)!=RDISK_SWAP) { printf("\nNot a swap partition!\n\n"); swapdev=-1; } } } nswap = rdsize(swapdev); if(minor(swapdev)==0) { printf ("swap dev = rd%d (%d,%d)\n", major(swapdev), major(swapdev), minor(swapdev) ); } else { printf ("swap dev = rd%d%c (%d,%d)\n", major(swapdev), 'a'+minor(swapdev)-1, major(swapdev), minor(swapdev) ); } (*bdevsw[major(swapdev)].d_open)(swapdev, FREAD|FWRITE, S_IFBLK); printf ("swap size = %u kbytes\n", nswap * DEV_BSIZE / 1024); if (nswap <= 0) panic ("zero swap size"); /* don't want to panic, but what ? */ mfree (swapmap, nswap, swapstart); /* Kick off timeout driven events by calling first time. */ schedcpu (0); /* Set up the root file system. */ rootdir = iget (rootdev, &mount[0].m_filsys, (ino_t) ROOTINO); iunlock (rootdir); u.u_cdir = iget (rootdev, &mount[0].m_filsys, (ino_t) ROOTINO); iunlock (u.u_cdir); u.u_rdir = NULL; /* * Make init process. */ if (newproc (0) == 0) { /* Parent process with pid 0: swapper. * No return from sched. */ sched(); } /* Child process with pid 1: init. */ s = splhigh(); p = u.u_procp; p->p_dsize = icodeend - icode; p->p_daddr = USER_DATA_START; p->p_ssize = 1024; /* one kbyte of stack */ p->p_saddr = USER_DATA_END - 1024; bcopy ((caddr_t) icode, (caddr_t) USER_DATA_START, icodeend - icode); /* * return goes to location 0 of user init code * just copied out. */ return 0; }
int client_main(struct client_ctx *cctx) { struct pollfd pfd; int n, nfds; siginit(); logfile("client"); /* * imsg_read in the first client poll loop (before the terminal has * been initialiased) may have read messages into the buffer after the * MSG_READY switched to here. Process anything outstanding now so poll * doesn't hang waiting for messages that have already arrived. */ if (client_msg_dispatch(cctx) != 0) goto out; for (;;) { if (sigterm) client_write_server(cctx, MSG_EXITING, NULL, 0); if (sigchld) { waitpid(WAIT_ANY, NULL, WNOHANG); sigchld = 0; } if (sigwinch) client_handle_winch(cctx); if (sigcont) { siginit(); client_write_server(cctx, MSG_WAKEUP, NULL, 0); sigcont = 0; } pfd.fd = cctx->ibuf.fd; pfd.events = POLLIN; if (cctx->ibuf.w.queued > 0) pfd.events |= POLLOUT; if ((nfds = poll(&pfd, 1, INFTIM)) == -1) { if (errno == EAGAIN || errno == EINTR) continue; fatal("poll failed"); } if (nfds == 0) continue; if (pfd.revents & (POLLERR|POLLHUP|POLLNVAL)) fatalx("socket error"); if (pfd.revents & POLLIN) { if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) { cctx->exittype = CCTX_DIED; break; } if (client_msg_dispatch(cctx) != 0) break; } if (pfd.revents & POLLOUT) { if (msgbuf_write(&cctx->ibuf.w) < 0) { cctx->exittype = CCTX_DIED; break; } } } out: if (sigterm) { printf("[terminated]\n"); return (1); } switch (cctx->exittype) { case CCTX_DIED: printf("[lost server]\n"); return (0); case CCTX_SHUTDOWN: printf("[server exited]\n"); return (0); case CCTX_EXIT: if (cctx->errstr != NULL) { printf("[error: %s]\n", cctx->errstr); return (1); } printf("[exited]\n"); return (0); case CCTX_DETACH: printf("[detached]\n"); return (0); default: printf("[unknown error]\n"); return (1); } }
/* * Logger helper app [only for non-unix systems] */ INTERNAL void logger(char *pgm, int argc, char **argv) { char *logserver; char *cmd; char args[AGENTD_PATHLEN]; int id, nc; int pid; int ok, help; int i; int rc; ok = 1; help = 0; Verbose = 0; while (argc && *argv[0] == '-') { char *opt; opt = argv[0] + 1; ++argv; --argc; if (substr(opt, "help")) ++help; else if (substr(opt, "debug")) ++Debug; else if (substr(opt, "nodebug")) Debug = 0; else if (substr(opt, "verbose")) Verbose = 1; else if (substr(opt, "quiet")) Verbose = 0; else if (substr(opt, "wd")) { if (argc < 1) { fprintf(stderr, "%s: missing argument to -%s\n", pgm, opt); ok = 0; break; } WorkDir = argv[0]; ++argv; --argc; } else if (substr(opt, "bin")) { if (argc < 1) { fprintf(stderr, "%s: missing argument to -%s\n", pgm, opt); ok = 0; break; } strcpy(ExecPath, argv[0]); ++argv; --argc; } else { fprintf(stderr, "%s: ignoring argument -%s\n", pgm, opt); help = 1; ok = 0; } } if (!ok || argc == 0) { logger_usage(pgm, help); exit(!help); } if (argc < 2) { fprintf(stderr, "usage: %s logserver cmd [args]\n", pgm); exit(4); } logserver = argv[0]; ++argv; --argc; cmd = argv[0]; ++argv; --argc; args[0] = '\0'; while (argc) { strcat(args, " "); strcat(args, argv[0]); ++argv; --argc; } /* Initialize agent control structures */ for (i = 0; i < MAX_AGENT; ++i) { Agent[i].pid = 0; Agent[i].status = AGENTD_AGENT_FREE; } event_verbose(Verbose); event_tunnel_enable(0); agentd_init(); siginit(); /* deal with signals */ id = event_join(logserver, &nc); if (id <= 0) { fprintf(stderr, "%s: couldn't join server %s\n", pgm, logserver); exit(4); } /* * N.B. For the moment disable the reading of all events * if we need to process incoming events, for some reason, we * should launch a separate thread, similar to the stdout/err * "reader" threads that get started in "start_agent". * Note that start_agent does not return until the subproccess, * i.e. the agent, terminates */ event_select_type(0, ET_MIN, ET_MAX); /*** No, not even these event_select_type(1, ET_AGENTD_MIN, ET_AGENTD_MAX); ***/ event_receive_enable(0); event_flush(1); event_register(LOGGERCLASS, LOGGERSPEC, cmd); rc = start_agent(NULL, cmd, args, &pid); event_leave(); exit(rc); }
main(int argc, char *argv[]) { char *pgm, *s; int ok, help; char *server; int id, nc; int i; char me[256]; char logstr[200]; pgm = argv[0]; /* Get and save our original working directory */ if (!GetWD(SelfWD, sizeof(SelfWD))) { fprintf(stderr, "%s: couldn't get working directory\n", pgm); perror(pgm); exit(4); } /* Get our own name and any path prefix */ if (pgm = strrchr(argv[0], '/')) { *pgm++ = '\0'; if (*argv[0] == '/') strcpy(Logdir, argv[0]); else make_path(Logdir, SelfWD, argv[0]); if (Verbose) printf("Logdir search is \"%s\"\n", Logdir); } else { strcpy(Logdir, SelfWD); pgm = argv[0]; } ++argv; --argc; /* See if we are running as the LOGGER */ sprintf(logstr, "{%s,%s%s}", LOGGEREXEC, LOGGEREXEC, LOGGEREXT); if (strmatch(logstr, pgm)) logger(pgm, argc, argv); /* Default options */ ok = 1; help = 0; /* Parse out command line options */ while (argc && *argv[0] == '-') { char *opt; opt = argv[0] + 1; ++argv; --argc; if (substr(opt, "help")) ++help; else if (substr(opt, "debug")) ++Debug; else if (substr(opt, "nodebug")) Debug = 0; else if (substr(opt, "verbose")) Verbose = 1; else if (substr(opt, "quiet")) Verbose = 0; else if (streq(opt, "bin") || streq(opt, "dir")) { if (argc < 1) { fprintf(stderr, "%s: missing argument to -%s\n", pgm, opt); ok = 0; break; } RootPath = argv[0]; ++argv; --argc; } else if (streq(opt, "wd") || streq(opt, "cd")) { if (argc < 1) { fprintf(stderr, "%s: missing argument to -%s\n", pgm, opt); ok = 0; break; } WorkDir = argv[0]; ++argv; --argc; } else if (substr(opt, "logger")) { if (argc < 1) { fprintf(stderr, "%s: missing argument to -%s\n", pgm, opt); ok = 0; break; } if (argv[0][0] == '/') strcpy(Logger, argv[0]); else { int len; char *name; /* Copy the current working directory */ strcpy(Logger, SelfWD); len = strlen(Logger); if (Logger[len-1] != '/') Logger[len++] = '/'; name = argv[0]; if (substr("./", name)) name += 2; strcpy(Logger+len, name); } ++argv; --argc; } else { fprintf(stderr, "%s: ignoring argument -%s\n", pgm, opt); help = 1; ok = 0; } } if (!ok || argc == 0) { usage(pgm, help); exit(!help); } server = argv[0]; ++argv; --argc; /* Allow directory to be specified as last command line arg */ if (argc) { if (RootPath) { if (!streq(RootPath, argv[0])) { fprintf(stderr, "%s: can't use -dir (%s) and specify path (%s)\n", pgm, RootPath, argv[0]); exit(4); } } else { RootPath = argv[0]; ++argv; --argc; } } /* Check for any extraneous args */ if (argc) { fprintf(stderr, "%s: too many arguments starting with \"%s\"\n", pgm, argv[0]); usage(pgm, help); exit(!help); } /* Now change to our root directory */ if (RootPath) { if (chdir(RootPath) != SYS_OK) { fprintf(stderr, "%s: couldn't chdir to \"%s\"\n", pgm, RootPath); exit(4); } } else fprintf(stderr, "%s: WARNING! no root directory specified - using .\n", pgm); /* Set up path to working directory for lauched agents */ if (WorkDir) if (*WorkDir == '/') strcpy(WorkPath, WorkDir); else make_path(WorkPath, SelfWD, WorkDir); /* Open the executable directory to process queries */ if (!GetWD(ExecPath, sizeof(ExecPath))) { fprintf(stderr, "%s: couldn't get working directory\n", pgm); perror(pgm); exit(4); } ExecDir = opendir(ExecPath); if (!ExecDir) { fprintf(stderr, "%s: couldn't open working directory \"%s\"\n", pgm, ExecPath); perror(pgm); exit(4); } #ifdef win32 /* * On windows we need to run the logger as a separate helper app * since the cygwin implementation of fork is not quite right. * Look for it in standard places as well as looking as users $PATH */ if (!Logger[0] && !find_logger()) { fprintf(stderr, "%s: couldn't find initiator \"%s\"\n", pgm, LOGGEREXEC); exit(4); } if (Verbose) printf("Logger exec is \"%s\"\n", Logger); #endif /* Make sure we found the file and it is executable */ if (Logger[0] && access(Logger, X_OK) != SYS_OK) { fprintf(stderr, "%s: initiator \"%s\" not %s\n", pgm, Logger, access(Logger, F_OK)?"found":"executable"); exit(4); } /* Deal with signals */ siginit(); /* local initialization */ event_verbose(Verbose); event_tunnel_enable(0); agentd_init(); /* Connect to our event server */ id = event_join(server, &nc); if (!id) { fprintf(stderr, "%s: couldn't join server \"%s\"\n", pgm, server); exit(4); } if (Verbose) printf("%s: joined %s as client id %d (%d clients)\n", pgm, server, id, nc); /* Register */ cuserid(me); event_register(AGENTDCLASS, AGENTDSPEC, me); /* Subscribe to only AGENTD type events */ event_select_type(0, ET_MIN, ET_MAX); event_select_type(1, ET_AGENTD_MIN, ET_AGENTD_MAX); /* Initialize agent control structures */ for (i = 0; i < MAX_AGENT; ++i) { Agent[i].pid = 0; Agent[i].status = AGENTD_AGENT_FREE; } mp_init(); /*(not strcitly necessary, since done in event land)*/ /* Allocate our locks and semaphores */ AgentLock = mp_alloclock(); Exitlock = mp_alloclock(); Exitwait = mp_allocsema(); ReadInit = mp_allocsema(); AgentInit = mp_allocsema(); /* * Loop forever processing agentd requests */ FOREVER { EVENT e; /* Wait for an event and then dispatch it */ event_wait(); if (!event_receive(&e)) continue; switch (e.ev_head.type) { case ET_AGENTD_REQ: agent_request((EVENT_AGENTD_REQ *)&e); break; default: if (Verbose) printf("Ignoring event \'%s\'(%d) from %d\n", event_lookup_name(e.ev_head.type), e.ev_head.type, e.ev_head.from); } } }
/* * This function is called very early on in the Mach startup, from the * function start_kernel_threads() in osfmk/kern/startup.c. It's called * in the context of the current (startup) task using a call to the * function kernel_thread_create() to jump into start_kernel_threads(). * Internally, kernel_thread_create() calls thread_create_internal(), * which calls uthread_alloc(). The function of uthread_alloc() is * normally to allocate a uthread structure, and fill out the uu_sigmask, * uu_context fields. It skips filling these out in the case of the "task" * being "kernel_task", because the order of operation is inverted. To * account for that, we need to manually fill in at least the contents * of the uu_context.vc_ucred field so that the uthread structure can be * used like any other. */ void bsd_init(void) { struct uthread *ut; unsigned int i; #if __i386__ || __x86_64__ int error; #endif struct vfs_context context; kern_return_t ret; struct ucred temp_cred; #define bsd_init_kprintf(x...) /* kprintf("bsd_init: " x) */ kernel_flock = funnel_alloc(KERNEL_FUNNEL); if (kernel_flock == (funnel_t *)0 ) { panic("bsd_init: Failed to allocate kernel funnel"); } printf(copyright); bsd_init_kprintf("calling kmeminit\n"); kmeminit(); bsd_init_kprintf("calling parse_bsd_args\n"); parse_bsd_args(); /* Initialize kauth subsystem before instancing the first credential */ bsd_init_kprintf("calling kauth_init\n"); kauth_init(); /* Initialize process and pgrp structures. */ bsd_init_kprintf("calling procinit\n"); procinit(); /* Initialize the ttys (MUST be before kminit()/bsd_autoconf()!)*/ tty_init(); kernproc = &proc0; /* implicitly bzero'ed */ /* kernel_task->proc = kernproc; */ set_bsdtask_info(kernel_task,(void *)kernproc); /* give kernproc a name */ bsd_init_kprintf("calling process_name\n"); process_name("kernel_task", kernproc); /* allocate proc lock group attribute and group */ bsd_init_kprintf("calling lck_grp_attr_alloc_init\n"); proc_lck_grp_attr= lck_grp_attr_alloc_init(); proc_lck_grp = lck_grp_alloc_init("proc", proc_lck_grp_attr); #ifndef CONFIG_EMBEDDED proc_slock_grp = lck_grp_alloc_init("proc-slock", proc_lck_grp_attr); proc_fdmlock_grp = lck_grp_alloc_init("proc-fdmlock", proc_lck_grp_attr); proc_mlock_grp = lck_grp_alloc_init("proc-mlock", proc_lck_grp_attr); #endif /* Allocate proc lock attribute */ proc_lck_attr = lck_attr_alloc_init(); #if 0 #if __PROC_INTERNAL_DEBUG lck_attr_setdebug(proc_lck_attr); #endif #endif #ifdef CONFIG_EMBEDDED proc_list_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); proc_klist_mlock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_mlock, proc_lck_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_fdmlock, proc_lck_grp, proc_lck_attr); lck_spin_init(&kernproc->p_slock, proc_lck_grp, proc_lck_attr); #else proc_list_mlock = lck_mtx_alloc_init(proc_mlock_grp, proc_lck_attr); proc_klist_mlock = lck_mtx_alloc_init(proc_mlock_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_mlock, proc_mlock_grp, proc_lck_attr); lck_mtx_init(&kernproc->p_fdmlock, proc_fdmlock_grp, proc_lck_attr); lck_spin_init(&kernproc->p_slock, proc_slock_grp, proc_lck_attr); #endif execargs_cache_lock = lck_mtx_alloc_init(proc_lck_grp, proc_lck_attr); execargs_cache_size = bsd_simul_execs; execargs_free_count = bsd_simul_execs; execargs_cache = (vm_offset_t *)kalloc(bsd_simul_execs * sizeof(vm_offset_t)); bzero(execargs_cache, bsd_simul_execs * sizeof(vm_offset_t)); if (current_task() != kernel_task) printf("bsd_init: We have a problem, " "current task is not kernel task\n"); bsd_init_kprintf("calling get_bsdthread_info\n"); ut = (uthread_t)get_bsdthread_info(current_thread()); #if CONFIG_MACF /* * Initialize the MAC Framework */ mac_policy_initbsd(); kernproc->p_mac_enforce = 0; #endif /* MAC */ /* * Create process 0. */ proc_list_lock(); LIST_INSERT_HEAD(&allproc, kernproc, p_list); kernproc->p_pgrp = &pgrp0; LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); LIST_INIT(&pgrp0.pg_members); #ifdef CONFIG_EMBEDDED lck_mtx_init(&pgrp0.pg_mlock, proc_lck_grp, proc_lck_attr); #else lck_mtx_init(&pgrp0.pg_mlock, proc_mlock_grp, proc_lck_attr); #endif /* There is no other bsd thread this point and is safe without pgrp lock */ LIST_INSERT_HEAD(&pgrp0.pg_members, kernproc, p_pglist); kernproc->p_listflag |= P_LIST_INPGRP; kernproc->p_pgrpid = 0; pgrp0.pg_session = &session0; pgrp0.pg_membercnt = 1; session0.s_count = 1; session0.s_leader = kernproc; session0.s_listflags = 0; #ifdef CONFIG_EMBEDDED lck_mtx_init(&session0.s_mlock, proc_lck_grp, proc_lck_attr); #else lck_mtx_init(&session0.s_mlock, proc_mlock_grp, proc_lck_attr); #endif LIST_INSERT_HEAD(SESSHASH(0), &session0, s_hash); proc_list_unlock(); #if CONFIG_LCTX kernproc->p_lctx = NULL; #endif kernproc->task = kernel_task; kernproc->p_stat = SRUN; kernproc->p_flag = P_SYSTEM; kernproc->p_nice = NZERO; kernproc->p_pptr = kernproc; TAILQ_INIT(&kernproc->p_uthlist); TAILQ_INSERT_TAIL(&kernproc->p_uthlist, ut, uu_list); kernproc->sigwait = FALSE; kernproc->sigwait_thread = THREAD_NULL; kernproc->exit_thread = THREAD_NULL; kernproc->p_csflags = CS_VALID; /* * Create credential. This also Initializes the audit information. */ bsd_init_kprintf("calling bzero\n"); bzero(&temp_cred, sizeof(temp_cred)); temp_cred.cr_ngroups = 1; temp_cred.cr_audit.as_aia_p = &audit_default_aia; /* XXX the following will go away with cr_au */ temp_cred.cr_au.ai_auid = AU_DEFAUDITID; bsd_init_kprintf("calling kauth_cred_create\n"); kernproc->p_ucred = kauth_cred_create(&temp_cred); /* give the (already exisiting) initial thread a reference on it */ bsd_init_kprintf("calling kauth_cred_ref\n"); kauth_cred_ref(kernproc->p_ucred); ut->uu_context.vc_ucred = kernproc->p_ucred; ut->uu_context.vc_thread = current_thread(); TAILQ_INIT(&kernproc->p_aio_activeq); TAILQ_INIT(&kernproc->p_aio_doneq); kernproc->p_aio_total_count = 0; kernproc->p_aio_active_count = 0; bsd_init_kprintf("calling file_lock_init\n"); file_lock_init(); #if CONFIG_MACF mac_cred_label_associate_kernel(kernproc->p_ucred); mac_task_label_update_cred (kernproc->p_ucred, (struct task *) kernproc->task); #endif /* Create the file descriptor table. */ filedesc0.fd_refcnt = 1+1; /* +1 so shutdown will not _FREE_ZONE */ kernproc->p_fd = &filedesc0; filedesc0.fd_cmask = cmask; filedesc0.fd_knlistsize = -1; filedesc0.fd_knlist = NULL; filedesc0.fd_knhash = NULL; filedesc0.fd_knhashmask = 0; /* Create the limits structures. */ kernproc->p_limit = &limit0; for (i = 0; i < sizeof(kernproc->p_rlimit)/sizeof(kernproc->p_rlimit[0]); i++) limit0.pl_rlimit[i].rlim_cur = limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = maxprocperuid; limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; limit0.pl_rlimit[RLIMIT_STACK] = vm_initial_limit_stack; limit0.pl_rlimit[RLIMIT_DATA] = vm_initial_limit_data; limit0.pl_rlimit[RLIMIT_CORE] = vm_initial_limit_core; limit0.pl_refcnt = 1; kernproc->p_stats = &pstats0; kernproc->p_sigacts = &sigacts0; /* * Charge root for two processes: init and mach_init. */ bsd_init_kprintf("calling chgproccnt\n"); (void)chgproccnt(0, 1); /* * Allocate a kernel submap for pageable memory * for temporary copying (execve()). */ { vm_offset_t minimum; bsd_init_kprintf("calling kmem_suballoc\n"); ret = kmem_suballoc(kernel_map, &minimum, (vm_size_t)bsd_pageable_map_size, TRUE, VM_FLAGS_ANYWHERE, &bsd_pageable_map); if (ret != KERN_SUCCESS) panic("bsd_init: Failed to allocate bsd pageable map"); } /* * Initialize buffers and hash links for buffers * * SIDE EFFECT: Starts a thread for bcleanbuf_thread(), so must * happen after a credential has been associated with * the kernel task. */ bsd_init_kprintf("calling bsd_bufferinit\n"); bsd_bufferinit(); /* Initialize the execve() semaphore */ bsd_init_kprintf("calling semaphore_create\n"); if (ret != KERN_SUCCESS) panic("bsd_init: Failed to create execve semaphore"); /* * Initialize the calendar. */ bsd_init_kprintf("calling IOKitInitializeTime\n"); IOKitInitializeTime(); if (turn_on_log_leaks && !new_nkdbufs) new_nkdbufs = 200000; start_kern_tracing(new_nkdbufs); if (turn_on_log_leaks) log_leaks = 1; bsd_init_kprintf("calling ubc_init\n"); ubc_init(); /* Initialize the file systems. */ bsd_init_kprintf("calling vfsinit\n"); vfsinit(); #if SOCKETS /* Initialize per-CPU cache allocator */ mcache_init(); /* Initialize mbuf's. */ bsd_init_kprintf("calling mbinit\n"); mbinit(); net_str_id_init(); /* for mbuf tags */ #endif /* SOCKETS */ /* * Initializes security event auditing. * XXX: Should/could this occur later? */ #if CONFIG_AUDIT bsd_init_kprintf("calling audit_init\n"); audit_init(); #endif /* Initialize kqueues */ bsd_init_kprintf("calling knote_init\n"); knote_init(); /* Initialize for async IO */ bsd_init_kprintf("calling aio_init\n"); aio_init(); /* Initialize pipes */ bsd_init_kprintf("calling pipeinit\n"); pipeinit(); /* Initialize SysV shm subsystem locks; the subsystem proper is * initialized through a sysctl. */ #if SYSV_SHM bsd_init_kprintf("calling sysv_shm_lock_init\n"); sysv_shm_lock_init(); #endif #if SYSV_SEM bsd_init_kprintf("calling sysv_sem_lock_init\n"); sysv_sem_lock_init(); #endif #if SYSV_MSG bsd_init_kprintf("sysv_msg_lock_init\n"); sysv_msg_lock_init(); #endif bsd_init_kprintf("calling pshm_lock_init\n"); pshm_lock_init(); bsd_init_kprintf("calling psem_lock_init\n"); psem_lock_init(); pthread_init(); /* POSIX Shm and Sem */ bsd_init_kprintf("calling pshm_cache_init\n"); pshm_cache_init(); bsd_init_kprintf("calling psem_cache_init\n"); psem_cache_init(); bsd_init_kprintf("calling time_zone_slock_init\n"); time_zone_slock_init(); /* Stack snapshot facility lock */ stackshot_lock_init(); /* * Initialize protocols. Block reception of incoming packets * until everything is ready. */ bsd_init_kprintf("calling sysctl_register_fixed\n"); sysctl_register_fixed(); bsd_init_kprintf("calling sysctl_mib_init\n"); sysctl_mib_init(); #if NETWORKING bsd_init_kprintf("calling dlil_init\n"); dlil_init(); bsd_init_kprintf("calling proto_kpi_init\n"); proto_kpi_init(); #endif /* NETWORKING */ #if SOCKETS bsd_init_kprintf("calling socketinit\n"); socketinit(); bsd_init_kprintf("calling domaininit\n"); domaininit(); #endif /* SOCKETS */ kernproc->p_fd->fd_cdir = NULL; kernproc->p_fd->fd_rdir = NULL; #if CONFIG_EMBEDDED /* Initialize kernel memory status notifications */ bsd_init_kprintf("calling kern_memorystatus_init\n"); kern_memorystatus_init(); #endif #ifdef GPROF /* Initialize kernel profiling. */ kmstartup(); #endif /* kick off timeout driven events by calling first time */ thread_wakeup(&lbolt); timeout(lightning_bolt, 0, hz); bsd_init_kprintf("calling bsd_autoconf\n"); bsd_autoconf(); #if CONFIG_DTRACE dtrace_postinit(); #endif /* * We attach the loopback interface *way* down here to ensure * it happens after autoconf(), otherwise it becomes the * "primary" interface. */ #include <loop.h> #if NLOOP > 0 bsd_init_kprintf("calling loopattach\n"); loopattach(); /* XXX */ #endif #if PFLOG /* Initialize packet filter log interface */ pfloginit(); #endif /* PFLOG */ #if NETHER > 0 /* Register the built-in dlil ethernet interface family */ bsd_init_kprintf("calling ether_family_init\n"); ether_family_init(); #endif /* ETHER */ #if NETWORKING /* Call any kext code that wants to run just after network init */ bsd_init_kprintf("calling net_init_run\n"); net_init_run(); /* register user tunnel kernel control handler */ utun_register_control(); #endif /* NETWORKING */ bsd_init_kprintf("calling vnode_pager_bootstrap\n"); vnode_pager_bootstrap(); #if 0 /* XXX Hack for early debug stop */ printf("\nabout to sleep for 10 seconds\n"); IOSleep( 10 * 1000 ); /* Debugger("hello"); */ #endif bsd_init_kprintf("calling inittodr\n"); inittodr(0); #if CONFIG_EMBEDDED { /* print out early VM statistics */ kern_return_t kr1; vm_statistics_data_t stat; mach_msg_type_number_t count; count = HOST_VM_INFO_COUNT; kr1 = host_statistics(host_self(), HOST_VM_INFO, (host_info_t)&stat, &count); kprintf("Mach Virtual Memory Statistics (page size of 4096) bytes\n" "Pages free:\t\t\t%u.\n" "Pages active:\t\t\t%u.\n" "Pages inactive:\t\t\t%u.\n" "Pages wired down:\t\t%u.\n" "\"Translation faults\":\t\t%u.\n" "Pages copy-on-write:\t\t%u.\n" "Pages zero filled:\t\t%u.\n" "Pages reactivated:\t\t%u.\n" "Pageins:\t\t\t%u.\n" "Pageouts:\t\t\t%u.\n" "Object cache: %u hits of %u lookups (%d%% hit rate)\n", stat.free_count, stat.active_count, stat.inactive_count, stat.wire_count, stat.faults, stat.cow_faults, stat.zero_fill_count, stat.reactivations, stat.pageins, stat.pageouts, stat.hits, stat.lookups, (stat.hits == 0) ? 100 : ((stat.lookups * 100) / stat.hits)); } #endif /* CONFIG_EMBEDDED */ /* Mount the root file system. */ while( TRUE) { int err; bsd_init_kprintf("calling setconf\n"); setconf(); bsd_init_kprintf("vfs_mountroot\n"); if (0 == (err = vfs_mountroot())) break; rootdevice[0] = '\0'; #if NFSCLIENT if (mountroot == netboot_mountroot) { PE_display_icon( 0, "noroot"); /* XXX a netboot-specific icon would be nicer */ vc_progress_set(FALSE, 0); for (i=1; 1; i*=2) { printf("bsd_init: failed to mount network root, error %d, %s\n", err, PE_boot_args()); printf("We are hanging here...\n"); IOSleep(i*60*1000); } /*NOTREACHED*/ } #endif printf("cannot mount root, errno = %d\n", err); boothowto |= RB_ASKNAME; } IOSecureBSDRoot(rootdevice); context.vc_thread = current_thread(); context.vc_ucred = kernproc->p_ucred; mountlist.tqh_first->mnt_flag |= MNT_ROOTFS; bsd_init_kprintf("calling VFS_ROOT\n"); /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ if (VFS_ROOT(mountlist.tqh_first, &rootvnode, &context)) panic("bsd_init: cannot find root vnode: %s", PE_boot_args()); rootvnode->v_flag |= VROOT; (void)vnode_ref(rootvnode); (void)vnode_put(rootvnode); filedesc0.fd_cdir = rootvnode; #if NFSCLIENT if (mountroot == netboot_mountroot) { int err; /* post mount setup */ if ((err = netboot_setup()) != 0) { PE_display_icon( 0, "noroot"); /* XXX a netboot-specific icon would be nicer */ vc_progress_set(FALSE, 0); for (i=1; 1; i*=2) { printf("bsd_init: NetBoot could not find root, error %d: %s\n", err, PE_boot_args()); printf("We are hanging here...\n"); IOSleep(i*60*1000); } /*NOTREACHED*/ } } #endif #if CONFIG_IMAGEBOOT /* * See if a system disk image is present. If so, mount it and * switch the root vnode to point to it */ if(imageboot_needed()) { int err; /* An image was found */ if((err = imageboot_setup())) { /* * this is not fatal. Keep trying to root * off the original media */ printf("%s: imageboot could not find root, %d\n", __FUNCTION__, err); } } #endif /* CONFIG_IMAGEBOOT */ /* set initial time; all other resource data is already zero'ed */ microtime(&kernproc->p_start); kernproc->p_stats->p_start = kernproc->p_start; /* for compat */ #if DEVFS { char mounthere[] = "/dev"; /* !const because of internal casting */ bsd_init_kprintf("calling devfs_kernel_mount\n"); devfs_kernel_mount(mounthere); } #endif /* DEVFS */ /* Initialize signal state for process 0. */ bsd_init_kprintf("calling siginit\n"); siginit(kernproc); bsd_init_kprintf("calling bsd_utaskbootstrap\n"); bsd_utaskbootstrap(); #if defined(__LP64__) kernproc->p_flag |= P_LP64; printf("Kernel is LP64\n"); #endif #if __i386__ || __x86_64__ /* this should be done after the root filesystem is mounted */ error = set_archhandler(kernproc, CPU_TYPE_POWERPC); // 10/30/08 - gab: <rdar://problem/6324501> // if default 'translate' can't be found, see if the understudy is available if (ENOENT == error) { strlcpy(exec_archhandler_ppc.path, kRosettaStandIn_str, MAXPATHLEN); error = set_archhandler(kernproc, CPU_TYPE_POWERPC); } if (error) /* XXX make more generic */ exec_archhandler_ppc.path[0] = 0; #endif bsd_init_kprintf("calling mountroot_post_hook\n"); /* invoke post-root-mount hook */ if (mountroot_post_hook != NULL) mountroot_post_hook(); #if 0 /* not yet */ consider_zone_gc(FALSE); #endif bsd_init_kprintf("done\n"); }