Date: Thu, 1 Sep 2005 19:09:54 GMT From: soc-tyler <soc-tyler@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82971 for review Message-ID: <200509011909.j81J9skW050533@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82971 Change 82971 by soc-tyler@soc-tyler_launchd on 2005/09/01 19:09:08 Hoorah, at least it's correctly managing jobs now. note: remove "stop" command from launchctl, as it *sucks* Add launch_fork() command to replace functionality of fork_with_bootstrap_port() from launchd/MacOS Affected files ... .. //depot/projects/soc2005/launchd/includes/launch_priv.h#3 edit .. //depot/projects/soc2005/launchd/launchctl/launchctl.c#16 edit .. //depot/projects/soc2005/launchd/launchd.c#18 edit .. //depot/projects/soc2005/launchd/liblaunch.c#15 edit Differences ... ==== //depot/projects/soc2005/launchd/includes/launch_priv.h#3 (text+ko) ==== @@ -23,6 +23,8 @@ #ifndef _LAUNCH_PRIV_H_ #define _LAUNCH_PRIV_H_ +#include <sys/types.h> + #define LAUNCH_KEY_GETUSERENVIRONMENT "GetUserEnvironment" #define LAUNCH_KEY_SETUSERENVIRONMENT "SetUserEnvironment" #define LAUNCH_KEY_UNSETUSERENVIRONMENT "UnsetUserEnvironment" @@ -48,6 +50,11 @@ typedef struct _launch *launch_t; +/* launch_fork() is essentially the replacement for + * fork_with_bootstrap_port() on non-OS X machines. + * (defined in launchd.c) + */ +pid_t launch_fork(void); launch_t launchd_fdopen(int); int launchd_getfd(launch_t); void launchd_close(launch_t); ==== //depot/projects/soc2005/launchd/launchctl/launchctl.c#16 (text+ko) ==== @@ -131,9 +131,9 @@ { "unload", load_and_unload_cmd, "Unload configuration files and/or directories" }, // { "reload", reload_cmd, "Reload configuration files and/or directories" }, { "start", start_stop_remove_cmd, "Start specified job" }, - { "stop", start_stop_remove_cmd, "Stop specified job" }, +// { "stop", start_stop_remove_cmd, "Stop specified job" }, { "submit", submit_cmd, "Submit a job from the command line" }, - { "remove", start_stop_remove_cmd, "Remove specified job" }, + { "remove", start_stop_remove_cmd, "Remove/stop specified job" }, { "list", list_cmd, "List jobs and information about jobs" }, { "setenv", setenv_cmd, "Set an environmental variable in launchd" }, { "unsetenv", unsetenv_cmd, "Unset an environmental variable in launchd" }, ==== //depot/projects/soc2005/launchd/launchd.c#18 (text+ko) ==== @@ -90,7 +90,6 @@ #define LAUNCHD_REWARD_JOB_RUN_TIME 60 #define LAUNCHD_FAILED_EXITS_THRESHOLD 10 #define PID1LAUNCHD_CONF "/etc/launchd.conf" -/* XXX: will we really need a local launchd.conf? */ #define LAUNCHD_CONF ".launchd.conf" #ifdef _BUILD_DARWIN_ @@ -344,37 +343,41 @@ static struct timespec timeout = { 30, 0 }; struct timespec *timeoutp = NULL; - if (getpid() == 1) { + /* if (getpid() == 1) { if (readcfg_pid == 0) init_pre_kevent(); } else { + /* in theory, this will make sure we don't exit if we + * have (a) any more jobs nd (b) open socket connections + * to say, something like, launchctl? ;) + * if (TAILQ_EMPTY(&jobs) && TAILQ_EMPTY(&connections)) { - /* liblaunch will restart launchd if we're needed again */ + /* liblaunch will restart launchd if we're needed again * timeoutp = &timeout; } else if (shutdown_in_progress && total_children == 0) { exit(EXIT_SUCCESS); } } - + */ switch (kevent(mainkq, NULL, 0, &kev, 1, timeoutp)) { - case -1: - syslog(LOG_DEBUG, "kevent(): %m"); - break; - case 1: - (*((kq_callback *)kev.udata))(kev.udata, &kev); - break; - case 0: - /* we exit here if and once we're done processing all jobs - * assigned to us - */ - if (timeoutp) - exit(EXIT_SUCCESS); - else - syslog(LOG_DEBUG, "kevent(): spurious return with infinite timeout"); - break; - default: - syslog(LOG_DEBUG, "unexpected: kevent() returned something != 0, -1 or 1"); - break; + case -1: + syslog(LOG_DEBUG, "kevent(): %m"); + break; + case 1: + (*((kq_callback *)kev.udata))(kev.udata, &kev); + break; + case 0: + /* we exit here if and once we're done processing all jobs + * assigned to us + */ + if (timeoutp) + exit(EXIT_SUCCESS); + else + syslog(LOG_DEBUG, "kevent(): spurious return with infinite timeout"); + break; + default: + syslog(LOG_DEBUG, "unexpected: kevent() returned something != 0, -1 or 1"); + break; } } } @@ -1008,10 +1011,14 @@ if (NULL == resp) resp = launch_data_new_errno(ESRCH); } else if (!strcmp(cmd, LAUNCH_KEY_REMOVEJOB)) { + fprintf(stderr, "**debug** j == %p\n", j); + fprintf(stderr, "**debug** jobs.tqh_first == %p\n", jobs.tqh_first); + fprintf(stderr, "**debug** jobs.tqh_last == %p\n", jobs.tqh_last); TAILQ_FOREACH(j, &jobs, tqe) { if (!strcmp(j->label, launch_data_get_string(data))) { job_remove(j); resp = launch_data_new_errno(0); + break; } } if (NULL == resp) @@ -1661,7 +1668,7 @@ // This function can be found in the vendor source in bootstrap.c switch (c = fork_with_bootstrap_port(launchd_bootstrap_port)) { #else - switch (c = fork()) { + switch (c = launch_fork()) { #endif case -1: job_log_error(j, LOG_ERR, "fork() failed, will try again in one second"); @@ -2529,3 +2536,34 @@ syslog(LOG_DEBUG, "unexpected: kevent() returned something != 0, -1 or 1"); } } + +/* + * launch_fork() effectively replaces the functionality of + * fork_with_bootstrap_port() on non-MacOS boxen + */ +pid_t launch_fork() { + static pthread_mutex_t forklock = PTHREAD_MUTEX_INITIALIZER; + pid_t r; + size_t i; + + fprintf(stderr, "**debug** starting launch_fork()\n"); + + pthread_mutex_lock(&forklock); + + sigprocmask(SIG_BLOCK, &blocked_signals, NULL); + + r = fork(); + + if (r <= 0) { + for (i = 0; i <= NSIG; i++) { + if (sigismember(&blocked_signals, i)) + signal(i, SIG_DFL); + } + } + + sigprocmask(SIG_UNBLOCK, &blocked_signals, NULL); + + pthread_mutex_unlock(&forklock); + + return r; +} ==== //depot/projects/soc2005/launchd/liblaunch.c#15 (text+ko) ==== @@ -965,3 +965,4 @@ return r; } +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509011909.j81J9skW050533>