Compare commits
	
		
			20 Commits
		
	
	
		
			openrc-0.1
			...
			funtoo-ope
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 67b2255ebb | ||
|   | 6eace7dc5a | ||
|   | 11e1f4d30d | ||
|   | c30a8d2c3c | ||
|   | 419af8f0aa | ||
|   | 9e989227ab | ||
|   | d6436bed09 | ||
|   | 4480f1f395 | ||
|   | 0ba14ae720 | ||
|   | 7716bf31de | ||
|   | 445b297360 | ||
|   | 2590bf7a2b | ||
|   | 4ce3cb90a0 | ||
|   | a78b18e291 | ||
|   | 72b58b9e6b | ||
|   | 5c3e5d801b | ||
|   | bb8a9c087d | ||
|   | d1b183a2f9 | ||
|   | 7296379f3f | ||
|   | 1f5d447eda | 
| @@ -1,3 +1,3 @@ | ||||
| NAME=		openrc | ||||
| VERSION=	0.12 | ||||
| VERSION=	0.13 | ||||
| PKG=		${NAME}-${VERSION} | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # Set to the hostname of this machine | ||||
| # Set to the fully-qualified hostname of this machine | ||||
| hostname="localhost" | ||||
|   | ||||
							
								
								
									
										3
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -4,8 +4,6 @@ hostname | ||||
| local | ||||
| localmount | ||||
| moused | ||||
| net.lo | ||||
| net.lo0 | ||||
| netmount | ||||
| network | ||||
| root | ||||
| @@ -41,4 +39,5 @@ syslogd | ||||
| termencoding | ||||
| ttys | ||||
| wscons | ||||
| tmpfiles.dev | ||||
| tmpfiles.setup | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| include ../mk/net.mk | ||||
|  | ||||
| DIR=	${INITDIR} | ||||
| SRCS=	bootmisc.in fsck.in hostname.in local.in localmount.in loopback.in \ | ||||
| SRCS=	bootmisc.in fsck.in hostname.in local.in localmount.in \ | ||||
| 	netmount.in root.in savecache.in swap.in swapfiles.in \ | ||||
| 	tmpfiles.setup.in swclock.in sysctl.in urandom.in ${SRCS-${OS}} | ||||
| BIN=	${OBJS} | ||||
|   | ||||
| @@ -1,18 +1,42 @@ | ||||
| #!@SBINDIR@/runscript | ||||
| #!@PREFIX@/sbin/runscript | ||||
| # Copyright (c) 2007-2009 Roy Marples <roy@marples.name> | ||||
| # Released under the 2-clause BSD license. | ||||
|  | ||||
| description="Sets the hostname of the machine." | ||||
|  | ||||
| depend() { | ||||
| 	keyword -prefix -lxc | ||||
| 	need root | ||||
| } | ||||
|  | ||||
| start() | ||||
| { | ||||
| 	# HOSTNAME variable used to be defined in caps in conf.d/hostname. | ||||
| 	# It is also a magic variable in bash. | ||||
| 	hostname=${hostname-${HOSTNAME-localhost}} # checkbashisms: false positive | ||||
| 	hostname=${hostname-${HOSTNAME-localhost}} | ||||
| 	out=$hostname | ||||
| 	short=${hostname%%.*} | ||||
| 	if [ "$short" != "$hostname" ]; then | ||||
| 		out="$out $short" | ||||
| 	fi | ||||
| 	if [ "$nisdomainname" != "" ]; then | ||||
| 		ebegin "Setting NIS domain name to $nisdomainname" | ||||
| 		nisdomainname $nisdomainname | ||||
| 		eend $? "Failed to set the NIS domain name" | ||||
| 	fi | ||||
| 	if [ "$short" != "localhost" ]; then | ||||
| 		out="$out localhost" | ||||
| 	fi | ||||
| 	if [ "$hostname" != "localhost.localdomain" ]; then | ||||
| 		out="$out localhost.localdomain" | ||||
| 	fi | ||||
| 	[ -n "$aliases" ] && out="$out $aliases" | ||||
| 	ebegin "Configuring /etc/hosts" | ||||
| 	[ -e /etc/hosts ] && sed -i -e '/[[:space:]]*127.0.0.1[[:space:]]/d' -e '/[[:space:]]*::1[[:space:]]/d' /etc/hosts | ||||
| 	cat <<END >> /etc/hosts | ||||
| 127.0.0.1	$out | ||||
| ::1		$out | ||||
| END | ||||
| 	chmod 0644 /etc/hosts | ||||
| 	eend $? | ||||
| 	[ "$RC_SYS" = "LXC" ] && return 0 | ||||
| 	ebegin "Setting hostname to $hostname" | ||||
| 	hostname "$hostname" | ||||
| 	eend $? "Failed to set the hostname" | ||||
|   | ||||
| @@ -9,7 +9,7 @@ depend() | ||||
| 	need fsck | ||||
| 	use lvm modules mtab | ||||
| 	after lvm modules | ||||
| 	keyword -jail -openvz -prefix -vserver -lxc | ||||
| 	keyword -jail -prefix -vserver -lxc | ||||
| } | ||||
|  | ||||
| start() | ||||
|   | ||||
| @@ -1,35 +0,0 @@ | ||||
| #!@SBINDIR@/runscript | ||||
| # Copyright (c) 2013 William Hubbs <w.d.hubbs@gmail.com> | ||||
| # Released under the 2-clause BSD license. | ||||
|  | ||||
| description="Configures the loopback interface." | ||||
|  | ||||
| depend() | ||||
| { | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| start() | ||||
| { | ||||
| 	if [ "$RC_UNAME" = Linux ]; then | ||||
| 		ebegin "Bringing up network interface lo" | ||||
| 		if type ip > /dev/null 2>&1; then | ||||
| 			ip addr add 127.0.0.1/8 dev lo brd + scope host | ||||
| 			ip route add 127.0.0.0/8 dev lo scope host | ||||
| 			ip link set lo up | ||||
| 		else | ||||
| 			ifconfig lo 127.0.0.1 netmask 255.0.0.0 | ||||
| 			route add -net 127.0.0.0 netmask 255.0.0.0 gw 127.0.0.1 | ||||
| 		fi | ||||
| 	else | ||||
| 		ebegin "Bringing up network interface lo0" | ||||
| 		ifconfig lo0 127.0.0.1 netmask 255.0.0.0 | ||||
| 		route -q add -inet 127.0.0.0 -netmask 255.0.0.0 127.0.0.1 | ||||
| 	fi | ||||
| 	eend $? | ||||
| } | ||||
|  | ||||
| stop() | ||||
| { | ||||
| 	return 0 | ||||
| } | ||||
| @@ -1,11 +1,11 @@ | ||||
| #!@SBINDIR@/runscript | ||||
| #!@PREFIX@/sbin/runscript | ||||
| # Copyright (c) 2007-2008 Roy Marples <roy@marples.name> | ||||
| # Released under the 2-clause BSD license. | ||||
|  | ||||
| depend() | ||||
| { | ||||
| 	before bootmisc logger | ||||
| 	keyword -lxc -prefix -vserver | ||||
| 	keyword -lxc -vserver | ||||
| } | ||||
|  | ||||
| start() | ||||
| @@ -15,6 +15,14 @@ start() | ||||
| 	ebegin "Configuring kernel parameters" | ||||
| 	eindent | ||||
|  | ||||
| 	# default sysctl System V max shared memory to 1/4 of RAM: | ||||
| 	mem_bytes=`awk '/MemTotal:/ { printf "%0.f",$2 * 1024}' /proc/meminfo` | ||||
| 	mem_max=`expr $mem_bytes / 4` | ||||
| 	page_size=`getconf PAGE_SIZE` | ||||
| 	shmall=`expr $mem_bytes / $page_size` | ||||
| 	sysctl kernel.shmmax=$mem_max > /dev/null | ||||
| 	sysctl kernel.shmall=$shmall > /dev/null | ||||
|  | ||||
| 	for conf in @SYSCONFDIR@/sysctl.conf @SYSCONFDIR@/sysctl.d/*.conf; do | ||||
| 		if [ -r "$conf" ]; then | ||||
| 			vebegin "applying $conf" | ||||
|   | ||||
| @@ -105,7 +105,8 @@ and | ||||
| respectively, but only work when | ||||
| .Va EINFO_VERBOSE | ||||
| is true. You can also make the | ||||
| .Fn einfo | ||||
| .Fn einfo , | ||||
| .Fn ewarn , | ||||
| and | ||||
| .Fn ebegin | ||||
| functions silent by setting | ||||
| @@ -184,6 +185,12 @@ when set to true makes the | ||||
| and | ||||
| .Fn einfon | ||||
| family of functions quiet, so nothing is printed. | ||||
| .Va EERROR_QUIET | ||||
| when set to true makes the | ||||
| .Fn eerror | ||||
| and | ||||
| .Fn eerrorn | ||||
| family of functions quiet, so nothing is printed. | ||||
| .Pp | ||||
| .Va EINFO_VERBOSE | ||||
| when set to true makes the | ||||
|   | ||||
| @@ -60,12 +60,12 @@ First we ensure that any services that depend on us are stopped. If any | ||||
| services that need us fail to stop then we exit with a suitable error, | ||||
| otherwise call the supplied stop function if it exists. | ||||
| .It Ar restart | ||||
| Stop and start the service, including dependencies. This cannot be | ||||
| Stops and starts the service, including dependencies. This cannot be | ||||
| overridden. See the description of the RC_CMD variable below for the | ||||
| method to make your service behave differently when restart is being | ||||
| executed. | ||||
| .It Ar status | ||||
| Show the status of the service. The return code matches the status, with the | ||||
| Shows the status of the service. The return code matches the status, with the | ||||
| exception of "started" returning 0 to match standard command behaviour. | ||||
| .It Ar zap | ||||
| Resets the service state to stopped and removes all saved data about the | ||||
| @@ -88,8 +88,8 @@ Output from any non OpenRC commands is not affected. | ||||
| .It Fl v , -verbose | ||||
| Turns on any extra informational output the service generates. | ||||
| .It Fl Z , -dry-run | ||||
| Shows what services would be stopped and/or started without actually starting | ||||
| or stopping them. | ||||
| Shows which services would be stopped and/or started without actually stopping | ||||
| or starting them. | ||||
| .El | ||||
| .Pp | ||||
| The following variables affect the service script: | ||||
| @@ -471,7 +471,7 @@ start_pre() | ||||
| 		# stop_post. | ||||
| 	fi | ||||
|     # Ensure that our dirs are correct | ||||
|     checkpath --dir --owner foo:foo --mode 0664 \\ | ||||
|     checkpath --directory --owner foo:foo --mode 0775 \\ | ||||
| 	/var/run/foo /var/cache/foo | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| include ../mk/net.mk | ||||
|  | ||||
| BOOT=		bootmisc fsck hostname localmount loopback \ | ||||
| BOOT=		bootmisc fsck hostname localmount \ | ||||
| 		root swap swapfiles sysctl urandom ${BOOT-${OS}} | ||||
| DEFAULT=	local netmount | ||||
| SHUTDOWN=	savecache ${SHUTDOWN-${OS}} | ||||
|   | ||||
| @@ -273,6 +273,12 @@ is_quiet(void) | ||||
| 	return yesno(getenv("EINFO_QUIET")); | ||||
| } | ||||
|  | ||||
| static bool | ||||
| is_really_quiet(void) | ||||
| { | ||||
| 	return yesno(getenv("EERROR_QUIET")); | ||||
| } | ||||
|  | ||||
| static bool | ||||
| is_verbose(void) | ||||
| { | ||||
| @@ -674,6 +680,8 @@ eerrorn(const char *EINFO_RESTRICT fmt, ...) | ||||
| 	int retval; | ||||
| 	va_list ap; | ||||
|  | ||||
| 	if (!fmt || is_really_quiet()) | ||||
| 		return 0; | ||||
| 	va_start(ap, fmt); | ||||
| 	retval = _eerrorvn(fmt, ap); | ||||
| 	va_end(ap); | ||||
| @@ -705,7 +713,7 @@ ewarn(const char *EINFO_RESTRICT fmt, ...) | ||||
| 	int retval; | ||||
| 	va_list ap; | ||||
|  | ||||
| 	if (!fmt) | ||||
| 	if (!fmt || is_quiet()) | ||||
| 		return 0; | ||||
| 	va_start(ap, fmt); | ||||
| 	elogv(LOG_WARNING, fmt, ap); | ||||
| @@ -740,7 +748,7 @@ eerror(const char *EINFO_RESTRICT fmt, ...) | ||||
| 	int retval; | ||||
| 	va_list ap; | ||||
|  | ||||
| 	if (!fmt) | ||||
| 	if (!fmt || is_really_quiet()) | ||||
| 		return 0; | ||||
| 	va_start(ap, fmt); | ||||
| 	elogv(LOG_ERR, fmt, ap); | ||||
| @@ -757,7 +765,7 @@ eerrorx(const char *EINFO_RESTRICT fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
|  | ||||
| 	if (fmt) { | ||||
| 	if (fmt && !is_really_quiet()) { | ||||
| 		va_start(ap, fmt); | ||||
| 		elogv(LOG_ERR, fmt, ap); | ||||
| 		_eerrorvn(fmt, ap); | ||||
|   | ||||
| @@ -323,6 +323,42 @@ rc_parse_service_state(RC_SERVICE state) | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| /* Returns a list of all the chained runlevels used by the | ||||
|  * specified runlevel in dependency order, including the | ||||
|  * specified runlevel. */ | ||||
| static void | ||||
| get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list) | ||||
| { | ||||
| 	char path[PATH_MAX]; | ||||
| 	RC_STRINGLIST *dirs; | ||||
| 	RC_STRING *d, *dn; | ||||
|  | ||||
| 	/* | ||||
| 	 * If we haven't been passed a runlevel or a level list, or | ||||
| 	 * if the passed runlevel doesn't exist then we're done already! | ||||
| 	 */ | ||||
| 	if (!runlevel || !level_list || !rc_runlevel_exists(runlevel)) | ||||
| 		return; | ||||
|  | ||||
| 	/* | ||||
| 	 * We want to add this runlevel to the list but if | ||||
| 	 * it is already in the list it needs to go at the | ||||
| 	 * end again. | ||||
| 	 */ | ||||
| 	if (rc_stringlist_find(level_list, runlevel)) | ||||
| 		rc_stringlist_delete(level_list, runlevel); | ||||
| 	rc_stringlist_add(level_list, runlevel); | ||||
|  | ||||
| 	/* | ||||
| 	 * We can now do exactly the above procedure for our chained | ||||
| 	 * runlevels. | ||||
| 	 */ | ||||
| 	snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel); | ||||
| 	dirs = ls_dir(path, LS_DIR); | ||||
| 	TAILQ_FOREACH_SAFE(d, dirs, entries, dn) | ||||
| 		get_runlevel_chain(d->value, level_list); | ||||
| } | ||||
|  | ||||
| bool | ||||
| rc_runlevel_starting(void) | ||||
| { | ||||
| @@ -424,22 +460,10 @@ librc_hidden_def(rc_runlevel_unstack) | ||||
| RC_STRINGLIST * | ||||
| rc_runlevel_stacks(const char *runlevel) | ||||
| { | ||||
| 	char path[PATH_MAX]; | ||||
| 	RC_STRINGLIST *dirs; | ||||
| 	RC_STRING *d, *dn; | ||||
|  | ||||
| 	if (!runlevel) | ||||
| 		return false; | ||||
| 	snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel); | ||||
| 	dirs = ls_dir(path, LS_DIR); | ||||
| 	TAILQ_FOREACH_SAFE(d, dirs, entries, dn) { | ||||
| 		if (!rc_runlevel_exists(d->value)) { | ||||
| 			TAILQ_REMOVE(dirs, d, entries); | ||||
| 			free(d->value); | ||||
| 			free(d); | ||||
| 		} | ||||
| 	} | ||||
| 	return dirs; | ||||
| 	RC_STRINGLIST *stack; | ||||
| 	stack = rc_stringlist_new(); | ||||
| 	get_runlevel_chain(runlevel, stack); | ||||
| 	return stack; | ||||
| } | ||||
| librc_hidden_def(rc_runlevel_stacks) | ||||
|  | ||||
| @@ -903,17 +927,13 @@ rc_services_in_runlevel_stacked(const char *runlevel) | ||||
| 	stacks = rc_runlevel_stacks(runlevel); | ||||
| 	TAILQ_FOREACH(stack, stacks, entries) { | ||||
| 		sl = rc_services_in_runlevel(stack->value); | ||||
| 		if (list != NULL) { | ||||
| 		TAILQ_CONCAT(list, sl, entries); | ||||
| 		free(sl); | ||||
| 		} else | ||||
| 			list = sl; | ||||
| 	} | ||||
| 	return list; | ||||
| } | ||||
| librc_hidden_def(rc_services_in_runlevel_stacked) | ||||
|  | ||||
|  | ||||
| RC_STRINGLIST * | ||||
| rc_services_in_state(RC_SERVICE state) | ||||
| { | ||||
|   | ||||
							
								
								
									
										1
									
								
								src/rc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/rc/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -3,6 +3,7 @@ rc-status | ||||
| rc-service | ||||
| rc-update | ||||
| runscript | ||||
| service | ||||
| start-stop-daemon | ||||
| einfon | ||||
| einfo | ||||
|   | ||||
| @@ -35,6 +35,21 @@ | ||||
| #  define _noreturn | ||||
| #endif | ||||
|  | ||||
| static void set_quiet_options(void) | ||||
| { | ||||
| 	static int qcount = 0; | ||||
|  | ||||
| 	qcount ++; | ||||
| 	switch (qcount) { | ||||
| 	case 1: | ||||
| 		setenv ("EINFO_QUIET", "YES", 1); | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		setenv ("EERROR_QUIET", "YES", 1); | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| _noreturn static void | ||||
| show_version(void) | ||||
| { | ||||
|   | ||||
| @@ -38,13 +38,13 @@ | ||||
| 	"Disable color output",						      \ | ||||
| 	"Display software version",			              \ | ||||
| 	"Run verbosely",						      \ | ||||
| 	"Run quietly (Does not affect errors)" | ||||
| 	"Run quietly (repeat to suppress errors)" | ||||
|  | ||||
| #define case_RC_COMMON_getopt_case_C  setenv ("EINFO_COLOR", "NO", 1); | ||||
| #define case_RC_COMMON_getopt_case_h  usage (EXIT_SUCCESS); | ||||
| #define case_RC_COMMON_getopt_case_V  if (argc == 2) show_version(); | ||||
| #define case_RC_COMMON_getopt_case_v  setenv ("EINFO_VERBOSE", "YES", 1); | ||||
| #define case_RC_COMMON_getopt_case_q  setenv ("EINFO_QUIET", "YES", 1); | ||||
| #define case_RC_COMMON_getopt_case_q  set_quiet_options(); | ||||
| #define case_RC_COMMON_getopt_default usage (EXIT_FAILURE); | ||||
|  | ||||
| #define case_RC_COMMON_GETOPT						      \ | ||||
|   | ||||
| @@ -171,6 +171,26 @@ print_services(const char *runlevel, RC_STRINGLIST *svcs) | ||||
| 	rc_stringlist_free(l); | ||||
| } | ||||
|  | ||||
| static void | ||||
| print_stacked_services(const char *runlevel) | ||||
| { | ||||
| 	RC_STRINGLIST *stackedlevels, *servicelist; | ||||
| 	RC_STRING *stackedlevel; | ||||
|  | ||||
| 	stackedlevels = rc_runlevel_stacks(runlevel); | ||||
| 	TAILQ_FOREACH(stackedlevel, stackedlevels, entries) { | ||||
| 		if (rc_stringlist_find(levels, stackedlevel->value) != NULL) | ||||
| 			continue; | ||||
| 		print_level("Stacked", stackedlevel->value); | ||||
| 		servicelist = rc_services_in_runlevel(stackedlevel->value); | ||||
| 		print_services(stackedlevel->value, servicelist); | ||||
| 		rc_stringlist_free(servicelist); | ||||
| 		print_stacked_services(stackedlevel->value); | ||||
| 	} | ||||
| 	rc_stringlist_free(stackedlevels); | ||||
| 	stackedlevels = NULL; | ||||
| } | ||||
|  | ||||
| #include "_usage.h" | ||||
| #define usagestring ""						\ | ||||
| 	"Usage: rc-status [options] <runlevel>...\n"		\ | ||||
| @@ -199,7 +219,8 @@ static const char * const longopts_help[] = { | ||||
| int | ||||
| rc_status(int argc, char **argv) | ||||
| { | ||||
| 	RC_STRING *s, *l, *t; | ||||
|     RC_STRING *s, *l, *t, *level; | ||||
|  | ||||
| 	char *p, *runlevel = NULL; | ||||
| 	int opt, aflag = 0, retval = 0; | ||||
|  | ||||
| @@ -280,16 +301,7 @@ rc_status(int argc, char **argv) | ||||
| 		print_level(NULL, l->value); | ||||
| 		services = rc_services_in_runlevel(l->value); | ||||
| 		print_services(l->value, services); | ||||
| 		nservices = rc_runlevel_stacks(l->value); | ||||
| 		TAILQ_FOREACH(s, nservices, entries) { | ||||
| 			if (rc_stringlist_find(levels, s->value) != NULL) | ||||
| 				continue; | ||||
| 			print_level("Stacked", s->value); | ||||
| 			sservices = rc_services_in_runlevel(s->value); | ||||
| 			print_services(s->value, sservices); | ||||
| 			rc_stringlist_free(sservices); | ||||
| 		} | ||||
| 		sservices = NULL; | ||||
| 		print_stacked_services(l->value); | ||||
| 		rc_stringlist_free(nservices); | ||||
| 		nservices = NULL; | ||||
| 		rc_stringlist_free(services); | ||||
| @@ -317,15 +329,13 @@ rc_status(int argc, char **argv) | ||||
| 		services = rc_services_in_runlevel(NULL); | ||||
| 		sservices = rc_stringlist_new(); | ||||
| 		TAILQ_FOREACH(l, levels, entries) { | ||||
| 			nservices = rc_services_in_runlevel(l->value); | ||||
| 			nservices = rc_services_in_runlevel_stacked(l->value); | ||||
| 			TAILQ_CONCAT(sservices, nservices, entries); | ||||
| 			free(nservices); | ||||
| 		} | ||||
| 		TAILQ_FOREACH_SAFE(s, services, entries, t) { | ||||
| 			if (rc_stringlist_find(sservices, s->value) || | ||||
| 			    rc_service_state(s->value) & | ||||
| 			    (RC_SERVICE_STOPPED | RC_SERVICE_HOTPLUGGED)) | ||||
| 		{ | ||||
| 			if ((rc_stringlist_find(sservices, s->value) || | ||||
| 			    (rc_service_state(s->value) & ( RC_SERVICE_STOPPED | RC_SERVICE_HOTPLUGGED)))) { | ||||
| 				TAILQ_REMOVE(services, s, entries); | ||||
| 				free(s->value); | ||||
| 				free(s); | ||||
| @@ -337,22 +347,23 @@ rc_status(int argc, char **argv) | ||||
| 		alist = rc_stringlist_new(); | ||||
| 		l = rc_stringlist_add(alist, ""); | ||||
| 		p = l->value; | ||||
| 		if (!runlevel) | ||||
| 			runlevel = rc_runlevel_get(); | ||||
| 		TAILQ_FOREACH(level, levels, entries) { | ||||
| 			TAILQ_FOREACH_SAFE(s, services, entries, t) { | ||||
| 				l->value = s->value; | ||||
| 			unsetenv("RC_SVCNAME"); | ||||
| 				setenv("RC_SVCNAME", l->value, 1); | ||||
| 			tmp = rc_deptree_depends(deptree, needsme, alist, runlevel, RC_DEP_TRACE); | ||||
| 				tmp = rc_deptree_depends(deptree, needsme, alist, level->value, RC_DEP_TRACE); | ||||
| 				if (TAILQ_FIRST(tmp)) { | ||||
| 					TAILQ_REMOVE(services, s, entries); | ||||
| 					TAILQ_INSERT_TAIL(nservices, s, entries); | ||||
| 				} | ||||
| 				rc_stringlist_free(tmp); | ||||
| 			} | ||||
| 		} | ||||
| 		l->value = p; | ||||
| 		/* we are unsetting RC_SVCNAME because last loaded service  | ||||
| 		   wount be added to list */ | ||||
| 		/* | ||||
| 		 * we are unsetting RC_SVCNAME because last loaded service will not | ||||
| 		 * be added to the list | ||||
| 		 */ | ||||
| 		unsetenv("RC_SVCNAME"); | ||||
| 		print_level("Dynamic", "needed"); | ||||
| 		print_services(NULL, nservices); | ||||
|   | ||||
							
								
								
									
										88
									
								
								src/rc/rc.c
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								src/rc/rc.c
									
									
									
									
									
								
							| @@ -79,12 +79,6 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples"; | ||||
|  | ||||
| const char *applet = NULL; | ||||
| static char *runlevel; | ||||
| static RC_STRINGLIST *hotplugged_services; | ||||
| static RC_STRINGLIST *stop_services; | ||||
| static RC_STRINGLIST *start_services; | ||||
| static RC_STRINGLIST *types_n; | ||||
| static RC_STRINGLIST *types_nua; | ||||
| static RC_DEPTREE *deptree; | ||||
| static RC_HOOK hook_out; | ||||
|  | ||||
| struct termios *termios_orig = NULL; | ||||
| @@ -524,7 +518,9 @@ runlevel_config(const char *service, const char *level) | ||||
| } | ||||
|  | ||||
| static void | ||||
| do_stop_services(const char *newlevel, bool parallel, bool going_down) | ||||
| do_stop_services(const RC_STRINGLIST *types_n, const RC_STRINGLIST *start_services, | ||||
| 				 const RC_STRINGLIST *stop_services, const RC_DEPTREE *deptree, | ||||
| 				 const char *newlevel, bool parallel, bool going_down) | ||||
| { | ||||
| 	pid_t pid; | ||||
| 	RC_STRING *service, *svc1, *svc2; | ||||
| @@ -627,7 +623,7 @@ stop: | ||||
| } | ||||
|  | ||||
| static void | ||||
| do_start_services(bool parallel) | ||||
| do_start_services(const RC_STRINGLIST *start_services, bool parallel) | ||||
| { | ||||
| 	RC_STRING *service; | ||||
| 	pid_t pid; | ||||
| @@ -754,6 +750,12 @@ main(int argc, char **argv) | ||||
| { | ||||
| 	const char *bootlevel = NULL; | ||||
| 	char *newlevel = NULL; | ||||
| 	static RC_STRINGLIST *hotplugged_services; | ||||
| 	static RC_STRINGLIST *stop_services; | ||||
| 	static RC_STRINGLIST *start_services; | ||||
| 	static RC_STRINGLIST *types_n; | ||||
| 	static RC_STRINGLIST *types_nua; | ||||
| 	static RC_DEPTREE *deptree; | ||||
| 	RC_STRINGLIST *deporder = NULL; | ||||
| 	RC_STRINGLIST *tmplist; | ||||
| 	RC_STRING *service; | ||||
| @@ -868,7 +870,11 @@ main(int argc, char **argv) | ||||
| 	snprintf(pidstr, sizeof(pidstr), "%d", getpid()); | ||||
| 	setenv("RC_PID", pidstr, 1); | ||||
|  | ||||
| 	/* Load current runlevel */ | ||||
| 	/* Create a list of all services which should be started for the new or | ||||
| 	* current runlevel including those in boot, sysinit and hotplugged | ||||
| 	* runlevels.  Clearly, some of these will already be started so we | ||||
| 	* won't actually be starting them all. | ||||
| 	*/ | ||||
| 	bootlevel = getenv("RC_BOOTLEVEL"); | ||||
| 	runlevel = rc_runlevel_get(); | ||||
|  | ||||
| @@ -972,8 +978,13 @@ main(int argc, char **argv) | ||||
| 		    applet, RC_STOPPING, strerror(errno)); | ||||
| 	} | ||||
|  | ||||
| 	/* Build a list of all services to stop and then work out the | ||||
| 	 * correct order for stopping them */ | ||||
| 	/* Create a list of all services which we could stop (assuming | ||||
| 	* they won't be active in the new or current runlevel) including | ||||
| 	* all those services which have been started, are inactive or | ||||
| 	* are currently starting.  Clearly, some of these will be listed | ||||
| 	* in the new or current runlevel so we won't actually be stopping | ||||
| 	* them all. | ||||
| 	*/ | ||||
| 	stop_services = rc_services_in_state(RC_SERVICE_STARTED); | ||||
| 	tmplist = rc_services_in_state(RC_SERVICE_INACTIVE); | ||||
| 	TAILQ_CONCAT(stop_services, tmplist, entries); | ||||
| @@ -996,7 +1007,11 @@ main(int argc, char **argv) | ||||
| 		stop_services = tmplist; | ||||
| 	} | ||||
|  | ||||
| 	/* Load our list of start services */ | ||||
| 	/* Create a list of all services which should be started for the new or | ||||
| 	 * current runlevel including those in boot, sysinit and hotplugged | ||||
| 	 * runlevels.  Clearly, some of these will already be started so we | ||||
| 	 * won't actually be starting them all. | ||||
| 	 */ | ||||
| 	hotplugged_services = rc_services_in_state(RC_SERVICE_HOTPLUGGED); | ||||
| 	start_services = rc_services_in_runlevel_stacked(newlevel ? | ||||
| 	    newlevel : runlevel); | ||||
| @@ -1006,9 +1021,11 @@ main(int argc, char **argv) | ||||
| 		tmplist = rc_services_in_runlevel(RC_LEVEL_SYSINIT); | ||||
| 		TAILQ_CONCAT(start_services, tmplist, entries); | ||||
| 		free(tmplist); | ||||
| 		/* If we are NOT headed for the single-user runlevel... */ | ||||
| 		if (strcmp(newlevel ? newlevel : runlevel, | ||||
| 			RC_LEVEL_SINGLE) != 0) | ||||
| 		{ | ||||
| 			/* If we are NOT headed for the boot runlevel... */ | ||||
| 			if (strcmp(newlevel ? newlevel : runlevel, | ||||
| 				bootlevel) != 0) | ||||
| 			{ | ||||
| @@ -1029,7 +1046,7 @@ main(int argc, char **argv) | ||||
|  | ||||
| 	/* Now stop the services that shouldn't be running */ | ||||
| 	if (stop_services && !nostop) | ||||
| 		do_stop_services(newlevel, parallel, going_down); | ||||
| 		do_stop_services(types_n, start_services, stop_services, deptree, newlevel, parallel, going_down); | ||||
|  | ||||
| 	/* Wait for our services to finish */ | ||||
| 	wait_for_services(); | ||||
| @@ -1065,18 +1082,10 @@ main(int argc, char **argv) | ||||
| 		TAILQ_FOREACH(service, hotplugged_services, entries) | ||||
| 		    rc_service_mark(service->value, RC_SERVICE_HOTPLUGGED); | ||||
|  | ||||
| 	/* Order the services to start */ | ||||
| 	if (start_services) { | ||||
| 		rc_stringlist_sort(&start_services); | ||||
| 		deporder = rc_deptree_depends(deptree, types_nua, | ||||
| 		    start_services, runlevel, | ||||
| 		    depoptions | RC_DEP_START); | ||||
| 		rc_stringlist_free(start_services); | ||||
| 		start_services = deporder; | ||||
| 	} | ||||
|  | ||||
| #ifdef __linux__ | ||||
| 	/* mark any services skipped as started */ | ||||
| 	/* If the "noinit" parameter was passed on the kernel command line then | ||||
| 	 * mark the specified services as started so they will not be started | ||||
| 	 * by us. */ | ||||
| 	proc = p = rc_proc_getent("noinit"); | ||||
| 	if (proc) { | ||||
| 		while ((token = strsep(&p, ","))) | ||||
| @@ -1085,19 +1094,38 @@ main(int argc, char **argv) | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	/* If we have a list of services to start then... */ | ||||
| 	if (start_services) { | ||||
| 		do_start_services(parallel); | ||||
| 		/* FIXME: If we skip the boot runlevel and go straight | ||||
| 		 * to default from sysinit, we should now re-evaluate our | ||||
| 		 * start services + hotplugged services and call | ||||
| 		 * do_start_services a second time. */ | ||||
| 		/* Get a list of the chained runlevels which compose the target runlevel */ | ||||
| 		RC_STRINGLIST *runlevel_chain = rc_runlevel_stacks(runlevel); | ||||
|  | ||||
| 		/* Loop through them in reverse order. */ | ||||
| 		RC_STRING *rlevel; | ||||
| 		TAILQ_FOREACH_REVERSE(rlevel, runlevel_chain, rc_stringlist, entries) | ||||
| 		{ | ||||
| 			/* Get a list of all the services in that runlevel */ | ||||
| 			RC_STRINGLIST *run_services = rc_services_in_runlevel(rlevel->value); | ||||
|  | ||||
| 			/* Start those services. */ | ||||
| 			rc_stringlist_sort(&run_services); | ||||
| 			deporder = rc_deptree_depends(deptree, types_nua, run_services, rlevel->value, depoptions | RC_DEP_START); | ||||
| 			rc_stringlist_free(run_services); | ||||
| 			run_services = deporder; | ||||
| 			do_start_services(run_services, parallel); | ||||
|  | ||||
| 			/* Wait for our services to finish */ | ||||
| 			wait_for_services(); | ||||
|  | ||||
| 			/* Free the list of services, we're done with it. */ | ||||
| 			rc_stringlist_free(run_services); | ||||
| 		} | ||||
| 		rc_stringlist_free(runlevel_chain); | ||||
| 	} | ||||
|  | ||||
| #ifdef __linux__ | ||||
| 	/* mark any services skipped as stopped */ | ||||
| 	/* If the "noinit" parameter was passed on the kernel command line then | ||||
| 	 * mark the specified services as stopped so that our records reflect | ||||
| 	 * reality.	 */ | ||||
| 	proc = p = rc_proc_getent("noinit"); | ||||
| 	if (proc) { | ||||
| 		while ((token = strsep(&p, ","))) | ||||
|   | ||||
| @@ -307,7 +307,7 @@ parse_schedule(const char *string, int timeout) | ||||
| } | ||||
|  | ||||
| static pid_t | ||||
| get_pid(const char *pidfile, bool quiet) | ||||
| get_pid(const char *pidfile) | ||||
| { | ||||
| 	FILE *fp; | ||||
| 	pid_t pid; | ||||
| @@ -316,13 +316,11 @@ get_pid(const char *pidfile, bool quiet) | ||||
| 		return -1; | ||||
|  | ||||
| 	if ((fp = fopen(pidfile, "r")) == NULL) { | ||||
| 		if (!quiet) | ||||
| 		eerror("%s: fopen `%s': %s", applet, pidfile, strerror(errno)); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (fscanf(fp, "%d", &pid) != 1) { | ||||
| 		if (!quiet) | ||||
| 		eerror("%s: no pid found in `%s'", applet, pidfile); | ||||
| 		fclose(fp); | ||||
| 		return -1; | ||||
| @@ -336,8 +334,7 @@ get_pid(const char *pidfile, bool quiet) | ||||
| /* return number of processed killed, -1 on error */ | ||||
| static int | ||||
| do_stop(const char *exec, const char *const *argv, | ||||
|     pid_t pid, uid_t uid,int sig, | ||||
|     bool quiet, bool verbose, bool test) | ||||
|     pid_t pid, uid_t uid,int sig, bool test) | ||||
| { | ||||
| 	RC_PIDLIST *pids; | ||||
| 	RC_PID *pi; | ||||
| @@ -355,18 +352,14 @@ do_stop(const char *exec, const char *const *argv, | ||||
|  | ||||
| 	LIST_FOREACH_SAFE(pi, pids, entries, np) { | ||||
| 		if (test) { | ||||
| 			if (!quiet) | ||||
| 			einfo("Would send signal %d to PID %d", sig, pi->pid); | ||||
| 			nkilled++; | ||||
| 		} else { | ||||
| 			if (verbose) | ||||
| 				ebegin("Sending signal %d to PID %d", | ||||
| 				    sig, pi->pid); | ||||
| 			ebeginv("Sending signal %d to PID %d", sig, pi->pid); | ||||
| 			errno = 0; | ||||
| 			killed = (kill(pi->pid, sig) == 0 || | ||||
| 			    errno == ESRCH ? true : false); | ||||
| 			if (verbose) | ||||
| 				eend(killed ? 0 : 1, | ||||
| 			eendv(killed ? 0 : 1, | ||||
| 				"%s: failed to send signal %d to PID %d: %s", | ||||
| 				applet, sig, pi->pid, strerror(errno)); | ||||
| 			if (!killed) { | ||||
| @@ -386,7 +379,7 @@ do_stop(const char *exec, const char *const *argv, | ||||
| static int | ||||
| run_stop_schedule(const char *exec, const char *const *argv, | ||||
|     const char *pidfile, uid_t uid, | ||||
|     bool quiet, bool verbose, bool test, bool progress) | ||||
|     bool test, bool progress) | ||||
| { | ||||
| 	SCHEDULEITEM *item = TAILQ_FIRST(&schedule); | ||||
| 	int nkilled = 0; | ||||
| @@ -398,15 +391,15 @@ run_stop_schedule(const char *exec, const char *const *argv, | ||||
| 	const char *const *p; | ||||
| 	bool progressed = false; | ||||
|  | ||||
| 	if (verbose) { | ||||
| 	if (exec) | ||||
| 			einfo ("Will stop %s", exec); | ||||
| 		einfov("Will stop %s", exec); | ||||
| 	if (pidfile) | ||||
| 			einfo("Will stop PID in pidfile `%s'", pidfile); | ||||
| 		einfov("Will stop PID in pidfile `%s'", pidfile); | ||||
| 	if (uid) | ||||
| 			einfo("Will stop processes owned by UID %d", uid); | ||||
| 		einfov("Will stop processes owned by UID %d", uid); | ||||
| 	if (argv && *argv) { | ||||
| 			einfon("Will stop processes of `"); | ||||
| 		einfovn("Will stop processes of `"); | ||||
| 		if (rc_yesno(getenv("EINFO_VERBOSE"))) { | ||||
| 			for (p = argv; p && *p; p++) { | ||||
| 				if (p != argv) | ||||
| 					printf(" "); | ||||
| @@ -417,7 +410,7 @@ run_stop_schedule(const char *exec, const char *const *argv, | ||||
| 	} | ||||
|  | ||||
| 	if (pidfile) { | ||||
| 		pid = get_pid(pidfile, false); | ||||
| 		pid = get_pid(pidfile); | ||||
| 		if (pid == -1) | ||||
| 			return 0; | ||||
| 	} | ||||
| @@ -430,8 +423,7 @@ run_stop_schedule(const char *exec, const char *const *argv, | ||||
|  | ||||
| 		case SC_SIGNAL: | ||||
| 			nrunning = 0; | ||||
| 			nkilled = do_stop(exec, argv, pid, uid, item->value, | ||||
| 			    quiet, verbose, test); | ||||
| 			nkilled = do_stop(exec, argv, pid, uid, item->value, test); | ||||
| 			if (nkilled == 0) { | ||||
| 				if (tkilled == 0) { | ||||
| 					if (progressed) | ||||
| @@ -460,8 +452,7 @@ run_stop_schedule(const char *exec, const char *const *argv, | ||||
| 				     nloops++) | ||||
| 				{ | ||||
| 					if ((nrunning = do_stop(exec, argv, | ||||
| 						    pid, uid, 0, true, false, | ||||
| 						    true)) == 0) | ||||
| 						    pid, uid, 0, true)) == 0) | ||||
| 						return 0; | ||||
|  | ||||
|  | ||||
| @@ -678,8 +669,6 @@ start_stop_daemon(int argc, char **argv) | ||||
| 	bool stop = false; | ||||
| 	bool oknodo = false; | ||||
| 	bool test = false; | ||||
| 	bool quiet; | ||||
| 	bool verbose = false; | ||||
| 	char *exec = NULL; | ||||
| 	char *startas = NULL; | ||||
| 	char *name = NULL; | ||||
| @@ -916,8 +905,6 @@ start_stop_daemon(int argc, char **argv) | ||||
| 	endpwent(); | ||||
| 	argc -= optind; | ||||
| 	argv += optind; | ||||
| 	quiet = rc_yesno(getenv("EINFO_QUIET")); | ||||
| 	verbose = rc_yesno(getenv("EINFO_VERBOSE")); | ||||
|  | ||||
| 	/* Allow start-stop-daemon --signal HUP --exec /usr/sbin/dnsmasq | ||||
| 	 * instead of forcing --stop --oknodo as well */ | ||||
| @@ -1061,7 +1048,7 @@ start_stop_daemon(int argc, char **argv) | ||||
| 		else | ||||
| 			parse_schedule(NULL, sig); | ||||
| 		i = run_stop_schedule(exec, (const char *const *)margv, | ||||
| 		    pidfile, uid, quiet, verbose, test, progress); | ||||
| 		    pidfile, uid, test, progress); | ||||
|  | ||||
| 		if (i < 0) | ||||
| 			/* We failed to stop something */ | ||||
| @@ -1083,16 +1070,16 @@ start_stop_daemon(int argc, char **argv) | ||||
| 	} | ||||
|  | ||||
| 	if (pidfile) | ||||
| 		pid = get_pid(pidfile, true); | ||||
| 		pid = get_pid(pidfile); | ||||
| 	else | ||||
| 		pid = 0; | ||||
|  | ||||
| 	if (do_stop(exec, (const char * const *)margv, pid, uid, | ||||
| 		0, true, false, true) > 0) | ||||
| 		0, true) > 0) | ||||
| 		eerrorx("%s: %s is already running", applet, exec); | ||||
|  | ||||
| 	if (test) { | ||||
| 		if (quiet) | ||||
| 		if (rc_yesno(getenv("EINFO_QUIET"))) | ||||
| 			exit (EXIT_SUCCESS); | ||||
|  | ||||
| 		einfon("Would start"); | ||||
| @@ -1116,10 +1103,8 @@ start_stop_daemon(int argc, char **argv) | ||||
| 		exit(EXIT_SUCCESS); | ||||
| 	} | ||||
|  | ||||
| 	if (verbose) { | ||||
| 		ebegin("Detaching to start `%s'", exec); | ||||
| 		eindent(); | ||||
| 	} | ||||
| 	ebeginv("Detaching to start `%s'", exec); | ||||
| 	eindentv(); | ||||
|  | ||||
| 	/* Remove existing pidfile */ | ||||
| 	if (pidfile) | ||||
| @@ -1287,9 +1272,9 @@ start_stop_daemon(int argc, char **argv) | ||||
| 		} | ||||
|  | ||||
| 		/* We don't redirect stdin as some daemons may need it */ | ||||
| 		if (background || quiet || redirect_stdout) | ||||
| 		if (background || redirect_stdout || rc_yesno(getenv("EINFO_QUIET"))) | ||||
| 			dup2(stdout_fd, STDOUT_FILENO); | ||||
| 		if (background || redirect_stderr) | ||||
| 		if (background || redirect_stderr || rc_yesno(getenv("EINFO_QUIET"))) | ||||
| 			dup2(stderr_fd, STDERR_FILENO); | ||||
|  | ||||
| 		for (i = getdtablesize() - 1; i >= 3; --i) | ||||
| @@ -1320,9 +1305,10 @@ start_stop_daemon(int argc, char **argv) | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} while (!WIFEXITED(i) && !WIFSIGNALED(i)); | ||||
| 		if (!WIFEXITED(i) || WEXITSTATUS(i) != 0) | ||||
| 			eerrorx("%s: failed to start `%s'", applet, exec); | ||||
|  | ||||
| 		if (!WIFEXITED(i) || WEXITSTATUS(i) != 0) { | ||||
| 			eerror("%s: failed to start `%s'", applet, exec); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 		pid = spid; | ||||
| 	} | ||||
|  | ||||
| @@ -1356,7 +1342,7 @@ start_stop_daemon(int argc, char **argv) | ||||
| 				alive = true; | ||||
| 		} else { | ||||
| 			if (pidfile) { | ||||
| 				pid = get_pid(pidfile, false); | ||||
| 				pid = get_pid(pidfile); | ||||
| 				if (pid == -1) { | ||||
| 					eerrorx("%s: did not " | ||||
| 					    "create a valid" | ||||
| @@ -1366,7 +1352,7 @@ start_stop_daemon(int argc, char **argv) | ||||
| 			} else | ||||
| 				pid = 0; | ||||
| 			if (do_stop(exec, (const char *const *)margv, | ||||
| 				pid, uid, 0, true, false, true) > 0) | ||||
| 				pid, uid, 0, true) > 0) | ||||
| 				alive = true; | ||||
| 		} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user