From owner-p4-projects@FreeBSD.ORG Fri Jul 15 18:11:11 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 AD66716A420; Fri, 15 Jul 2005 18:11:10 +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 86BB516A41C for ; Fri, 15 Jul 2005 18:11:10 +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 3879E43D45 for ; Fri, 15 Jul 2005 18:11:10 +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 j6FIBA3Z018694 for ; Fri, 15 Jul 2005 18:11:10 GMT (envelope-from soc-tyler@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j6FIB9Sm018691 for perforce@freebsd.org; Fri, 15 Jul 2005 18:11:09 GMT (envelope-from soc-tyler@freebsd.org) Date: Fri, 15 Jul 2005 18:11:09 GMT Message-Id: <200507151811.j6FIB9Sm018691@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 80288 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: Fri, 15 Jul 2005 18:11:11 -0000 http://perforce.freebsd.org/chv.cgi?CH=80288 Change 80288 by soc-tyler@soc-tyler_launchd on 2005/07/15 18:10:21 Remove all the build errors regarding launchd.c Inside launch.h check to make sure we're not building on top of Darwin/Mac OS X, if so #define _BUILD_DARWIN_. Using that macro to stub out any Darwin specifics inside of launchd.c (but keeping them around for reference.) In theory, by the time I'm done with porting, it will still be back-portable to Darwin. Affected files ... .. //depot/projects/soc2005/launchd/NOTES#5 edit .. //depot/projects/soc2005/launchd/includes/launch.h#3 edit .. //depot/projects/soc2005/launchd/includes/launchd.h#4 edit .. //depot/projects/soc2005/launchd/launchd.c#4 edit Differences ... ==== //depot/projects/soc2005/launchd/NOTES#5 (text+ko) ==== @@ -18,7 +18,12 @@ fixed to accomodate. - o Regarding init(8) I'm still wondering whether or not it'd be best to take the stock - FreeBSD init(8) code, or the code that zarzycki@ and NeXT have modified for - Mac OS X (and NeXTStep). i.e. Fresh start or hackery begets hackery... - + o The stock source comes with a modified init.c from Mac OS 10.3 and + previously which was derived from the standard BSD init.c some eternity ago. + zarzycki@ simply modified it a bit to fit within the launchd(8) event loop. + Plan on taking the current init.c from the FreeBSD source tree and modifying + it accordingly. + + o FEATURE DROP: + - Xml configuration files (for now, or until I think of a better format) + - LowPriorityIO as a job option. ==== //depot/projects/soc2005/launchd/includes/launch.h#3 (text+ko) ==== @@ -53,7 +53,12 @@ #include #include +/* Keep Mac OS/Darwin specific code in for reference purposes, but don't build it */ +#if defined(__APPLE__) && defined(__MACH__) +#define _BUILD_DARWIN_ +#endif + #define LAUNCH_KEY_SUBMITJOB "SubmitJob" #define LAUNCH_KEY_REMOVEJOB "RemoveJob" #define LAUNCH_KEY_STARTJOB "StartJob" @@ -84,7 +89,10 @@ #define LAUNCH_JOBKEY_PID "PID" #define LAUNCH_JOBKEY_UMASK "Umask" #define LAUNCH_JOBKEY_NICE "Nice" +// FreeBSD's sysctl() interface doesn't allow per-process attributes :/ +#ifdef _BUILD_DARWIN_ #define LAUNCH_JOBKEY_LOWPRIORITYIO "LowPriorityIO" +#endif #define LAUNCH_JOBKEY_SESSIONCREATE "SessionCreate" #define LAUNCH_JOBKEY_SOFTRESOURCELIMITS "SoftResourceLimits" #define LAUNCH_JOBKEY_HARDRESOURCELIMITS "HardResourceLimits" ==== //depot/projects/soc2005/launchd/includes/launchd.h#4 (text+ko) ==== @@ -23,14 +23,13 @@ #ifndef __LAUNCHD_H__ #define __LAUNCHD_H__ +#include #include +#include typedef void (*kq_callback)(void *, struct kevent *); extern kq_callback kqsimple_zombie_reaper; -#ifdef _BUILD_MACOS -extern mach_port_t launchd_bootstrap_port; -#endif extern sigset_t blocked_signals; #ifdef PID1_REAP_ADOPTED_CHILDREN @@ -38,7 +37,6 @@ #endif int kevent_mod(uintptr_t ident, short filter, u_short flags, u_int fflags, intptr_t data, void *udata); -void launchd_SessionCreate(const char *who); void init_boot(bool sflag, bool vflag, bool xflag); void init_pre_kevent(void); @@ -48,9 +46,33 @@ void catatonia(void); void death(void); +#ifdef _BUILD_DARWIN_ +extern mach_port_t launchd_bootstrap_port; +void launchd_SessionCreate(const char *who); +#endif + +#ifndef _BUILD_DARWIN_ // on Darwin-based systems, LOG_LAUNCHD is defined for syslog() -#ifndef _BUILD_MACOS #define LOG_LAUNCHD LOG_DAEMON + +/* on Darwin-based systems, O_EVTONLY helps us track changes to a certain file descriptor + * as outlined here: + * http://developer.apple.com/documentation/Performance/Conceptual/FileSystem/Articles/TrackingChanges.html#//apple_ref/doc/uid/20001993-118158 + * + * on FreeBSD, specifically, EVFILT_VNODE is the closest thing to what we want to do + */ +#define O_EVTONLY EVFILT_VNODE + +/* these are defined in sys/event.h in the Darwin source tree, for now we'll + * define them here (disgusting, but we'll see how it works out. + * + * XXX: this may break something ;) + */ +#define NOTE_SECONDS 0x00000001 /* data is seconds */ +#define NOTE_USECONDS 0x00000002 /* data is microseconds */ +#define NOTE_NSECONDS 0x00000004 /* data is nanoseconds */ +#define NOTE_ABSOLUTE 0x00000008 /* absolute timeout */ #endif + #endif ==== //depot/projects/soc2005/launchd/launchd.c#4 (text+ko) ==== @@ -48,14 +48,16 @@ * @APPLE_LICENSE_HEADER_END@ */ -#ifdef _BUILD_MACOS +#ifdef _BUILD_DARWIN_ #include #include #include + #ifdef EVFILT_MACH_IMPLEMENTED #include #include #endif + #endif #include @@ -100,7 +102,7 @@ #include "launch_priv.h" #include "launchd.h" -#ifdef _BUILD_MACOS +#ifdef _BUILD_DARWIN_ #include "bootstrap_internal.h" #endif @@ -111,7 +113,7 @@ #define LAUNCHD_CONF ".launchd.conf" #define LAUNCHCTL_PATH "/sbin/launchctl" -#ifdef _BUILD_MACOS +#ifdef _BUILD_DARWIN_ #define SECURITY_LIB "/System/Library/Frameworks/Security.framework/Versions/A/Security" #define VOLFSDIR "/.vol" #endif @@ -198,17 +200,10 @@ static void launchd_server_init(bool create_session); static void conceive_firstborn(char *argv[]); -#ifdef EVFILT_MACH_IMPLEMENTED -static void *mach_demand_loop(void *); -static void mach_callback(void *, struct kevent *); -static kq_callback kqmach_callback = mach_callback; -#endif - static void usage(FILE *where); static int _fd(int fd); static void loopback_setup(void); -static void workaround3048875(int argc, char *argv[]); static void reload_launchd_config(void); static int dir_has_files(const char *path); static void setup_job_env(launch_data_t obj, const char *key, void *context); @@ -222,7 +217,17 @@ sigset_t blocked_signals; -#ifdef _BUILD_MACOS +#ifdef _BUILD_DARWIN_ + +#ifdef EVFILT_MACH_IMPLEMENTED +static void *mach_demand_loop(void *); +static void mach_callback(void *, struct kevent *); +static kq_callback kqmach_callback = mach_callback; +#endif + +// workaround for an OpenFirmware and Xnu bug, only on Darwin though ;) +static void workaround3048875(int argc, char *argv[]); + static pthread_t mach_server_loop_thread; mach_port_t launchd_bootstrap_port = MACH_PORT_NULL; blocked_signals = 0; @@ -256,8 +261,11 @@ bool sflag = false, xflag = false, vflag = false, dflag = false; int ch; +// workaround for that nasty OpenFirmware bug, zoinks! +#ifdef _BUILD_DARWIN_ if (getpid() == 1) workaround3048875(argc, argv); +#endif setegid(getgid()); seteuid(getuid()); @@ -319,7 +327,7 @@ if (getpid() == 1) { pid1_magic_init(sflag, vflag, xflag); } else { -#ifdef _BUILD_MACOS +#ifdef _BUILD_DARWIN_ launchd_bootstrap_port = bootstrap_port; #endif launchd_server_init(argv[0] ? true : false); @@ -383,8 +391,10 @@ uint64_t mem = 0; uint32_t mvn; size_t memsz = sizeof(mem); +#ifdef _BUILD_DARWIN_ int pthr_r; - +#endif + setpriority(PRIO_PROCESS, 0, -1); if (setsid() == -1) @@ -426,7 +436,7 @@ syslog(LOG_ERR, "mount(\"%s\", \"%s\", ...): %m", "fdesc", "/dev/"); setenv("PATH", _PATH_STDPATH, 1); -#ifdef _BUILD_MACOS +#ifdef _BUILD_DARWIN_ launchd_bootstrap_port = mach_init_init(); task_set_bootstrap_port(mach_task_self(), launchd_bootstrap_port); bootstrap_port = MACH_PORT_NULL; @@ -434,7 +444,7 @@ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -#ifdef _BUILD_MACOS +#ifdef _BUILD_DARWIN_ pthr_r = pthread_create(&mach_server_loop_thread, &attr, mach_server_loop, NULL); if (pthr_r != 0) { syslog(LOG_ERR, "pthread_create(mach_server_loop): %s", strerror(pthr_r)); @@ -1616,8 +1626,12 @@ 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)) { +#else + switch (c = fork()) { +#endif case -1: job_log_error(j, LOG_ERR, "fork() failed, will try again in one second"); close(execspair[0]); @@ -1707,7 +1721,9 @@ { launch_data_t srl = launch_data_dict_lookup(j->ldj, LAUNCH_JOBKEY_SOFTRESOURCELIMITS); launch_data_t hrl = launch_data_dict_lookup(j->ldj, LAUNCH_JOBKEY_HARDRESOURCELIMITS); +#ifdef _BUILD_DARWIN_ bool inetcompat = job_get_bool(j->ldj, LAUNCH_JOBKEY_INETDCOMPATIBILITY); +#endif launch_data_t tmp; size_t i; const char *tmpstr; @@ -1749,9 +1765,12 @@ } } +#ifdef _BUILD_DARWIN_ if (!inetcompat && job_get_bool(j->ldj, LAUNCH_JOBKEY_SESSIONCREATE)) launchd_SessionCreate(job_get_file2exec(j->ldj)); + // sysctl(2) in FreeBSD doesn't have a comprable option for changing the + // I/O priority on a specific process :-/ if (job_get_bool(j->ldj, LAUNCH_JOBKEY_LOWPRIORITYIO)) { int lowprimib[] = { CTL_KERN, KERN_PROC_LOW_PRI_IO }; int val = 1; @@ -1759,6 +1778,8 @@ if (sysctl(lowprimib, sizeof(lowprimib) / sizeof(lowprimib[0]), NULL, NULL, &val, sizeof(val)) == -1) job_log_error(j, LOG_WARNING, "sysctl(\"%s\")", "kern.proc_low_pri_io"); } +#endif + if ((tmpstr = job_get_string(j->ldj, LAUNCH_JOBKEY_ROOTDIRECTORY))) { chroot(tmpstr); chdir("."); @@ -1861,7 +1882,10 @@ if (getpid() == 1) { catatonia(); +#ifdef _BUILD_DARWIN_ + /* defined in bootstrap.h for building on Mac OS 10.xx systems */ mach_start_shutdown(SIGTERM); +#endif } } @@ -1913,6 +1937,7 @@ } } +#ifdef _BUILD_DARWIN_ if (!mounted_volfs) { int r = mount("volfs", VOLFSDIR, MNT_RDONLY, NULL); @@ -1927,6 +1952,7 @@ mounted_volfs = true; } } +#endif if (!launchd_inited) launchd_server_init(false); @@ -2047,7 +2073,11 @@ if (lstat(ldconf, &sb) == 0) { int spair[2]; socketpair(AF_UNIX, SOCK_STREAM, 0, spair); +#ifdef _BUILD_DARWIN_ readcfg_pid = fork_with_bootstrap_port(launchd_bootstrap_port); +#else + readcfg_pid = fork(); +#endif if (readcfg_pid == 0) { char nbuf[100]; close(spair[0]); @@ -2165,7 +2195,11 @@ close(s); close(s6); } - +/* + * This workaround fixes a bug or two cause because the Xnu kernel wasn't + * passing boot-args from OFW to PID 1 correctly, yikes! + */ +#ifdef _BUILD_DARWIN_ static void workaround3048875(int argc, char *argv[]) { int i; @@ -2189,6 +2223,7 @@ execv(newargv[0], newargv); } +#endif static launch_data_t adjust_rlimits(launch_data_t in) { @@ -2257,9 +2292,13 @@ } /* - * XXX: I'm not exactly sure what this function's exact purpose is. + * I believe this function opens an interface to the Security.framework which + * allows verification against keychains, etc. + * http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/security.1.html + * + * This is here because of the securityd team at Apple Inc.....i.e. we don't really need it ;) */ -#ifdef _BUILD_MACOS +#ifdef _BUILD_DARWIN_ __private_extern__ void launchd_SessionCreate(const char *who) { void *seclib = dlopen(SECURITY_LIB, RTLD_LAZY);