From owner-p4-projects@FreeBSD.ORG Tue Jul 19 19:29:30 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 78BC316A421; Tue, 19 Jul 2005 19:29:30 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 534B216A41F for ; Tue, 19 Jul 2005 19:29:30 +0000 (GMT) (envelope-from soc-tyler@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id E105843D45 for ; Tue, 19 Jul 2005 19:29:29 +0000 (GMT) (envelope-from soc-tyler@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j6JJTTws078716 for ; Tue, 19 Jul 2005 19:29:29 GMT (envelope-from soc-tyler@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j6JJTTAu078713 for perforce@freebsd.org; Tue, 19 Jul 2005 19:29:29 GMT (envelope-from soc-tyler@freebsd.org) Date: Tue, 19 Jul 2005 19:29:29 GMT Message-Id: <200507191929.j6JJTTAu078713@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to soc-tyler@freebsd.org using -f From: soc-tyler To: Perforce Change Reviews Cc: Subject: PERFORCE change 80544 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Jul 2005 19:29:31 -0000 http://perforce.freebsd.org/chv.cgi?CH=80544 Change 80544 by soc-tyler@soc-tyler_launchd on 2005/07/19 19:28:37 Merge changes from 10.4.1 -> 10.4.2 Affected files ... .. //depot/projects/soc2005/launchd/includes/launch.h#6 edit .. //depot/projects/soc2005/launchd/launchd.8#2 edit .. //depot/projects/soc2005/launchd/launchd.c#6 edit Differences ... ==== //depot/projects/soc2005/launchd/includes/launch.h#6 (text+ko) ==== @@ -137,8 +137,7 @@ #define LAUNCH_JOBSOCKETKEY_SERVICENAME "SockServiceName" #define LAUNCH_JOBSOCKETKEY_FAMILY "SockFamily" #define LAUNCH_JOBSOCKETKEY_PROTOCOL "SockProtocol" -#define LAUNCH_JOBSOCKETKEY_FD "SockFD" -#define LAUNCH_JOBSOCKETKEY_ADDRINFORESULTS "AddrinfoResults" +#define LAUNCH_JOBSOCKETKEY_MULTICASTGROUP "MulticastGroup" typedef struct _launch_data *launch_data_t; ==== //depot/projects/soc2005/launchd/launchd.8#2 (text+ko) ==== @@ -6,6 +6,7 @@ .Nd System wide and per-user daemon/agent manager .Sh SYNOPSIS .Nm +.Op Fl d .Op Fl v .Op Fl s .Op Fl x @@ -31,6 +32,8 @@ is invoked by the kernel to run as the first process on the system and to further bootstrap the rest of the system. .Sh OPTIONS WHEN RUN AS PID 1 .Bl -tag -width -indent +.It Fl d +Daemonize. Useful when passing a command to launchd on the command line. .It Fl v Verbose boot. .It Fl s @@ -40,6 +43,11 @@ .It Fl x Safe mode boot. Instructs the system to boot conservatively. .El +.Sh ENVIRONMENTAL VARIABLES +.Bl -tag -width -indent +.It Pa LAUNCHD_SOCKET +This variable is exported when invoking a command via the launchd command line. It informs launchctl how to find the correct launchd to talk to. +.El .Sh NOTES In Darwin it is preferable to have your daemon launch via launchd instead of modifying .Nm rc ==== //depot/projects/soc2005/launchd/launchd.c#6 (text+ko) ==== @@ -212,6 +212,7 @@ static size_t total_children = 0; static pid_t readcfg_pid = 0; +static pid_t launchd_proper_pid = 0; static bool launchd_inited = false; static bool shutdown_in_progress = false; @@ -553,9 +554,13 @@ goto out_bad; } } + if (chown(ourdir, getuid(), getgid()) == -1) syslog(LOG_WARNING, "chown(\"%s\"): %m", ourdir); + setegid(getgid()); + seteuid(getuid()); + ourdirfd = _fd(open(ourdir, O_RDONLY)); if (ourdirfd == -1) { syslog(LOG_ERR, "open(\"%s\"): %m", ourdir); @@ -588,8 +593,6 @@ syslog(LOG_ERR, "bind(\"thesocket\"): %m"); goto out_bad; } - if (chown(sun.sun_path, getuid(), getgid()) == -1) - syslog(LOG_WARNING, "chown(\"thesocket\"): %m"); if (listen(fd, SOMAXCONN) == -1) { syslog(LOG_ERR, "listen(\"thesocket\"): %m"); @@ -606,6 +609,7 @@ sockdir = strdup(ourdir); sockpath = strdup(sun.sun_path); + launchd_proper_pid = getpid(); atexit(launchd_clean_up); out_bad: @@ -871,7 +875,7 @@ if (-1 == (dcc_r = dir_has_files(thepath))) { job_log_error(j, LOG_ERR, "dir_has_files(\"%s\", ...)", thepath); - } else if (dcc_r > 0) { + } else if (dcc_r > 0 && !shutdown_in_progress) { job_start(j); break; } @@ -1129,7 +1133,7 @@ launch_data_t tmp, resp; const char *label; struct jobcb *j; - bool startnow; + bool startnow, hasprog = false, hasprogargs = false; if ((label = job_get_string(pload, LAUNCH_JOBKEY_LABEL))) { TAILQ_FOREACH(j, &jobs, tqe) { @@ -1142,7 +1146,13 @@ resp = launch_data_new_errno(EINVAL); goto out; } - if (launch_data_dict_lookup(pload, LAUNCH_JOBKEY_PROGRAMARGUMENTS) == NULL) { + + if (launch_data_dict_lookup(pload, LAUNCH_JOBKEY_PROGRAM)) + hasprog = true; + if (launch_data_dict_lookup(pload, LAUNCH_JOBKEY_PROGRAMARGUMENTS)) + hasprogargs = true; + + if (!hasprog && !hasprogargs) { resp = launch_data_new_errno(EINVAL); goto out; } @@ -1197,6 +1207,11 @@ launch_data_t tmp_k; j->start_cal_interval = calloc(1, sizeof(struct tm)); + j->start_cal_interval->tm_min = -1; + j->start_cal_interval->tm_hour = -1; + j->start_cal_interval->tm_mday = -1; + j->start_cal_interval->tm_wday = -1; + j->start_cal_interval->tm_mon = -1; if (LAUNCH_DATA_DICTIONARY == launch_data_get_type(tmp)) { if ((tmp_k = launch_data_dict_lookup(tmp, LAUNCH_JOBKEY_CAL_MINUTE))) @@ -1205,11 +1220,8 @@ j->start_cal_interval->tm_hour = launch_data_get_integer(tmp_k); if ((tmp_k = launch_data_dict_lookup(tmp, LAUNCH_JOBKEY_CAL_DAY))) j->start_cal_interval->tm_mday = launch_data_get_integer(tmp_k); - if ((tmp_k = launch_data_dict_lookup(tmp, LAUNCH_JOBKEY_CAL_WEEKDAY))) { + if ((tmp_k = launch_data_dict_lookup(tmp, LAUNCH_JOBKEY_CAL_WEEKDAY))) j->start_cal_interval->tm_wday = launch_data_get_integer(tmp_k); - if (j->start_cal_interval->tm_wday == 0) - j->start_cal_interval->tm_wday = 7; - } if ((tmp_k = launch_data_dict_lookup(tmp, LAUNCH_JOBKEY_CAL_MONTH))) j->start_cal_interval->tm_mon = launch_data_get_integer(tmp_k); } @@ -1489,15 +1501,15 @@ job_log(j, LOG_WARNING, "failed to checkin"); job_remove(j); return false; + } else if (j->failed_exits >= LAUNCHD_FAILED_EXITS_THRESHOLD) { + job_log(j, LOG_WARNING, "too many failures in succession"); + job_remove(j); + return false; } else if (od || shutdown_in_progress) { if (!od && shutdown_in_progress) job_log(j, LOG_NOTICE, "exited while shutdown is in progress, will not restart unless demand requires it"); job_watch(j); return false; - } else if (j->failed_exits >= LAUNCHD_FAILED_EXITS_THRESHOLD) { - job_log(j, LOG_WARNING, "too many failures in a row for a job that should be alive all the time"); - job_remove(j); - return false; } return true; @@ -1625,6 +1637,7 @@ socketpair(AF_UNIX, SOCK_STREAM, 0, execspair); time(&j->start_time); + #ifdef _BUILD_DARWIN_ // This function can be found in the vendor source in bootstrap.c switch (c = fork_with_bootstrap_port(launchd_bootstrap_port)) { @@ -1692,14 +1705,25 @@ bool inetcompat = job_get_bool(j->ldj, LAUNCH_JOBKEY_INETDCOMPATIBILITY); size_t i, argv_cnt; const char **argv, *file2exec = "/usr/libexec/launchproxy"; + int r; + bool hasprog = false; job_setup_attributes(j); - argv_cnt = launch_data_array_get_count(ldpa); - argv = alloca((argv_cnt + 2) * sizeof(char *)); - for (i = 0; i < argv_cnt; i++) - argv[i + 1] = launch_data_get_string(launch_data_array_get_index(ldpa, i)); - argv[argv_cnt + 1] = NULL; + if (ldpa) { + argv_cnt = launch_data_array_get_count(ldpa); + argv = alloca((argv_cnt + 2) * sizeof(char *)); + for (i = 0; i < argv_cnt; i++) + argv[i + 1] = launch_data_get_string(launch_data_array_get_index(ldpa, i)); + argv[argv_cnt + 1] = NULL; + } else { + argv = alloca(3 * sizeof(char *)); + argv[1] = job_get_string(j->ldj, LAUNCH_JOBKEY_PROGRAM); + argv[2] = NULL; + } + + if (job_get_string(j->ldj, LAUNCH_JOBKEY_PROGRAM)) + hasprog = true; if (inetcompat) { argv[0] = file2exec; @@ -1708,12 +1732,17 @@ file2exec = job_get_file2exec(j->ldj); } - if (-1 == execvp(file2exec, (char *const*)argv)) { - int e = errno; /* errno is a macro that expands, best not to take the address of it */ - write(execfd, &e, sizeof(e)); - job_log_error(j, LOG_ERR, "execvp(\"%s\", ...)", file2exec); + if (hasprog) { + r = execv(file2exec, (char *const*)argv); + } else { + r = execvp(file2exec, (char *const*)argv); + } + + if (-1 == r) { + write(execfd, &errno, sizeof(errno)); + job_log_error(j, LOG_ERR, "execv%s(\"%s\", ...)", hasprog ? "" : "p", file2exec); } - _exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } static void job_setup_attributes(struct jobcb *j) @@ -2354,20 +2383,20 @@ latertm.tm_isdst = -1; - if (j->start_cal_interval->tm_min) + if (-1 != j->start_cal_interval->tm_min) latertm.tm_min = j->start_cal_interval->tm_min; - if (j->start_cal_interval->tm_hour) + if (-1 != j->start_cal_interval->tm_hour) latertm.tm_hour = j->start_cal_interval->tm_hour; otherlatertm = latertm; - if (j->start_cal_interval->tm_mday) + if (-1 != j->start_cal_interval->tm_mday) latertm.tm_mday = j->start_cal_interval->tm_mday; - if (j->start_cal_interval->tm_mon) + if (-1 != j->start_cal_interval->tm_mon) latertm.tm_mon = j->start_cal_interval->tm_mon; /* cron semantics are fun */ - if (j->start_cal_interval->tm_wday) { + if (-1 != j->start_cal_interval->tm_wday) { int delta, realwday = j->start_cal_interval->tm_wday; if (realwday == 7) @@ -2385,9 +2414,9 @@ otherlatertm.tm_mday += delta; else if (delta < 0) otherlatertm.tm_mday += 7 + delta; - else if (otherlatertm.tm_hour < nowtm->tm_hour) + else if (-1 != j->start_cal_interval->tm_hour && otherlatertm.tm_hour <= nowtm->tm_hour) otherlatertm.tm_mday += 7; - else if (otherlatertm.tm_min < nowtm->tm_min) + else if (-1 != j->start_cal_interval->tm_min && otherlatertm.tm_min <= nowtm->tm_min) otherlatertm.tm_hour++; else otherlatertm.tm_min++; @@ -2395,13 +2424,13 @@ otherlater = mktime(&otherlatertm); } - if (latertm.tm_mon < nowtm->tm_mon) { + if (-1 != j->start_cal_interval->tm_mon && latertm.tm_mon <= nowtm->tm_mon) { latertm.tm_year++; - } else if (latertm.tm_mday < nowtm->tm_mday) { + } else if (-1 != j->start_cal_interval->tm_mday && latertm.tm_mday <= nowtm->tm_mday) { latertm.tm_mon++; - } else if (latertm.tm_hour < nowtm->tm_hour) { + } else if (-1 != j->start_cal_interval->tm_hour && latertm.tm_hour <= nowtm->tm_hour) { latertm.tm_mday++; - } else if (latertm.tm_min < nowtm->tm_min) { + } else if (-1 != j->start_cal_interval->tm_min && latertm.tm_min <= nowtm->tm_min) { latertm.tm_hour++; } else { latertm.tm_min++; @@ -2410,7 +2439,7 @@ later = mktime(&latertm); if (otherlater) { - if (j->start_cal_interval->tm_mday) + if (-1 != j->start_cal_interval->tm_mday) later = later < otherlater ? later : otherlater; else later = otherlater;