Compare commits
	
		
			5 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2747f40f82 | ||
| 
						 | 
					933972da53 | ||
| 
						 | 
					dbcb8ba3fe | ||
| 
						 | 
					e462c3223e | ||
| 
						 | 
					06f195ce37 | 
@@ -38,7 +38,7 @@ Who:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
When: 1.0
 | 
					When: 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Why: Deprecated in favor of extra_commands, extra_started_commands
 | 
					Why: Depprecated in favor of extra_commands, extra_started_commands
 | 
				
			||||||
	 and extra_stopped_commands.
 | 
						 and extra_stopped_commands.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Who:
 | 
					Who:
 | 
				
			||||||
@@ -47,7 +47,7 @@ Who:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
When: 1.0
 | 
					When: 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Why: Deprecated in favor of executable scripts in @SYSCONFDIR@/local.d
 | 
					Why: Depprecated in favor of executable scripts in @SYSCONFDIR@/local.d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Who:
 | 
					Who:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,3 +76,13 @@ Why: The getline() function was standardized in POSIX.1-2008, so it
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Who:
 | 
					Who:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### rc_sys()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When: 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Why: The OpenRC code now uses two internal functions, detect_container()
 | 
				
			||||||
 | 
						 and detect_vm() to handle this. rc_sys() is broken because it
 | 
				
			||||||
 | 
						 doesn't differentiate between containers and vm's.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Who:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
NAME=		openrc
 | 
					NAME=		openrc
 | 
				
			||||||
VERSION=	0.21.7
 | 
					VERSION=	0.20.1
 | 
				
			||||||
PKG=		${NAME}-${VERSION}
 | 
					PKG=		${NAME}-${VERSION}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								NEWS.md
									
									
									
									
									
								
							@@ -3,33 +3,6 @@
 | 
				
			|||||||
This file will contain a list of notable changes for each release. Note
 | 
					This file will contain a list of notable changes for each release. Note
 | 
				
			||||||
the information in this file is in reverse order.
 | 
					the information in this file is in reverse order.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## OpenRC-0.21
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This version adds a daemon supervisor which can start daemons and
 | 
					 | 
				
			||||||
restart them if they crash. See supervise-daemon-guide.md in the
 | 
					 | 
				
			||||||
distribution for details on its use.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It is now possible to mark certain mount points as critical. If these
 | 
					 | 
				
			||||||
mount points are unable to be mounted, localmount or netmount will fail.
 | 
					 | 
				
			||||||
This is handled in /etc/conf.d/localmount and /etc/conf.d/netmount. See
 | 
					 | 
				
			||||||
these files for the setup.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The deprecation messages in 0.13.x for runscript and rc are now
 | 
					 | 
				
			||||||
made visible in preparation for the removal of these binaries in 1.0.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The steps you should take to get rid of these warnings is to run openrc
 | 
					 | 
				
			||||||
in initialization steps instead of rc and change the shebang lines in
 | 
					 | 
				
			||||||
service scripts to refer to "openrc-run" instead of "runscript".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In 0.21.4, a modules-load service was added. This works like the
 | 
					 | 
				
			||||||
equivalent service in systemd. It looks for files named *.conf first in
 | 
					 | 
				
			||||||
/usr/lib/modules-load.d, then /run/modules-load.d, then
 | 
					 | 
				
			||||||
/etc/modules-load.d. These files contain a list of modules, one per
 | 
					 | 
				
			||||||
line, which should be loaded into the kernel. If a file name appears in
 | 
					 | 
				
			||||||
/run/modules-load.d, it overrides a file of the same name in
 | 
					 | 
				
			||||||
/usr/lib/modules-load.d. A file appearing in /etc/modules-load.d
 | 
					 | 
				
			||||||
overrides a file of the same name in both previous directories.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## OpenRC-0.19
 | 
					## OpenRC-0.19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This version adds a net-online service. By default, this
 | 
					This version adds a net-online service. By default, this
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ wipe_tmp="YES"
 | 
				
			|||||||
# This may be useful if you need the kernel boot log afterwards
 | 
					# This may be useful if you need the kernel boot log afterwards
 | 
				
			||||||
log_dmesg="YES"
 | 
					log_dmesg="YES"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Save the previous dmesg log to dmesg.old
 | 
					# Save the previous dmesg log to dmesc.old
 | 
				
			||||||
# This may be useful if you need to compare the current boot to the
 | 
					# This may be useful if you need to compare the current boot to the
 | 
				
			||||||
# previous one.
 | 
					# previous one.
 | 
				
			||||||
#previous_dmesg=no
 | 
					#previous_dmesg=no
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,3 @@
 | 
				
			|||||||
# Stop the unmounting of certain points.
 | 
					# Stop the unmounting of certain points.
 | 
				
			||||||
# This could be useful for some NFS related work.
 | 
					# This could be useful for some NFS related work.
 | 
				
			||||||
#no_umounts="/dir1:/var/dir2"
 | 
					#no_umounts="/dir1:/var/dir2"
 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Mark certain mount points as critical.
 | 
					 | 
				
			||||||
# This contains aspace separated list of mount points which should be
 | 
					 | 
				
			||||||
# considered critical. If one of these mount points cannot be mounted,
 | 
					 | 
				
			||||||
# localmount will fail.
 | 
					 | 
				
			||||||
# By default, this is empty.
 | 
					 | 
				
			||||||
#critical_mounts="/home /var"
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,10 +38,3 @@
 | 
				
			|||||||
# other words, please change it to be more suited to your system.
 | 
					# other words, please change it to be more suited to your system.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
rc_need="net"
 | 
					rc_need="net"
 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Mark certain mount points as critical.
 | 
					 | 
				
			||||||
# This contains aspace separated list of mount points which should be
 | 
					 | 
				
			||||||
# considered critical. If one of these mount points cannot be mounted,
 | 
					 | 
				
			||||||
# netmount will fail.
 | 
					 | 
				
			||||||
# By default, this is empty.
 | 
					 | 
				
			||||||
#critical_mounts="/home /var"
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										251
									
								
								guide.md
									
									
									
									
									
								
							
							
						
						
									
										251
									
								
								guide.md
									
									
									
									
									
								
							@@ -1,251 +0,0 @@
 | 
				
			|||||||
# Purpose and description
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenRC is an init system for Unixoid operating systems. It takes care of 
 | 
					 | 
				
			||||||
startup and shutdown of the whole system, including services.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It evolved out of the Gentoo "Baselayout" package which was a custom pure-shell 
 | 
					 | 
				
			||||||
startup solution. (This was both hard to maintain and debug, and not very 
 | 
					 | 
				
			||||||
performant)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Most of the core parts are written in C99 for performance and flexibility 
 | 
					 | 
				
			||||||
reasons, while everything else is posix sh.
 | 
					 | 
				
			||||||
The License is 2-clause BSD
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Current size is about 10k LoC C, and about 4k LoC shell.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenRC is known to work on Linux, many BSDs (FreeBSD, OpenBSD, DragonFlyBSD at 
 | 
					 | 
				
			||||||
least) and HURD.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Services are stateful (i.e. start; start will lead to "it's already started")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Startup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Usually PID1 (aka. init) calls the OpenRC binary ("/sbin/openrc" by default).
 | 
					 | 
				
			||||||
(The default setup assumes sysvinit for this)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
openrc scans the runlevels (default: "/etc/runlevels") and builds a dependency 
 | 
					 | 
				
			||||||
graph, then starts the needed service scripts, either serialized (default) or in 
 | 
					 | 
				
			||||||
parallel.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
When all the init scripts are started openrc terminates. There is no persistent 
 | 
					 | 
				
			||||||
daemon. (Integration with tools like monit, runit or s6 can be done)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Shutdown
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On change to runlevel 0/6 or running "reboot", "halt" etc., openrc stops all 
 | 
					 | 
				
			||||||
services that are started and runs the services in the "shutdown" runlevel.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Modifying Service Scripts
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Any service can, at any time, be started/stopped/restarted by executing 
 | 
					 | 
				
			||||||
"rc-service someservice start", "rc-service someservice stop", etc.
 | 
					 | 
				
			||||||
Another, less preferred method, is to run the service script directly,
 | 
					 | 
				
			||||||
e.g. "/etc/init.d/service start", "/etc/init.d/service stop", etc.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenRC will take care of dependencies, e.g starting apache will start network 
 | 
					 | 
				
			||||||
first, and stopping network will stop apache first.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
There is a special command "zap" that makes OpenRC 'forget' that a service is 
 | 
					 | 
				
			||||||
started; this is mostly useful to reset a crashed service to stopped state 
 | 
					 | 
				
			||||||
without invoking the (possibly broken) stop function of the service script.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Calling "openrc" without any arguments will try to reset all services so
 | 
					 | 
				
			||||||
that the current runlevel is satisfied; if you manually started apache it will be 
 | 
					 | 
				
			||||||
stopped, and if squid died but is in the current runlevel it'll be restarted.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
There is a "service" helper that emulates the syntax seen on e.g. older Redhat 
 | 
					 | 
				
			||||||
and Ubuntu ("service nginx start" etc.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Runlevels
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenRC has a concept of runlevels, similar to what sysvinit historically 
 | 
					 | 
				
			||||||
offered. A runlevel is basically a collection of services that needs to be 
 | 
					 | 
				
			||||||
started. Instead of random numbers they are named, and users can create their 
 | 
					 | 
				
			||||||
own if needed. This allows, for example, to have a default runlevel with 
 | 
					 | 
				
			||||||
"everything" enabled, and a "powersaving" runlevel where some services are 
 | 
					 | 
				
			||||||
disabled.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The "rc-status" helper will print all currently active runlevels and the state 
 | 
					 | 
				
			||||||
of init scripts in them:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# rc-status
 | 
					 | 
				
			||||||
 * Caching service dependencies ... [ ok ]
 | 
					 | 
				
			||||||
Runlevel: default
 | 
					 | 
				
			||||||
 modules                     [  started  ]
 | 
					 | 
				
			||||||
 lvm                         [  started  ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
All runlevels are represented as folders in /etc/runlevels/ with symlinks to 
 | 
					 | 
				
			||||||
the actual init scripts.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Calling openrc with an argument ("openrc default") will switch to that
 | 
					 | 
				
			||||||
runlevel; this will start and stop services as needed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Managing runlevels is usually done through the "rc-update" helper, but could of 
 | 
					 | 
				
			||||||
course be done by hand if desired.
 | 
					 | 
				
			||||||
e.g. "rc-update add nginx default" - add nginx to the default runlevel
 | 
					 | 
				
			||||||
Note: This will not auto-start nginx! You'd still have to trigger "rc" or run 
 | 
					 | 
				
			||||||
the initscript by hand.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FIXME: Document stacked runlevels
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The default startup uses the runlevels "boot", "sysinit" and "default", in that 
 | 
					 | 
				
			||||||
order. Shutdown uses the "shutdown" runlevel.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Syntax of Service Scripts
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Service scripts are shell scripts. OpenRC aims at using only the standardized 
 | 
					 | 
				
			||||||
POSIX sh subset for portability reasons. The default interpreter (build-time 
 | 
					 | 
				
			||||||
toggle) is /bin/sh, so using for example mksh is not a problem.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenRC has been tested with busybox sh, ash, dash, bash, mksh, zsh and possibly 
 | 
					 | 
				
			||||||
others. Using busybox sh has been difficult as it replaces commands with 
 | 
					 | 
				
			||||||
builtins that don't offer the expected features.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The interpreter for initscripts is #!/sbin/openrc-run
 | 
					 | 
				
			||||||
Not using this interpreter will break the use of dependencies and is not 
 | 
					 | 
				
			||||||
supported. (iow: if you insist on using #!/bin/sh you're on your own)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
A "depend" function declares the dependencies of this service script.
 | 
					 | 
				
			||||||
All scripts must have start/stop/status functions, but defaults are provided.
 | 
					 | 
				
			||||||
Extra functions can be added easily:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extra_commands="checkconfig"
 | 
					 | 
				
			||||||
checkconfig() {
 | 
					 | 
				
			||||||
	doSomething
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This exports the checkconfig function so that "/etc/init.d/someservice 
 | 
					 | 
				
			||||||
checkconfig" will be available, and it "just" runs this function.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
While commands defined in extra_commands are always available, commands
 | 
					 | 
				
			||||||
defined in extra_started_commands will only work when the service is started
 | 
					 | 
				
			||||||
and those defined in extra_stopped_commands will only work when the service is
 | 
					 | 
				
			||||||
stopped. This can be used for implementing graceful reload and similar
 | 
					 | 
				
			||||||
behaviour.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Adding a restart function will not work, this is a design decision within 
 | 
					 | 
				
			||||||
OpenRC. Since there may be dependencies involved (e.g. network -> apache) a 
 | 
					 | 
				
			||||||
restart function is in general not going to work. 
 | 
					 | 
				
			||||||
restart is internally mapped to stop() + start() (plus handling dependencies).
 | 
					 | 
				
			||||||
If a service needs to behave differently when it is being restarted vs
 | 
					 | 
				
			||||||
started or stopped, it should test the $RC_CMD variable, for example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [ "$RC_CMD" = restart ] && do_something
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The Depend Function
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This function declares the dependencies for a service script. This
 | 
					 | 
				
			||||||
determines the order the service scripts start.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
depend() {
 | 
					 | 
				
			||||||
	need net
 | 
					 | 
				
			||||||
	use dns logger netmount
 | 
					 | 
				
			||||||
	want coolservice
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"need" declares a hard dependency - net always needs to be started before this 
 | 
					 | 
				
			||||||
	service does
 | 
					 | 
				
			||||||
"use" is a soft dependency - if dns, logger or netmount is in this runlevel 
 | 
					 | 
				
			||||||
	start it before, but we don't care if it's not in this runlevel.
 | 
					 | 
				
			||||||
	"want" is between need and use - try to start coolservice if it is
 | 
					 | 
				
			||||||
	installed on the system, regardless of whether it is in the
 | 
					 | 
				
			||||||
	runlevel, but we don't care if it starts.
 | 
					 | 
				
			||||||
"before" declares that we need to be started before another service
 | 
					 | 
				
			||||||
"after" declares that we need to be started after another service, without 
 | 
					 | 
				
			||||||
	creating a dependency (so on calling stop the two are independent)
 | 
					 | 
				
			||||||
"provide" allows multiple implementations to provide one service type, e.g.:
 | 
					 | 
				
			||||||
	'provide cron' is set in all cron-daemons, so any one of them started 
 | 
					 | 
				
			||||||
	satisfies a cron dependency
 | 
					 | 
				
			||||||
"keyword" allows platform-specific overrides, e.g. "keyword -lxc" makes this 
 | 
					 | 
				
			||||||
	service script a noop in lxc containers. Useful for things like keymaps, 
 | 
					 | 
				
			||||||
	module loading etc. that are either platform-specific or not available 
 | 
					 | 
				
			||||||
	in containers/virtualization/...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FIXME: Anything missing in this list?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The Default Functions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
All service scripts are assumed to have the following functions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start()
 | 
					 | 
				
			||||||
stop()
 | 
					 | 
				
			||||||
status()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
There are default implementations in rc/sh/openrc-run.sh - this allows very 
 | 
					 | 
				
			||||||
compact service scripts. These functions can be overridden per service script as 
 | 
					 | 
				
			||||||
needed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The default functions assume the following variables to be set in the service 
 | 
					 | 
				
			||||||
script:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
command=
 | 
					 | 
				
			||||||
command_args=
 | 
					 | 
				
			||||||
pidfile=
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Thus the 'smallest' service scripts can be half a dozen lines long
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The Magic of Conf.d
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Most service scripts need default values. It would be fragile to
 | 
					 | 
				
			||||||
explicitly source some arbitrary files. By convention openrc-run will source
 | 
					 | 
				
			||||||
the matching file in /etc/conf.d/ for any script in /etc/init.d/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This allows you to set random startup-related things easily. Example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
conf.d/foo:
 | 
					 | 
				
			||||||
START_OPTS="--extraparameter sausage"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
init.d/foo:
 | 
					 | 
				
			||||||
start() {
 | 
					 | 
				
			||||||
	/usr/sbin/foo-daemon ${STARTOPTS}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The big advantage of this split is that most of the time editing of the init 
 | 
					 | 
				
			||||||
script can be avoided.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Start-Stop-Daemon
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenRC has its own modified version of s-s-d, which is historically related and 
 | 
					 | 
				
			||||||
mostly syntax-compatible to Debian's s-s-d, but has been rewritten from scratch.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It helps with starting daemons, backgrounding, creating PID files and many 
 | 
					 | 
				
			||||||
other convenience functions related to managing daemons.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# /etc/rc.conf
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This file manages the default configuration for OpenRC, and it has examples of 
 | 
					 | 
				
			||||||
per-service-script variables.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Among these are rc_parallel (for parallelized startup), rc_log (logs all boot 
 | 
					 | 
				
			||||||
messages to a file), and a few others.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# ulimit and CGroups
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Setting ulimit and nice values per service can be done through the rc_ulimit 
 | 
					 | 
				
			||||||
variable.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Under Linux, OpenRC can optionally use CGroups for process management.
 | 
					 | 
				
			||||||
By default each service script's processes are migrated to their own CGroup.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
By changing certain values in the conf.d file limits can be enforced per 
 | 
					 | 
				
			||||||
service. It is easy to find orphan processes of a service that persist after 
 | 
					 | 
				
			||||||
stop(), but by default these will NOT be terminated.
 | 
					 | 
				
			||||||
To change this add rc_cgroup_cleanup="yes" in the conf.d files for services 
 | 
					 | 
				
			||||||
where you desire this functionality.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Caching
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For performance reasons OpenRC keeps a cache of pre-parsed initscript metadata
 | 
					 | 
				
			||||||
(e.g. depend). The default location for this is /${RC_SVCDIR}/cache.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The cache uses mtime to check for file staleness. Should any service script
 | 
					 | 
				
			||||||
change it'll re-source the relevant files and update the cache
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Convenience functions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenRC has wrappers for many common output tasks in libeinfo.
 | 
					 | 
				
			||||||
This allows to print colour-coded status notices and other things.
 | 
					 | 
				
			||||||
To make the output consistent the bundled initscripts all use ebegin/eend to 
 | 
					 | 
				
			||||||
print nice messages.
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,4 @@
 | 
				
			|||||||
binfmt
 | 
					binfmt
 | 
				
			||||||
modules-load
 | 
					 | 
				
			||||||
bootmisc
 | 
					bootmisc
 | 
				
			||||||
fsck
 | 
					fsck
 | 
				
			||||||
hostname
 | 
					hostname
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,10 +19,10 @@ SRCS-FreeBSD=	hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \
 | 
				
			|||||||
		rpcbind.in savecore.in syslogd.in
 | 
							rpcbind.in savecore.in syslogd.in
 | 
				
			||||||
# These are FreeBSD specific
 | 
					# These are FreeBSD specific
 | 
				
			||||||
SRCS-FreeBSD+=	adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \
 | 
					SRCS-FreeBSD+=	adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \
 | 
				
			||||||
		modules.in modules-load.in mixer.in nscd.in powerd.in syscons.in
 | 
							mixer.in nscd.in powerd.in syscons.in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SRCS-Linux=	binfmt.in devfs.in dmesg.in hwclock.in consolefont.in keymaps.in \
 | 
					SRCS-Linux=	binfmt.in devfs.in dmesg.in hwclock.in consolefont.in keymaps.in \
 | 
				
			||||||
		killprocs.in modules.in modules-load.in mount-ro.in mtab.in numlock.in \
 | 
							killprocs.in modules.in mount-ro.in mtab.in numlock.in \
 | 
				
			||||||
		procfs.in net-online.in sysfs.in termencoding.in tmpfiles.dev.in
 | 
							procfs.in net-online.in sysfs.in termencoding.in tmpfiles.dev.in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Generic BSD scripts
 | 
					# Generic BSD scripts
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ depend()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	after procfs
 | 
						after procfs
 | 
				
			||||||
	use modules devfs
 | 
						use modules devfs
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -openvz -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ depend()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	need localmount termencoding
 | 
						need localmount termencoding
 | 
				
			||||||
	after hotplug bootmisc modules
 | 
						after hotplug bootmisc modules
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
						keyword -openvz -prefix -systemd-nspawn -uml -vserver -xenu -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ depend()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	provide dev-mount
 | 
						provide dev-mount
 | 
				
			||||||
	before dev
 | 
						before dev
 | 
				
			||||||
	keyword -docker -lxc -prefix -systemd-nspawn -vserver
 | 
						keyword -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mount_dev()
 | 
					mount_dev()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ description="Set the dmesg level for a cleaner boot"
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	before dev modules
 | 
						before dev modules
 | 
				
			||||||
	keyword -docker -lxc -prefix -systemd-nspawn -vserver
 | 
						keyword -lxc -prefix -systemd-nspawn -vserver
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ _IFS="
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	use dev clock modules
 | 
						use dev clock modules
 | 
				
			||||||
	keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -timeout -vserver -uml
 | 
						keyword -jail -openvz -prefix -systemd-nspawn -timeout -vserver -lxc -uml
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_abort() {
 | 
					_abort() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@
 | 
				
			|||||||
description="Sets the hostname of the machine."
 | 
					description="Sets the hostname of the machine."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
depend() {
 | 
					depend() {
 | 
				
			||||||
	keyword -docker -lxc -prefix -systemd-nspawn
 | 
						keyword -prefix -systemd-nspawn -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ depend()
 | 
				
			|||||||
	else
 | 
						else
 | 
				
			||||||
		before *
 | 
							before *
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
						keyword -openvz -prefix -systemd-nspawn -uml -vserver -xenu -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
setupopts()
 | 
					setupopts()
 | 
				
			||||||
@@ -69,16 +69,6 @@ _hwclock()
 | 
				
			|||||||
	return 1
 | 
						return 1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
get_noadjfile()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if ! yesno $clock_adjfile; then
 | 
					 | 
				
			||||||
		# Some implementations don't handle adjustments
 | 
					 | 
				
			||||||
		if LC_ALL=C hwclock --help 2>&1 | grep -q "\-\-noadjfile"; then
 | 
					 | 
				
			||||||
			echo --noadjfile
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local retval=0 errstr=""
 | 
						local retval=0 errstr=""
 | 
				
			||||||
@@ -101,16 +91,16 @@ start()
 | 
				
			|||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	# Always set the kernel's time zone.
 | 
						# Always set the kernel's time zone.
 | 
				
			||||||
	_hwclock --systz $utc_cmd $(get_noadjfile) $clock_args
 | 
						_hwclock --systz $utc_cmd $clock_args
 | 
				
			||||||
	: $(( retval += $? ))
 | 
						: $(( retval += $? ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if [ -e /etc/adjtime ] && yesno $clock_adjfile; then
 | 
						if [ -e /etc/adjtime ] && yesno $clock_adjfile; then
 | 
				
			||||||
		_hwclock --adjust $utc_cmd $(get_noadjfile)
 | 
							_hwclock --adjust $utc_cmd
 | 
				
			||||||
		: $(( retval += $? ))
 | 
							: $(( retval += $? ))
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if yesno ${clock_hctosys:-YES}; then
 | 
						if yesno ${clock_hctosys:-YES}; then
 | 
				
			||||||
		_hwclock --hctosys $utc_cmd $(get_noadjfile) $clock_args
 | 
							_hwclock --hctosys $utc_cmd $clock_args
 | 
				
			||||||
		: $(( retval += $? ))
 | 
							: $(( retval += $? ))
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -132,7 +122,14 @@ stop()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	ebegin "Setting hardware clock using the system clock" "[$utc]"
 | 
						ebegin "Setting hardware clock using the system clock" "[$utc]"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_hwclock --systohc $utc_cmd $(get_noadjfile) $clock_args
 | 
						if ! yesno $clock_adjfile; then
 | 
				
			||||||
 | 
							# Some implementations don't handle adjustments
 | 
				
			||||||
 | 
							if LC_ALL=C hwclock --help 2>&1 | grep -q "\-\-noadjfile"; then
 | 
				
			||||||
 | 
								utc_cmd="$utc_cmd --noadjfile"
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_hwclock --systohc $utc_cmd $clock_args
 | 
				
			||||||
	retval=$?
 | 
						retval=$?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eend $retval "Failed to sync clocks"
 | 
						eend $retval "Failed to sync clocks"
 | 
				
			||||||
@@ -147,5 +144,5 @@ save()
 | 
				
			|||||||
show()
 | 
					show()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setupopts
 | 
						setupopts
 | 
				
			||||||
	hwclock --show "$utc_cmd" $(get_noadjfile) $clock_args
 | 
						hwclock --show "$utc_cmd" $clock_args
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ depend()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	need localmount termencoding
 | 
						need localmount termencoding
 | 
				
			||||||
	after bootmisc
 | 
						after bootmisc
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
						keyword -openvz -prefix -systemd-nspawn -uml -vserver -xenu -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,10 @@ start()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	ebegin "Terminating remaining processes"
 | 
						ebegin "Terminating remaining processes"
 | 
				
			||||||
	killall5 -15 ${killall5_opts}
 | 
						killall5 -15 ${killall5_opts}
 | 
				
			||||||
 | 
						sleep 1
 | 
				
			||||||
	eend 0
 | 
						eend 0
 | 
				
			||||||
	ebegin "Killing remaining processes"
 | 
						ebegin "Killing remaining processes"
 | 
				
			||||||
	killall5 -9 ${killall5_opts}
 | 
						killall5 -9 ${killall5_opts}
 | 
				
			||||||
 | 
						sleep 1
 | 
				
			||||||
	eend 0
 | 
						eend 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,13 +16,13 @@ depend()
 | 
				
			|||||||
	need fsck
 | 
						need fsck
 | 
				
			||||||
	use lvm modules mtab
 | 
						use lvm modules mtab
 | 
				
			||||||
	after lvm modules
 | 
						after lvm modules
 | 
				
			||||||
	keyword -docker -jail -lxc -prefix -systemd-nspawn -vserver
 | 
						keyword -jail -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	# Mount local filesystems in /etc/fstab.
 | 
						# Mount local filesystems in /etc/fstab.
 | 
				
			||||||
	local critical= types="noproc" x= no_netdev= rc=
 | 
						local types="noproc" x= no_netdev= rc=
 | 
				
			||||||
	for x in $net_fs_list $extra_net_fs_list; do
 | 
						for x in $net_fs_list $extra_net_fs_list; do
 | 
				
			||||||
		types="${types},no${x}"
 | 
							types="${types},no${x}"
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
@@ -37,17 +37,8 @@ start()
 | 
				
			|||||||
	mount -at "$types" $no_netdev
 | 
						mount -at "$types" $no_netdev
 | 
				
			||||||
	eend $? "Some local filesystem failed to mount"
 | 
						eend $? "Some local filesystem failed to mount"
 | 
				
			||||||
	rc=$?
 | 
						rc=$?
 | 
				
			||||||
	if [ -z "$critical_mounts" ]; then
 | 
						if [ "$RC_UNAME" != Linux ]; then
 | 
				
			||||||
		rc=0
 | 
							rc=0
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		for x in ${critical_mounts}; do
 | 
					 | 
				
			||||||
		fstabinfo -q $x || continue
 | 
					 | 
				
			||||||
		if ! mountinfo -q $x; then
 | 
					 | 
				
			||||||
			critical=x
 | 
					 | 
				
			||||||
			eerror "Failed to mount $x"
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
		[ -z "$critical" ] && rc=0
 | 
					 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	return $rc
 | 
						return $rc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,72 +0,0 @@
 | 
				
			|||||||
#!@SBINDIR@/openrc-run
 | 
					 | 
				
			||||||
# Copyright (c) 2016 The OpenRC Authors.
 | 
					 | 
				
			||||||
# See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
# the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
# This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
# except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
description="Loads a list of modules from systemd-compatible locations."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
depend()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
find_modfiles()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local dirs="/usr/lib/modules-load.d /run/modules-load.d /etc/modules-load.d"
 | 
					 | 
				
			||||||
	local basenames files fn x y
 | 
					 | 
				
			||||||
	for x in $dirs; do
 | 
					 | 
				
			||||||
		[ ! -d $x ] && continue
 | 
					 | 
				
			||||||
		for y in $x/*.conf; do
 | 
					 | 
				
			||||||
			[ -f $y ] && basenames="${basenames}\n${y##*/}"
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	basenames=$(printf "$basenames" | sort -u)
 | 
					 | 
				
			||||||
	for x in $basenames; do
 | 
					 | 
				
			||||||
		for y in $dirs; do
 | 
					 | 
				
			||||||
			[ -r $y/$x ] &&
 | 
					 | 
				
			||||||
				fn=$y/$x
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
		files="$files $fn"
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	echo $files
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
load_modules()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local file m modules rc x
 | 
					 | 
				
			||||||
	file=$1
 | 
					 | 
				
			||||||
	[ -z "$file" ] && return 0
 | 
					 | 
				
			||||||
	while read m x; do
 | 
					 | 
				
			||||||
		case $m in
 | 
					 | 
				
			||||||
			\;*) continue ;;
 | 
					 | 
				
			||||||
			\#*) continue ;;
 | 
					 | 
				
			||||||
			*) modules="$modules $m"
 | 
					 | 
				
			||||||
			;;
 | 
					 | 
				
			||||||
		esac
 | 
					 | 
				
			||||||
	done < $file
 | 
					 | 
				
			||||||
	for x in $modules; do
 | 
					 | 
				
			||||||
		ebegin "Loading module $x"
 | 
					 | 
				
			||||||
		case "$RC_UNAME" in
 | 
					 | 
				
			||||||
			FreeBSD) kldload "$x"; rc=$? ;;
 | 
					 | 
				
			||||||
			Linux) modprobe -q "$x"; rc=$? ;;
 | 
					 | 
				
			||||||
			*) ;;
 | 
					 | 
				
			||||||
		esac
 | 
					 | 
				
			||||||
		eend $rc "Failed to load $x"
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local x
 | 
					 | 
				
			||||||
	files=$(find_modfiles)
 | 
					 | 
				
			||||||
	for x in $files; do
 | 
					 | 
				
			||||||
		load_modules $x
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -14,8 +14,7 @@ description="Loads a user defined list of kernel modules."
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	use isapnp
 | 
						use isapnp
 | 
				
			||||||
	want modules-load
 | 
						keyword -openvz -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ description="Re-mount filesytems read-only for a clean reboot."
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	need killprocs savecache
 | 
						need killprocs savecache
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -openvz -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ depend()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	after modules
 | 
						after modules
 | 
				
			||||||
	need sysfs
 | 
						need sysfs
 | 
				
			||||||
	keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -uml -vserver
 | 
						keyword -jail -lxc -openvz -prefix -systemd-nspawn -uml -vserver
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
get_interfaces()
 | 
					get_interfaces()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@ depend()
 | 
				
			|||||||
	want $mywant	
 | 
						want $mywant	
 | 
				
			||||||
	use afc-client amd openvpn
 | 
						use afc-client amd openvpn
 | 
				
			||||||
	use dns
 | 
						use dns
 | 
				
			||||||
	keyword -docker -jail -lxc -prefix -systemd-nspawn -vserver
 | 
						keyword -jail -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
@@ -37,22 +37,13 @@ start()
 | 
				
			|||||||
	ebegin "Mounting network filesystems"
 | 
						ebegin "Mounting network filesystems"
 | 
				
			||||||
	mount -at $fs
 | 
						mount -at $fs
 | 
				
			||||||
	rc=$?
 | 
						rc=$?
 | 
				
			||||||
	if [ "$RC_UNAME" = Linux ] && [ $rc = 0 ]; then
 | 
						if [ "$RC_UNAME" = Linux ]; then
 | 
				
			||||||
		mount -a -O _netdev
 | 
							mount -a -O _netdev
 | 
				
			||||||
		rc=$?
 | 
							rc=$?
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	ewend $rc "Could not mount all network filesystems"
 | 
						ewend $rc "Could not mount all network filesystems"
 | 
				
			||||||
	if [ -z "$critical_mounts" ]; then
 | 
						if [ "$RC_UNAME" != Linux ]; then
 | 
				
			||||||
		rc=0
 | 
							rc=0
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		for x in ${critical_mounts}; do
 | 
					 | 
				
			||||||
		fstabinfo -q $x || continue
 | 
					 | 
				
			||||||
		if ! mountinfo -q $x; then
 | 
					 | 
				
			||||||
			critical=x
 | 
					 | 
				
			||||||
			eerror "Failed to mount $x"
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
		[ -z "$critical" ] && rc=0
 | 
					 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	return $rc
 | 
						return $rc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -81,7 +72,7 @@ stop()
 | 
				
			|||||||
	retval=$?
 | 
						retval=$?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eoutdent
 | 
						eoutdent
 | 
				
			||||||
	if [ "$RC_UNAME" = Linux ] && [ $retval = 0 ]; then
 | 
						if [ "$RC_UNAME" = Linux ]; then
 | 
				
			||||||
		umount -a -O _netdev
 | 
							umount -a -O _netdev
 | 
				
			||||||
		retval=$?
 | 
							retval=$?
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ ttyn=${rc_tty_number:-${RC_TTY_NUMBER:-12}}
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	need localmount
 | 
						need localmount
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -openvz -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_setleds()
 | 
					_setleds()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ depend()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	use modules devfs
 | 
						use modules devfs
 | 
				
			||||||
	need localmount
 | 
						need localmount
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -openvz -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ description="Mount the root fs read/write"
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	need fsck
 | 
						need fsck
 | 
				
			||||||
	keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -jail -openvz -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,7 +49,7 @@ start()
 | 
				
			|||||||
	fi
 | 
						fi
 | 
				
			||||||
	ebegin "Saving dependency cache"
 | 
						ebegin "Saving dependency cache"
 | 
				
			||||||
	local rc=0 save=
 | 
						local rc=0 save=
 | 
				
			||||||
	for x in deptree depconfig shutdowntime softlevel rc.log; do
 | 
						for x in deptree depconfig shutdowntime softlevel nettree rc.log; do
 | 
				
			||||||
		[ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x"
 | 
							[ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x"
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
	if [ -n "$save" ]; then
 | 
						if [ -n "$save" ]; then
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	before localmount
 | 
						before localmount
 | 
				
			||||||
	keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -jail -openvz -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	need localmount
 | 
						need localmount
 | 
				
			||||||
	keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -jail -openvz -prefix -systemd-nspawn -vserver -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ depend()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	before *
 | 
						before *
 | 
				
			||||||
	provide clock
 | 
						provide clock
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
						keyword -openvz -prefix -systemd-nspawn -uml -vserver -xenu -lxc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# swclock is an OpenRC built in
 | 
					# swclock is an OpenRC built in
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ sysfs_opts=nodev,noexec,nosuid
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	keyword -docker -lxc -prefix -systemd-nspawn -vserver
 | 
						keyword -lxc -prefix -systemd-nspawn -vserver
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mount_sys()
 | 
					mount_sys()
 | 
				
			||||||
@@ -88,15 +88,6 @@ mount_misc()
 | 
				
			|||||||
		fi
 | 
							fi
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	# Setup Kernel Support for persistent storage
 | 
					 | 
				
			||||||
	if [ -d /sys/fs/pstore ] && ! mountinfo -q /sys/fs/pstore; then
 | 
					 | 
				
			||||||
		if grep -qs 'pstore$' /proc/filesystems; then
 | 
					 | 
				
			||||||
			ebegin "Mounting persistent storage (pstore) filesystem"
 | 
					 | 
				
			||||||
			mount -t pstore pstore -o ${sysfs_opts} /sys/fs/pstore
 | 
					 | 
				
			||||||
			eend $?
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# setup up kernel support for efivarfs
 | 
						# setup up kernel support for efivarfs
 | 
				
			||||||
	# slightly complicated, as if it's build as a module but NOT yet loaded,
 | 
						# slightly complicated, as if it's build as a module but NOT yet loaded,
 | 
				
			||||||
	# it will NOT appear in /proc/filesystems yet
 | 
						# it will NOT appear in /proc/filesystems yet
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ ttyn=${rc_tty_number:-${RC_TTY_NUMBER:-12}}
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
						keyword -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
				
			||||||
	use root
 | 
						use root
 | 
				
			||||||
	after bootmisc
 | 
						after bootmisc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ description="Initializes the random number generator."
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	need localmount
 | 
						need localmount
 | 
				
			||||||
	keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn
 | 
						keyword -jail -lxc -openvz -prefix -systemd-nspawn
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
save_seed()
 | 
					save_seed()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ MAN3=		einfo.3 \
 | 
				
			|||||||
		rc_config.3 rc_deptree.3 rc_find_pids.3 rc_plugin_hook.3 \
 | 
							rc_config.3 rc_deptree.3 rc_find_pids.3 rc_plugin_hook.3 \
 | 
				
			||||||
		rc_runlevel.3 rc_service.3 rc_stringlist.3
 | 
							rc_runlevel.3 rc_service.3 rc_stringlist.3
 | 
				
			||||||
MAN8=		rc-service.8 rc-status.8 rc-update.8 openrc.8 openrc-run.8 \
 | 
					MAN8=		rc-service.8 rc-status.8 rc-update.8 openrc.8 openrc-run.8 \
 | 
				
			||||||
		service.8 start-stop-daemon.8 supervise-daemon.8
 | 
							service.8 start-stop-daemon.8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq (${OS},Linux)
 | 
					ifeq (${OS},Linux)
 | 
				
			||||||
MAN8 += rc-sstat.8
 | 
					MAN8 += rc-sstat.8
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,17 +95,10 @@ String describing the service.
 | 
				
			|||||||
.It Ar description_$command
 | 
					.It Ar description_$command
 | 
				
			||||||
String describing the extra command.
 | 
					String describing the extra command.
 | 
				
			||||||
.It Ar supervisor
 | 
					.It Ar supervisor
 | 
				
			||||||
Supervisor to use to monitor this daemon. If this is unset or invalid,
 | 
					Supervisor to use to monitor this daemon. If this is unset,
 | 
				
			||||||
start-stop-daemon will be used.
 | 
					start-stop-daemon will be used. The only alternate supervisor we support
 | 
				
			||||||
Currently, we support s6 from scarnet software, and supervise-daemon
 | 
					in this release is S6 from Skarnet software. To use this, set
 | 
				
			||||||
which is a light-weight supervisor internal to OpenRC.
 | 
					 | 
				
			||||||
To use s6, set
 | 
					 | 
				
			||||||
supervisor=s6.
 | 
					supervisor=s6.
 | 
				
			||||||
or set
 | 
					 | 
				
			||||||
supervisor=supervise-daemon
 | 
					 | 
				
			||||||
to use supervise-daemon.
 | 
					 | 
				
			||||||
Note that supervise-daemon is still in early development, so it is
 | 
					 | 
				
			||||||
considered experimental.
 | 
					 | 
				
			||||||
.It Ar s6_service_path
 | 
					.It Ar s6_service_path
 | 
				
			||||||
The path to the s6 service directory if you are monitoring this service
 | 
					The path to the s6 service directory if you are monitoring this service
 | 
				
			||||||
with S6. The default is /var/svc.d/${RC_SVCNAME}.
 | 
					with S6. The default is /var/svc.d/${RC_SVCNAME}.
 | 
				
			||||||
@@ -119,16 +112,10 @@ List of arguments passed to start-stop-daemon when starting the daemon.
 | 
				
			|||||||
.It Ar command
 | 
					.It Ar command
 | 
				
			||||||
Daemon to start or stop via
 | 
					Daemon to start or stop via
 | 
				
			||||||
.Nm start-stop-daemon
 | 
					.Nm start-stop-daemon
 | 
				
			||||||
or
 | 
					 | 
				
			||||||
.Nm supervise-daemon
 | 
					 | 
				
			||||||
if no start or stop function is defined by the service.
 | 
					if no start or stop function is defined by the service.
 | 
				
			||||||
.It Ar command_args
 | 
					.It Ar command_args
 | 
				
			||||||
List of arguments to pass to the daemon when starting via
 | 
					List of arguments to pass to the daemon when starting via
 | 
				
			||||||
.Nm start-stop-daemon .
 | 
					.Nm start-stop-daemon .
 | 
				
			||||||
.It Ar command_args_foreground
 | 
					 | 
				
			||||||
List of arguments to pass to the daemon when starting via
 | 
					 | 
				
			||||||
.Nm supervise-daemon .
 | 
					 | 
				
			||||||
to force the daemon to stay in the foreground
 | 
					 | 
				
			||||||
.It Ar command_background
 | 
					.It Ar command_background
 | 
				
			||||||
Set this to "true", "yes" or "1" (case-insensitive) to force the daemon into
 | 
					Set this to "true", "yes" or "1" (case-insensitive) to force the daemon into
 | 
				
			||||||
the background. This implies the "--make-pidfile" and "--pidfile" option of
 | 
					the background. This implies the "--make-pidfile" and "--pidfile" option of
 | 
				
			||||||
@@ -136,8 +123,6 @@ the background. This implies the "--make-pidfile" and "--pidfile" option of
 | 
				
			|||||||
so the pidfile variable must be set.
 | 
					so the pidfile variable must be set.
 | 
				
			||||||
.It Ar chroot
 | 
					.It Ar chroot
 | 
				
			||||||
.Xr start-stop-daemon 8
 | 
					.Xr start-stop-daemon 8
 | 
				
			||||||
and
 | 
					 | 
				
			||||||
.Xr supervise-daemon 8
 | 
					 | 
				
			||||||
will chroot into this path before writing the pid file or starting the daemon.
 | 
					will chroot into this path before writing the pid file or starting the daemon.
 | 
				
			||||||
.It Ar pidfile
 | 
					.It Ar pidfile
 | 
				
			||||||
Pidfile to use for the above defined command.
 | 
					Pidfile to use for the above defined command.
 | 
				
			||||||
@@ -187,9 +172,9 @@ The service will start after these services and stop before these services.
 | 
				
			|||||||
The service will start before these services and stop after these services.
 | 
					The service will start before these services and stop after these services.
 | 
				
			||||||
.It Ic provide
 | 
					.It Ic provide
 | 
				
			||||||
The service provides this virtual service. For example, named provides dns.
 | 
					The service provides this virtual service. For example, named provides dns.
 | 
				
			||||||
Note that it is not legal to have a virtual and real service with the
 | 
					Virtual services take precedence over real services, so it is highly
 | 
				
			||||||
same name. If you do this, you will receive an error message, and you
 | 
					recommended that you do not have a real service that has the same name
 | 
				
			||||||
must rename either the real or virtual service.
 | 
					as a virtual service.
 | 
				
			||||||
.It Ic config
 | 
					.It Ic config
 | 
				
			||||||
We should recalculate our dependencies if the listed files have changed.
 | 
					We should recalculate our dependencies if the listed files have changed.
 | 
				
			||||||
.It Ic keyword
 | 
					.It Ic keyword
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,14 +20,6 @@
 | 
				
			|||||||
.Ar service cmd
 | 
					.Ar service cmd
 | 
				
			||||||
.Op Ar ...
 | 
					.Op Ar ...
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
.Op Fl I , -ifinactive
 | 
					 | 
				
			||||||
.Ar service cmd
 | 
					 | 
				
			||||||
.Op Ar ...
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Op Fl N , -ifnotstarted
 | 
					 | 
				
			||||||
.Ar service cmd
 | 
					 | 
				
			||||||
.Op Ar ...
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Fl e , -exists
 | 
					.Fl e , -exists
 | 
				
			||||||
.Ar service
 | 
					.Ar service
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
@@ -44,13 +36,6 @@ If
 | 
				
			|||||||
is given then
 | 
					is given then
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
returns 0 even if the service does not exist.
 | 
					returns 0 even if the service does not exist.
 | 
				
			||||||
If
 | 
					 | 
				
			||||||
.Fl I , -ifinactive
 | 
					 | 
				
			||||||
or
 | 
					 | 
				
			||||||
.Fl N , -ifnotstarted
 | 
					 | 
				
			||||||
is given then
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
returns 0 if the service exists but is in the wrong state.
 | 
					 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
If given the
 | 
					If given the
 | 
				
			||||||
.Fl l , -list
 | 
					.Fl l , -list
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,142 +0,0 @@
 | 
				
			|||||||
.\" Copyright (c) 2007-2015 The OpenRC Authors.
 | 
					 | 
				
			||||||
.\" See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
.\" https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
.\"
 | 
					 | 
				
			||||||
.\" This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
.\" the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
.\" distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
.\" This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
.\"    except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
.\"
 | 
					 | 
				
			||||||
.Dd April 27, 2016
 | 
					 | 
				
			||||||
.Dt supervise-DAEMON 8 SMM
 | 
					 | 
				
			||||||
.Os OpenRC
 | 
					 | 
				
			||||||
.Sh NAME
 | 
					 | 
				
			||||||
.Nm supervise-daemon
 | 
					 | 
				
			||||||
.Nd starts a daemon and restarts it if it crashes
 | 
					 | 
				
			||||||
.Sh SYNOPSIS
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Fl d , -chdir
 | 
					 | 
				
			||||||
.Ar path
 | 
					 | 
				
			||||||
.Fl e , -env
 | 
					 | 
				
			||||||
.Ar var=value
 | 
					 | 
				
			||||||
.Fl g , -group
 | 
					 | 
				
			||||||
.Ar group
 | 
					 | 
				
			||||||
.Fl I , -ionice
 | 
					 | 
				
			||||||
.Ar arg
 | 
					 | 
				
			||||||
.Fl k , -umask
 | 
					 | 
				
			||||||
.Ar value
 | 
					 | 
				
			||||||
.Fl N , -nicelevel
 | 
					 | 
				
			||||||
.Ar level
 | 
					 | 
				
			||||||
.Fl p , -pidfile
 | 
					 | 
				
			||||||
.Ar pidfile
 | 
					 | 
				
			||||||
.Fl u , -user
 | 
					 | 
				
			||||||
.Ar user
 | 
					 | 
				
			||||||
.Fl r , -chroot
 | 
					 | 
				
			||||||
.Ar chrootpath
 | 
					 | 
				
			||||||
.Fl 1 , -stdout
 | 
					 | 
				
			||||||
.Ar logfile
 | 
					 | 
				
			||||||
.Fl 2 , -stderr
 | 
					 | 
				
			||||||
.Ar logfile
 | 
					 | 
				
			||||||
.Fl S , -start
 | 
					 | 
				
			||||||
.Ar daemon
 | 
					 | 
				
			||||||
.Op Fl -
 | 
					 | 
				
			||||||
.Op Ar arguments
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Fl K , -stop
 | 
					 | 
				
			||||||
.Ar daemon
 | 
					 | 
				
			||||||
.Fl p , -pidfile
 | 
					 | 
				
			||||||
.Ar pidfile
 | 
					 | 
				
			||||||
.Fl r , -chroot
 | 
					 | 
				
			||||||
.Ar chrootpath
 | 
					 | 
				
			||||||
.Sh DESCRIPTION
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
provides a consistent method of starting, stopping and restarting
 | 
					 | 
				
			||||||
daemons. If
 | 
					 | 
				
			||||||
.Fl K , -stop
 | 
					 | 
				
			||||||
is not provided, then we assume we are starting the daemon.
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
only works with daemons which do not fork. Also, it uses its own pid
 | 
					 | 
				
			||||||
file, so the daemon should not write a pid file, or the pid file passed
 | 
					 | 
				
			||||||
to 
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
should not be the one the daemon writes.
 | 
					 | 
				
			||||||
.Pp
 | 
					 | 
				
			||||||
Here are the options to specify the daemon and how it should start or stop:
 | 
					 | 
				
			||||||
.Bl -tag -width indent
 | 
					 | 
				
			||||||
.It Fl p , -pidfile Ar pidfile
 | 
					 | 
				
			||||||
When starting, we write a
 | 
					 | 
				
			||||||
.Ar pidfile
 | 
					 | 
				
			||||||
so we know which supervisor to stop.  When stopping we only stop the pid(s)
 | 
					 | 
				
			||||||
listed in the
 | 
					 | 
				
			||||||
.Ar pidfile .
 | 
					 | 
				
			||||||
.It Fl u , -user Ar user Ns Op : Ns Ar group
 | 
					 | 
				
			||||||
Start the daemon as the
 | 
					 | 
				
			||||||
.Ar user
 | 
					 | 
				
			||||||
and update $HOME accordingly or stop daemons
 | 
					 | 
				
			||||||
owned by the user. You can optionally append a
 | 
					 | 
				
			||||||
.Ar group
 | 
					 | 
				
			||||||
name here also.
 | 
					 | 
				
			||||||
.It Fl v , -verbose
 | 
					 | 
				
			||||||
Print the action(s) that are taken just before doing them.
 | 
					 | 
				
			||||||
.Pp
 | 
					 | 
				
			||||||
The options are as follows:
 | 
					 | 
				
			||||||
.Bl -tag -width indent
 | 
					 | 
				
			||||||
.It Fl d , -chdir Ar path
 | 
					 | 
				
			||||||
chdir to this directory before starting the daemon.
 | 
					 | 
				
			||||||
.It Fl e , -env Ar VAR=VALUE
 | 
					 | 
				
			||||||
Set the environment variable VAR to VALUE.
 | 
					 | 
				
			||||||
.It Fl g , -group Ar group
 | 
					 | 
				
			||||||
Start the daemon as in the group.
 | 
					 | 
				
			||||||
.It Fl I , -ionice Ar class Ns Op : Ns Ar data
 | 
					 | 
				
			||||||
Modifies the IO scheduling priority of the daemon.
 | 
					 | 
				
			||||||
Class can be 0 for none, 1 for real time, 2 for best effort and 3 for idle.
 | 
					 | 
				
			||||||
Data can be from 0 to 7 inclusive.
 | 
					 | 
				
			||||||
.It Fl k , -umask Ar mode
 | 
					 | 
				
			||||||
Set the umask of the daemon.
 | 
					 | 
				
			||||||
.It Fl N , -nicelevel Ar level
 | 
					 | 
				
			||||||
Modifies the scheduling priority of the daemon.
 | 
					 | 
				
			||||||
.It Fl r , -chroot Ar path
 | 
					 | 
				
			||||||
chroot to this directory before starting the daemon. All other paths, such
 | 
					 | 
				
			||||||
as the path to the daemon, chdir and pidfile, should be relative to the chroot.
 | 
					 | 
				
			||||||
.It Fl u , -user Ar user
 | 
					 | 
				
			||||||
Start the daemon as the specified user.
 | 
					 | 
				
			||||||
.It Fl 1 , -stdout Ar logfile
 | 
					 | 
				
			||||||
Redirect the standard output of the process to logfile.
 | 
					 | 
				
			||||||
Must be an absolute pathname, but relative to the path optionally given with
 | 
					 | 
				
			||||||
.Fl r , -chroot .
 | 
					 | 
				
			||||||
The logfile can also be a named pipe.
 | 
					 | 
				
			||||||
.It Fl 2 , -stderr Ar logfile
 | 
					 | 
				
			||||||
The same thing as
 | 
					 | 
				
			||||||
.Fl 1 , -stdout
 | 
					 | 
				
			||||||
but with the standard error output.
 | 
					 | 
				
			||||||
.El
 | 
					 | 
				
			||||||
.Sh ENVIRONMENT
 | 
					 | 
				
			||||||
.Va SSD_NICELEVEL
 | 
					 | 
				
			||||||
can also set the scheduling priority of the daemon, but the command line
 | 
					 | 
				
			||||||
option takes precedence.
 | 
					 | 
				
			||||||
.Sh NOTE
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
uses
 | 
					 | 
				
			||||||
.Xr getopt 3
 | 
					 | 
				
			||||||
to parse its options, which allows it to accept the `--' option which will
 | 
					 | 
				
			||||||
cause it to stop processing options at that point. Any subsequent arguments
 | 
					 | 
				
			||||||
are passed as arguments to the daemon to start and used when finding a daemon
 | 
					 | 
				
			||||||
to stop or signal.
 | 
					 | 
				
			||||||
.Sh SEE ALSO
 | 
					 | 
				
			||||||
.Xr chdir 2 ,
 | 
					 | 
				
			||||||
.Xr chroot 2 ,
 | 
					 | 
				
			||||||
.Xr getopt 3 ,
 | 
					 | 
				
			||||||
.Xr nice 2 ,
 | 
					 | 
				
			||||||
.Xr rc_find_pids 3
 | 
					 | 
				
			||||||
.Sh BUGS
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
cannot stop an interpreted daemon that no longer exists without a pidfile.
 | 
					 | 
				
			||||||
.Sh HISTORY
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
first appeared in Debian.
 | 
					 | 
				
			||||||
.Pp
 | 
					 | 
				
			||||||
This is a complete re-implementation with the process finding code in the
 | 
					 | 
				
			||||||
OpenRC library (librc, -lrc) so other programs can make use of it.
 | 
					 | 
				
			||||||
.Sh AUTHORS
 | 
					 | 
				
			||||||
.An William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
@@ -3,6 +3,4 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
ifeq (${MKPREFIX},yes)
 | 
					ifeq (${MKPREFIX},yes)
 | 
				
			||||||
CPPFLAGS+=	-DPREFIX
 | 
					CPPFLAGS+=	-DPREFIX
 | 
				
			||||||
PKG_PREFIX?=	$(PREFIX)/usr
 | 
					 | 
				
			||||||
SED_EXTRA=	-e '/_PATH=.*usr.bin/d'
 | 
					 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								mk/os.mk
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								mk/os.mk
									
									
									
									
									
								
							@@ -13,7 +13,7 @@
 | 
				
			|||||||
_OS_SH=		uname -s | tr '/' '-'
 | 
					_OS_SH=		uname -s | tr '/' '-'
 | 
				
			||||||
_OS:= 		$(shell ${_OS_SH})
 | 
					_OS:= 		$(shell ${_OS_SH})
 | 
				
			||||||
OS?= 		${_OS}
 | 
					OS?= 		${_OS}
 | 
				
			||||||
include ${MK}/os-prefix.mk
 | 
					 | 
				
			||||||
include ${MK}/os-${OS}.mk
 | 
					include ${MK}/os-${OS}.mk
 | 
				
			||||||
 | 
					include ${MK}/os-prefix.mk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RC_LIB=		/$(LIBNAME)/rc
 | 
					RC_LIB=		/$(LIBNAME)/rc
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
AR?=			ar
 | 
					AR?=			ar
 | 
				
			||||||
CP?=			cp
 | 
					CP?=			cp
 | 
				
			||||||
PKG_CONFIG?=	pkg-config
 | 
					 | 
				
			||||||
ECHO?=			echo
 | 
					ECHO?=			echo
 | 
				
			||||||
INSTALL?=		install
 | 
					INSTALL?=		install
 | 
				
			||||||
RANLIB?=		ranlib
 | 
					RANLIB?=		ranlib
 | 
				
			||||||
@@ -27,7 +26,7 @@ ifeq (${MKPREFIX},yes)
 | 
				
			|||||||
UPREFIX= ${PREFIX}/usr
 | 
					UPREFIX= ${PREFIX}/usr
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
LOCAL_PREFIX=		$(UPREFIX)/local
 | 
					LOCAL_PREFIX=		/usr/local
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PICFLAG?=		-fPIC
 | 
					PICFLAG?=		-fPIC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
ifeq (${MKTERMCAP},ncurses)
 | 
					ifeq (${MKTERMCAP},ncurses)
 | 
				
			||||||
TERMCAP_CFLAGS:=	$(shell ${PKG_CONFIG} ncurses --cflags 2> /dev/null)
 | 
					TERMCAP_CFLAGS:=	$(shell pkg-config ncurses --cflags 2> /dev/null)
 | 
				
			||||||
LTERMCAP:=			$(shell ${PKG_CONFIG} ncurses --libs 2> /dev/null)
 | 
					LTERMCAP:=			$(shell pkg-config ncurses --libs 2> /dev/null)
 | 
				
			||||||
ifeq ($(LTERMCAP),)
 | 
					ifeq ($(LTERMCAP),)
 | 
				
			||||||
LIBTERMCAP?=	-lncurses
 | 
					LIBTERMCAP?=	-lncurses
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,6 @@ include ../mk/net.mk
 | 
				
			|||||||
BOOT=		bootmisc fsck hostname localmount loopback \
 | 
					BOOT=		bootmisc fsck hostname localmount loopback \
 | 
				
			||||||
		root swap swapfiles sysctl urandom ${BOOT-${OS}}
 | 
							root swap swapfiles sysctl urandom ${BOOT-${OS}}
 | 
				
			||||||
DEFAULT=	local netmount
 | 
					DEFAULT=	local netmount
 | 
				
			||||||
NONETWORK=	local
 | 
					 | 
				
			||||||
SHUTDOWN=	savecache ${SHUTDOWN-${OS}}
 | 
					SHUTDOWN=	savecache ${SHUTDOWN-${OS}}
 | 
				
			||||||
SYSINIT=	${SYSINIT-${OS}}
 | 
					SYSINIT=	${SYSINIT-${OS}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -11,7 +10,6 @@ LEVELDIR=	${DESTDIR}/${SYSCONFDIR}/runlevels
 | 
				
			|||||||
SYSINITDIR=	${LEVELDIR}/sysinit
 | 
					SYSINITDIR=	${LEVELDIR}/sysinit
 | 
				
			||||||
BOOTDIR=	${LEVELDIR}/boot
 | 
					BOOTDIR=	${LEVELDIR}/boot
 | 
				
			||||||
DEFAULTDIR=	${LEVELDIR}/default
 | 
					DEFAULTDIR=	${LEVELDIR}/default
 | 
				
			||||||
NONETWORKDIR=	${LEVELDIR}/nonetwork
 | 
					 | 
				
			||||||
SHUTDOWNDIR=	${LEVELDIR}/shutdown
 | 
					SHUTDOWNDIR=	${LEVELDIR}/shutdown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq (${MKNET},yes)
 | 
					ifeq (${MKNET},yes)
 | 
				
			||||||
@@ -74,14 +72,6 @@ install:
 | 
				
			|||||||
			fi; \
 | 
								fi; \
 | 
				
			||||||
			ln -snf ${INITDIR}/"$$x" ${DEFAULTDIR}/"$$x" || exit $$?; done \
 | 
								ln -snf ${INITDIR}/"$$x" ${DEFAULTDIR}/"$$x" || exit $$?; done \
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	if ! test -d "${NONETWORKDIR}"; then \
 | 
					 | 
				
			||||||
		${INSTALL} -d ${NONETWORKDIR} || exit $$?; \
 | 
					 | 
				
			||||||
		for x in ${NONETWORK}; do \
 | 
					 | 
				
			||||||
			if test "${MKPREFIX}" = yes; then \
 | 
					 | 
				
			||||||
				grep -q "keyword .*-prefix" ${INITFILES}/"$$x" && continue; \
 | 
					 | 
				
			||||||
			fi; \
 | 
					 | 
				
			||||||
			ln -snf ${INITDIR}/"$$x" ${NONETWORKDIR}/"$$x" || exit $$?; done \
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	if ! test -d "${SHUTDOWNDIR}"; then \
 | 
						if ! test -d "${SHUTDOWNDIR}"; then \
 | 
				
			||||||
		${INSTALL} -d ${SHUTDOWNDIR} || exit $$?; \
 | 
							${INSTALL} -d ${SHUTDOWNDIR} || exit $$?; \
 | 
				
			||||||
		for x in ${SHUTDOWN}; do \
 | 
							for x in ${SHUTDOWN}; do \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,7 @@
 | 
				
			|||||||
DIR=	${LIBEXECDIR}/sh
 | 
					DIR=	${LIBEXECDIR}/sh
 | 
				
			||||||
SRCS=	init.sh.in functions.sh.in gendepends.sh.in \
 | 
					SRCS=	init.sh.in functions.sh.in gendepends.sh.in \
 | 
				
			||||||
	openrc-run.sh.in rc-functions.sh.in tmpfiles.sh.in ${SRCS-${OS}}
 | 
						openrc-run.sh.in rc-functions.sh.in tmpfiles.sh.in ${SRCS-${OS}}
 | 
				
			||||||
INC=	functions.sh rc-mount.sh rc-functions.sh s6.sh start-stop-daemon.sh \
 | 
					INC=	rc-mount.sh functions.sh rc-functions.sh s6.sh start-stop-daemon.sh
 | 
				
			||||||
		supervise-daemon.sh
 | 
					 | 
				
			||||||
BIN=	gendepends.sh init.sh openrc-run.sh tmpfiles.sh ${BIN-${OS}}
 | 
					BIN=	gendepends.sh init.sh openrc-run.sh tmpfiles.sh ${BIN-${OS}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INSTALLAFTER=	_installafter
 | 
					INSTALLAFTER=	_installafter
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ apply_file() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	### FILE FORMAT ###
 | 
						### FILE FORMAT ###
 | 
				
			||||||
	# See https://www.kernel.org/doc/Documentation/binfmt_misc.txt
 | 
						# See https://www.kernel.org/doc/Documentation/binfmt_misc.txt
 | 
				
			||||||
	while read -r line; do
 | 
						while read line; do
 | 
				
			||||||
		LINENUM=$(( LINENUM+1 ))
 | 
							LINENUM=$(( LINENUM+1 ))
 | 
				
			||||||
		case $line in
 | 
							case $line in
 | 
				
			||||||
			\#*) continue ;;
 | 
								\#*) continue ;;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,7 +154,6 @@ start()
 | 
				
			|||||||
	local func=ssd_start
 | 
						local func=ssd_start
 | 
				
			||||||
	case "$supervisor" in
 | 
						case "$supervisor" in
 | 
				
			||||||
		s6) func=s6_start ;;
 | 
							s6) func=s6_start ;;
 | 
				
			||||||
		supervise-daemon) func=supervise_start ;;
 | 
					 | 
				
			||||||
		?*)
 | 
							?*)
 | 
				
			||||||
			ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
 | 
								ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
 | 
				
			||||||
			;;
 | 
								;;
 | 
				
			||||||
@@ -167,7 +166,6 @@ stop()
 | 
				
			|||||||
	local func=ssd_stop
 | 
						local func=ssd_stop
 | 
				
			||||||
	case "$supervisor" in
 | 
						case "$supervisor" in
 | 
				
			||||||
		s6) func=s6_stop ;;
 | 
							s6) func=s6_stop ;;
 | 
				
			||||||
		supervise-daemon) func=supervise_stop ;;
 | 
					 | 
				
			||||||
		?*)
 | 
							?*)
 | 
				
			||||||
			ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
 | 
								ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
 | 
				
			||||||
			;;
 | 
								;;
 | 
				
			||||||
@@ -180,7 +178,6 @@ status()
 | 
				
			|||||||
	local func=ssd_status
 | 
						local func=ssd_status
 | 
				
			||||||
	case "$supervisor" in
 | 
						case "$supervisor" in
 | 
				
			||||||
		s6) func=s6_status ;;
 | 
							s6) func=s6_status ;;
 | 
				
			||||||
		supervise-daemon) func=supervise_status ;;
 | 
					 | 
				
			||||||
		?*)
 | 
							?*)
 | 
				
			||||||
			ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
 | 
								ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
 | 
				
			||||||
			;;
 | 
								;;
 | 
				
			||||||
@@ -218,7 +215,6 @@ fi
 | 
				
			|||||||
# load service supervisor functions
 | 
					# load service supervisor functions
 | 
				
			||||||
sourcex "@LIBEXECDIR@/sh/s6.sh"
 | 
					sourcex "@LIBEXECDIR@/sh/s6.sh"
 | 
				
			||||||
sourcex "@LIBEXECDIR@/sh/start-stop-daemon.sh"
 | 
					sourcex "@LIBEXECDIR@/sh/start-stop-daemon.sh"
 | 
				
			||||||
sourcex "@LIBEXECDIR@/sh/supervise-daemon.sh"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Set verbose mode
 | 
					# Set verbose mode
 | 
				
			||||||
if yesno "${rc_verbose:-$RC_VERBOSE}"; then
 | 
					if yesno "${rc_verbose:-$RC_VERBOSE}"; then
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								sh/s6.sh
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								sh/s6.sh
									
									
									
									
									
								
							@@ -41,7 +41,7 @@ s6_stop()
 | 
				
			|||||||
 fi
 | 
					 fi
 | 
				
			||||||
	s6_service_link="${RC_SVCDIR}/s6-scan/${s6_service_path##*/}"
 | 
						s6_service_link="${RC_SVCDIR}/s6-scan/${s6_service_path##*/}"
 | 
				
			||||||
	ebegin "Stopping ${name:-$RC_SVCNAME}"
 | 
						ebegin "Stopping ${name:-$RC_SVCNAME}"
 | 
				
			||||||
	s6-svc -wD -d -T ${s6_service_timeout_stop:-10000} "${s6_service_link}"
 | 
						s6-svc -Dd -T ${s6_service_timeout_stop:-10000} "${s6_service_link}"
 | 
				
			||||||
	set -- $(s6-svstat "${s6_service_link}")
 | 
						set -- $(s6-svstat "${s6_service_link}")
 | 
				
			||||||
	[ "$1" = "down" ]
 | 
						[ "$1" = "down" ]
 | 
				
			||||||
	eend $? "Failed to stop $RC_SVCNAME"
 | 
						eend $? "Failed to stop $RC_SVCNAME"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,7 +40,6 @@ ssd_start()
 | 
				
			|||||||
	fi
 | 
						fi
 | 
				
			||||||
	eval start-stop-daemon --start \
 | 
						eval start-stop-daemon --start \
 | 
				
			||||||
		--exec $command \
 | 
							--exec $command \
 | 
				
			||||||
		${chroot:+--chroot} $chroot \
 | 
					 | 
				
			||||||
		${procname:+--name} $procname \
 | 
							${procname:+--name} $procname \
 | 
				
			||||||
		${pidfile:+--pidfile} $pidfile \
 | 
							${pidfile:+--pidfile} $pidfile \
 | 
				
			||||||
		${command_user+--user} $command_user \
 | 
							${command_user+--user} $command_user \
 | 
				
			||||||
@@ -48,7 +47,6 @@ ssd_start()
 | 
				
			|||||||
		-- $command_args $command_args_background
 | 
							-- $command_args $command_args_background
 | 
				
			||||||
	if eend $? "Failed to start $RC_SVCNAME"; then
 | 
						if eend $? "Failed to start $RC_SVCNAME"; then
 | 
				
			||||||
		service_set_value "command" "${command}"
 | 
							service_set_value "command" "${command}"
 | 
				
			||||||
		[ -n "${chroot}" ] && service_set_value "chroot" "${chroot}"
 | 
					 | 
				
			||||||
		[ -n "${pidfile}" ] && service_set_value "pidfile" "${pidfile}"
 | 
							[ -n "${pidfile}" ] && service_set_value "pidfile" "${pidfile}"
 | 
				
			||||||
		[ -n "${procname}" ] && service_set_value "procname" "${procname}"
 | 
							[ -n "${procname}" ] && service_set_value "procname" "${procname}"
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
@@ -64,11 +62,9 @@ ssd_start()
 | 
				
			|||||||
ssd_stop()
 | 
					ssd_stop()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local startcommand="$(service_get_value "command")"
 | 
						local startcommand="$(service_get_value "command")"
 | 
				
			||||||
	local startchroot="$(service_get_value "chroot")"
 | 
					 | 
				
			||||||
	local startpidfile="$(service_get_value "pidfile")"
 | 
						local startpidfile="$(service_get_value "pidfile")"
 | 
				
			||||||
	local startprocname="$(service_get_value "procname")"
 | 
						local startprocname="$(service_get_value "procname")"
 | 
				
			||||||
	command="${startcommand:-$command}"
 | 
						command="${startcommand:-$command}"
 | 
				
			||||||
	chroot="${startchroot:-$chroot}"
 | 
					 | 
				
			||||||
	pidfile="${startpidfile:-$pidfile}"
 | 
						pidfile="${startpidfile:-$pidfile}"
 | 
				
			||||||
	procname="${startprocname:-$procname}"
 | 
						procname="${startprocname:-$procname}"
 | 
				
			||||||
	[ -n "$command" -o -n "$procname" -o -n "$pidfile" ] || return 0
 | 
						[ -n "$command" -o -n "$procname" -o -n "$pidfile" ] || return 0
 | 
				
			||||||
@@ -77,7 +73,7 @@ ssd_stop()
 | 
				
			|||||||
		${retry:+--retry} $retry \
 | 
							${retry:+--retry} $retry \
 | 
				
			||||||
		${command:+--exec} $command \
 | 
							${command:+--exec} $command \
 | 
				
			||||||
		${procname:+--name} $procname \
 | 
							${procname:+--name} $procname \
 | 
				
			||||||
		${pidfile:+--pidfile} $chroot$pidfile \
 | 
							${pidfile:+--pidfile} $pidfile \
 | 
				
			||||||
		${stopsig:+--signal} $stopsig
 | 
							${stopsig:+--signal} $stopsig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eend $? "Failed to stop $RC_SVCNAME"
 | 
						eend $? "Failed to stop $RC_SVCNAME"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,55 +0,0 @@
 | 
				
			|||||||
# start / stop / status functions for supervise-daemon
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Copyright (c) 2016 The OpenRC Authors.
 | 
					 | 
				
			||||||
# See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
# the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
# This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
#    except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
supervise_start()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if [ -z "$command" ]; then
 | 
					 | 
				
			||||||
		ewarn "The command variable is undefined."
 | 
					 | 
				
			||||||
		ewarn "There is nothing for ${name:-$RC_SVCNAME} to start."
 | 
					 | 
				
			||||||
		return 1
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ebegin "Starting ${name:-$RC_SVCNAME}"
 | 
					 | 
				
			||||||
	eval supervise-daemon --start \
 | 
					 | 
				
			||||||
		${chroot:+--chroot} $chroot \
 | 
					 | 
				
			||||||
		${pidfile:+--pidfile} $pidfile \
 | 
					 | 
				
			||||||
		${command_user+--user} $command_user \
 | 
					 | 
				
			||||||
		$supervise_daemon_args \
 | 
					 | 
				
			||||||
		$command \
 | 
					 | 
				
			||||||
		-- $command_args $command_args_foreground
 | 
					 | 
				
			||||||
	rc=$?
 | 
					 | 
				
			||||||
	if [ $rc = 0 ]; then
 | 
					 | 
				
			||||||
		[ -n "${chroot}" ] && service_set_value "chroot" "${chroot}"
 | 
					 | 
				
			||||||
		[ -n "${pidfile}" ] && service_set_value "pidfile" "${pidfile}"
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	eend $rc "failed to start $RC_SVCNAME"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
supervise_stop()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local startchroot="$(service_get_value "chroot")"
 | 
					 | 
				
			||||||
	local startpidfile="$(service_get_value "pidfile")"
 | 
					 | 
				
			||||||
	chroot="${startchroot:-$chroot}"
 | 
					 | 
				
			||||||
	pidfile="${startpidfile:-$pidfile}"
 | 
					 | 
				
			||||||
	[ -n "$pidfile" ] || return 0
 | 
					 | 
				
			||||||
	ebegin "Stopping ${name:-$RC_SVCNAME}"
 | 
					 | 
				
			||||||
	supervise-daemon --stop \
 | 
					 | 
				
			||||||
		${pidfile:+--pidfile} $chroot$pidfile \
 | 
					 | 
				
			||||||
		${stopsig:+--signal} $stopsig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	eend $? "Failed to stop $RC_SVCNAME"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
supervise_status()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	_status
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -26,6 +26,7 @@
 | 
				
			|||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "helpers.h"
 | 
					#include "helpers.h"
 | 
				
			||||||
 | 
					#include "rc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RC_LEVEL_BOOT           "boot"
 | 
					#define RC_LEVEL_BOOT           "boot"
 | 
				
			||||||
#define RC_LEVEL_DEFAULT        "default"
 | 
					#define RC_LEVEL_DEFAULT        "default"
 | 
				
			||||||
@@ -60,6 +61,10 @@ int is_writable(const char *);
 | 
				
			|||||||
#define service_stop(service)  exec_service(service, "stop");
 | 
					#define service_stop(service)  exec_service(service, "stop");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int parse_mode(mode_t *, char *);
 | 
					int parse_mode(mode_t *, char *);
 | 
				
			||||||
 | 
					const char *detect_prefix(void);
 | 
				
			||||||
 | 
					const char *get_systype(void);
 | 
				
			||||||
 | 
					const char *detect_container(void);
 | 
				
			||||||
 | 
					const char *detect_vm(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Handy function so we can wrap einfo around our deptree */
 | 
					/* Handy function so we can wrap einfo around our deptree */
 | 
				
			||||||
RC_DEPTREE *_rc_deptree_load (int, int *);
 | 
					RC_DEPTREE *_rc_deptree_load (int, int *);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -717,16 +717,14 @@ rc_deptree_update_needed(time_t *newest, char *file)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
librc_hidden_def(rc_deptree_update_needed)
 | 
					librc_hidden_def(rc_deptree_update_needed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This is a 7 phase operation
 | 
					/* This is a 6 phase operation
 | 
				
			||||||
   Phase 1 is a shell script which loads each init script and config in turn
 | 
					   Phase 1 is a shell script which loads each init script and config in turn
 | 
				
			||||||
   and echos their dependency info to stdout
 | 
					   and echos their dependency info to stdout
 | 
				
			||||||
   Phase 2 takes that and populates a depinfo object with that data
 | 
					   Phase 2 takes that and populates a depinfo object with that data
 | 
				
			||||||
   Phase 3 adds any provided services to the depinfo object
 | 
					   Phase 3 adds any provided services to the depinfo object
 | 
				
			||||||
   Phase 4 scans that depinfo object and puts in backlinks
 | 
					   Phase 4 scans that depinfo object and puts in backlinks
 | 
				
			||||||
   Phase 5 removes broken before dependencies
 | 
					   Phase 5 removes broken before dependencies
 | 
				
			||||||
   Phase 6 looks for duplicate services indicating a real and virtual service
 | 
					   Phase 6 saves the depinfo object to disk
 | 
				
			||||||
   with the same names
 | 
					 | 
				
			||||||
   Phase 7 saves the depinfo object to disk
 | 
					 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
bool
 | 
					bool
 | 
				
			||||||
rc_deptree_update(void)
 | 
					rc_deptree_update(void)
 | 
				
			||||||
@@ -735,16 +733,15 @@ rc_deptree_update(void)
 | 
				
			|||||||
	RC_DEPTREE *deptree, *providers;
 | 
						RC_DEPTREE *deptree, *providers;
 | 
				
			||||||
	RC_DEPINFO *depinfo = NULL, *depinfo_np, *di;
 | 
						RC_DEPINFO *depinfo = NULL, *depinfo_np, *di;
 | 
				
			||||||
	RC_DEPTYPE *deptype = NULL, *dt_np, *dt, *provide;
 | 
						RC_DEPTYPE *deptype = NULL, *dt_np, *dt, *provide;
 | 
				
			||||||
	RC_STRINGLIST *config, *dupes, *types, *sorted, *visited;
 | 
						RC_STRINGLIST *config, *types, *sorted, *visited;
 | 
				
			||||||
	RC_STRING *s, *s2, *s2_np, *s3, *s4;
 | 
						RC_STRING *s, *s2, *s2_np, *s3, *s4;
 | 
				
			||||||
	char *line = NULL;
 | 
						char *line = NULL;
 | 
				
			||||||
	size_t len = 0;
 | 
						size_t len = 0;
 | 
				
			||||||
	char *depend, *depends, *service, *type, *nosys, *onosys;
 | 
						char *depend, *depends, *service, *type, *nosys, *onosys;
 | 
				
			||||||
	size_t i, k, l;
 | 
						size_t i, k, l;
 | 
				
			||||||
	bool retval = true;
 | 
						bool retval = true;
 | 
				
			||||||
	const char *sys = rc_sys();
 | 
						const char *sys = NULL;
 | 
				
			||||||
	struct utsname uts;
 | 
						struct utsname uts;
 | 
				
			||||||
	int serrno;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Some init scripts need RC_LIBEXECDIR to source stuff
 | 
						/* Some init scripts need RC_LIBEXECDIR to source stuff
 | 
				
			||||||
	   Ideally we should be setting our full env instead */
 | 
						   Ideally we should be setting our full env instead */
 | 
				
			||||||
@@ -850,6 +847,9 @@ rc_deptree_update(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Phase 2 - if we're a special system, remove services that don't
 | 
						/* Phase 2 - if we're a special system, remove services that don't
 | 
				
			||||||
	 * work for them. This doesn't stop them from being run directly. */
 | 
						 * work for them. This doesn't stop them from being run directly. */
 | 
				
			||||||
 | 
						sys = detect_container();
 | 
				
			||||||
 | 
							if (!sys)
 | 
				
			||||||
 | 
								sys = detect_vm();
 | 
				
			||||||
	if (sys) {
 | 
						if (sys) {
 | 
				
			||||||
		len = strlen(sys);
 | 
							len = strlen(sys);
 | 
				
			||||||
		nosys = xmalloc(len + 2);
 | 
							nosys = xmalloc(len + 2);
 | 
				
			||||||
@@ -999,22 +999,7 @@ rc_deptree_update(void)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	rc_stringlist_free(types);
 | 
						rc_stringlist_free(types);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Phase 6 - Print errors for duplicate services */
 | 
						/* Phase 6 - save to disk
 | 
				
			||||||
	dupes = rc_stringlist_new();
 | 
					 | 
				
			||||||
	TAILQ_FOREACH(depinfo, deptree, entries) {
 | 
					 | 
				
			||||||
		serrno = errno;
 | 
					 | 
				
			||||||
		errno = 0;
 | 
					 | 
				
			||||||
		rc_stringlist_addu(dupes,depinfo->service);
 | 
					 | 
				
			||||||
		if (errno == EEXIST) {
 | 
					 | 
				
			||||||
			fprintf(stderr,
 | 
					 | 
				
			||||||
					"Error: %s is the name of a real and virtual service.\n",
 | 
					 | 
				
			||||||
					depinfo->service);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		errno = serrno;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rc_stringlist_free(dupes);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Phase 7 - save to disk
 | 
					 | 
				
			||||||
	   Now that we're purely in C, do we need to keep a shell parseable file?
 | 
						   Now that we're purely in C, do we need to keep a shell parseable file?
 | 
				
			||||||
	   I think yes as then it stays human readable
 | 
						   I think yes as then it stays human readable
 | 
				
			||||||
	   This works and should be entirely shell parseable provided that depend
 | 
						   This works and should be entirely shell parseable provided that depend
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -198,9 +198,13 @@ found:
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *
 | 
					const char *
 | 
				
			||||||
get_systype(void)
 | 
					rc_sys(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifdef PREFIX
 | 
				
			||||||
 | 
						return RC_SYS_PREFIX;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *systype = rc_conf_value("rc_sys");
 | 
						char *systype = rc_conf_value("rc_sys");
 | 
				
			||||||
	if (systype) {
 | 
						if (systype) {
 | 
				
			||||||
		char *s = systype;
 | 
							char *s = systype;
 | 
				
			||||||
@@ -211,37 +215,10 @@ get_systype(void)
 | 
				
			|||||||
			s++;
 | 
								s++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return systype;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *
 | 
					 | 
				
			||||||
detect_prefix(const char *systype)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#ifdef PREFIX
 | 
					 | 
				
			||||||
	return RC_SYS_PREFIX;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	if (systype) {
 | 
					 | 
				
			||||||
		if (strcmp(systype, RC_SYS_NONE) == 0)
 | 
					 | 
				
			||||||
			return NULL;
 | 
					 | 
				
			||||||
		if (strcmp(systype, RC_SYS_PREFIX) == 0)
 | 
					 | 
				
			||||||
			return RC_SYS_PREFIX;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char *
 | 
					 | 
				
			||||||
detect_container(const char *systype)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#ifdef __FreeBSD__
 | 
					#ifdef __FreeBSD__
 | 
				
			||||||
	if (systype) {
 | 
						if (systype && strcmp(systype, RC_SYS_JAIL) == 0)
 | 
				
			||||||
		if (strcmp(systype, RC_SYS_NONE) == 0)
 | 
					 | 
				
			||||||
		       return NULL;
 | 
					 | 
				
			||||||
		if (strcmp(systype, RC_SYS_JAIL) == 0)
 | 
					 | 
				
			||||||
		return RC_SYS_JAIL;
 | 
							return RC_SYS_JAIL;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int jailed = 0;
 | 
						int jailed = 0;
 | 
				
			||||||
	size_t len = sizeof(jailed);
 | 
						size_t len = sizeof(jailed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -250,10 +227,25 @@ detect_container(const char *systype)
 | 
				
			|||||||
			return RC_SYS_JAIL;
 | 
								return RC_SYS_JAIL;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __NetBSD__
 | 
				
			||||||
 | 
						if (systype) {
 | 
				
			||||||
 | 
							if(strcmp(systype, RC_SYS_XEN0) == 0)
 | 
				
			||||||
 | 
									return RC_SYS_XEN0;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_XENU) == 0)
 | 
				
			||||||
 | 
								return RC_SYS_XENU;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (exists("/kern/xen/privcmd"))
 | 
				
			||||||
 | 
							return RC_SYS_XEN0;
 | 
				
			||||||
 | 
						if (exists("/kern/xen"))
 | 
				
			||||||
 | 
							return RC_SYS_XENU;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __linux__
 | 
					#ifdef __linux__
 | 
				
			||||||
	if (systype) {
 | 
						if (systype) {
 | 
				
			||||||
		if (strcmp(systype, RC_SYS_NONE) == 0)
 | 
							if (strcmp(systype, RC_SYS_XEN0) == 0)
 | 
				
			||||||
			return NULL;
 | 
								return RC_SYS_XEN0;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_XENU) == 0)
 | 
				
			||||||
 | 
								return RC_SYS_XENU;
 | 
				
			||||||
		if (strcmp(systype, RC_SYS_UML) == 0)
 | 
							if (strcmp(systype, RC_SYS_UML) == 0)
 | 
				
			||||||
			return RC_SYS_UML;
 | 
								return RC_SYS_UML;
 | 
				
			||||||
		if (strcmp(systype, RC_SYS_VSERVER) == 0)
 | 
							if (strcmp(systype, RC_SYS_VSERVER) == 0)
 | 
				
			||||||
@@ -269,7 +261,11 @@ detect_container(const char *systype)
 | 
				
			|||||||
		if (strcmp(systype, RC_SYS_DOCKER) == 0)
 | 
							if (strcmp(systype, RC_SYS_DOCKER) == 0)
 | 
				
			||||||
				return RC_SYS_DOCKER;
 | 
									return RC_SYS_DOCKER;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (file_regex("/proc/cpuinfo", "UML"))
 | 
						if (exists("/proc/xen")) {
 | 
				
			||||||
 | 
							if (file_regex("/proc/xen/capabilities", "control_d"))
 | 
				
			||||||
 | 
								return RC_SYS_XEN0;
 | 
				
			||||||
 | 
							return RC_SYS_XENU;
 | 
				
			||||||
 | 
						} else if (file_regex("/proc/cpuinfo", "UML"))
 | 
				
			||||||
		return RC_SYS_UML;
 | 
							return RC_SYS_UML;
 | 
				
			||||||
	else if (file_regex("/proc/self/status",
 | 
						else if (file_regex("/proc/self/status",
 | 
				
			||||||
		"(s_context|VxID):[[:space:]]*[1-9]"))
 | 
							"(s_context|VxID):[[:space:]]*[1-9]"))
 | 
				
			||||||
@@ -285,70 +281,12 @@ detect_container(const char *systype)
 | 
				
			|||||||
		return RC_SYS_RKT;
 | 
							return RC_SYS_RKT;
 | 
				
			||||||
	else if (file_regex("/proc/1/environ", "container=systemd-nspawn"))
 | 
						else if (file_regex("/proc/1/environ", "container=systemd-nspawn"))
 | 
				
			||||||
		return RC_SYS_SYSTEMD_NSPAWN;
 | 
							return RC_SYS_SYSTEMD_NSPAWN;
 | 
				
			||||||
	else if (exists("/.dockerenv"))
 | 
					 | 
				
			||||||
		return RC_SYS_DOCKER;
 | 
					 | 
				
			||||||
	/* old test, I'm not sure when this was valid. */
 | 
					 | 
				
			||||||
	else if (file_regex("/proc/1/environ", "container=docker"))
 | 
						else if (file_regex("/proc/1/environ", "container=docker"))
 | 
				
			||||||
		return RC_SYS_DOCKER;
 | 
							return RC_SYS_DOCKER;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char *
 | 
					 | 
				
			||||||
detect_vm(const char *systype)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#ifdef __NetBSD__
 | 
					 | 
				
			||||||
	if (systype) {
 | 
					 | 
				
			||||||
		if (strcmp(systype, RC_SYS_NONE) == 0)
 | 
					 | 
				
			||||||
			return NULL;
 | 
					 | 
				
			||||||
		if (strcmp(systype, RC_SYS_XEN0) == 0)
 | 
					 | 
				
			||||||
			return RC_SYS_XEN0;
 | 
					 | 
				
			||||||
		if (strcmp(systype, RC_SYS_XENU) == 0)
 | 
					 | 
				
			||||||
			return RC_SYS_XENU;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (exists("/kern/xen/privcmd"))
 | 
					 | 
				
			||||||
		return RC_SYS_XEN0;
 | 
					 | 
				
			||||||
	if (exists("/kern/xen"))
 | 
					 | 
				
			||||||
		return RC_SYS_XENU;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __linux__
 | 
					 | 
				
			||||||
	if (systype) {
 | 
					 | 
				
			||||||
		if (strcmp(systype, RC_SYS_NONE) == 0)
 | 
					 | 
				
			||||||
			return NULL;
 | 
					 | 
				
			||||||
		if (strcmp(systype, RC_SYS_XEN0) == 0)
 | 
					 | 
				
			||||||
			return RC_SYS_XEN0;
 | 
					 | 
				
			||||||
		if (strcmp(systype, RC_SYS_XENU) == 0)
 | 
					 | 
				
			||||||
			return RC_SYS_XENU;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (exists("/proc/xen")) {
 | 
					 | 
				
			||||||
		if (file_regex("/proc/xen/capabilities", "control_d"))
 | 
					 | 
				
			||||||
			return RC_SYS_XEN0;
 | 
					 | 
				
			||||||
		return RC_SYS_XENU;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const char *
 | 
					 | 
				
			||||||
rc_sys(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	const char *systype;
 | 
					 | 
				
			||||||
	const char *sys;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	systype = get_systype();
 | 
					 | 
				
			||||||
	sys = detect_prefix(systype);
 | 
					 | 
				
			||||||
	if (!sys) {
 | 
					 | 
				
			||||||
		sys = detect_container(systype);
 | 
					 | 
				
			||||||
		if (!sys) {
 | 
					 | 
				
			||||||
			sys = detect_vm(systype);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return sys;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
librc_hidden_def(rc_sys)
 | 
					librc_hidden_def(rc_sys)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *
 | 
					static const char *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -318,7 +318,6 @@ bool rc_service_daemons_crashed(const char *);
 | 
				
			|||||||
 * Some services cannot work in these systems, or we do something else. */
 | 
					 * Some services cannot work in these systems, or we do something else. */
 | 
				
			||||||
#define RC_SYS_DOCKER  "DOCKER"
 | 
					#define RC_SYS_DOCKER  "DOCKER"
 | 
				
			||||||
#define RC_SYS_JAIL    "JAIL"
 | 
					#define RC_SYS_JAIL    "JAIL"
 | 
				
			||||||
#define RC_SYS_NONE    ""
 | 
					 | 
				
			||||||
#define RC_SYS_OPENVZ  "OPENVZ"
 | 
					#define RC_SYS_OPENVZ  "OPENVZ"
 | 
				
			||||||
#define RC_SYS_LXC     "LXC"
 | 
					#define RC_SYS_LXC     "LXC"
 | 
				
			||||||
#define RC_SYS_PREFIX  "PREFIX"
 | 
					#define RC_SYS_PREFIX  "PREFIX"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								src/rc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/rc/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -5,7 +5,6 @@ rc-update
 | 
				
			|||||||
runscript
 | 
					runscript
 | 
				
			||||||
service
 | 
					service
 | 
				
			||||||
start-stop-daemon
 | 
					start-stop-daemon
 | 
				
			||||||
supervise-daemon
 | 
					 | 
				
			||||||
einfon
 | 
					einfon
 | 
				
			||||||
einfo
 | 
					einfo
 | 
				
			||||||
ewarnn
 | 
					ewarnn
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,4 @@
 | 
				
			|||||||
SRCS=	checkpath.c do_e.c do_mark_service.c do_service.c \
 | 
					SRCS=	rc.c 	rc-logger.c rc-misc.c rc-plugin.c
 | 
				
			||||||
		do_value.c fstabinfo.c is_newer_than.c is_older_than.c \
 | 
					 | 
				
			||||||
		mountinfo.c openrc-run.c rc-abort.c rc.c \
 | 
					 | 
				
			||||||
		rc-depend.c rc-logger.c rc-misc.c rc-plugin.c \
 | 
					 | 
				
			||||||
		rc-service.c rc-status.c rc-update.c \
 | 
					 | 
				
			||||||
		shell_var.c start-stop-daemon.c supervise-daemon.c swclock.c _usage.c
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq (${MKSELINUX},yes)
 | 
					ifeq (${MKSELINUX},yes)
 | 
				
			||||||
SRCS+=		rc-selinux.c
 | 
					SRCS+=		rc-selinux.c
 | 
				
			||||||
@@ -16,8 +11,7 @@ SBINDIR=	${PREFIX}/sbin
 | 
				
			|||||||
LINKDIR=	${LIBEXECDIR}
 | 
					LINKDIR=	${LIBEXECDIR}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BINPROGS=	rc-status
 | 
					BINPROGS=	rc-status
 | 
				
			||||||
SBINPROGS = openrc openrc-run rc rc-service rc-update runscript service \
 | 
					SBINPROGS = openrc openrc-run rc rc-service rc-update runscript service start-stop-daemon
 | 
				
			||||||
			start-stop-daemon supervise-daemon
 | 
					 | 
				
			||||||
RC_BINPROGS=	einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
 | 
					RC_BINPROGS=	einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
 | 
				
			||||||
				eindent eoutdent esyslog eval_ecolors ewaitfile \
 | 
									eindent eoutdent esyslog eval_ecolors ewaitfile \
 | 
				
			||||||
				veinfo vewarn vebegin veend vewend veindent veoutdent \
 | 
									veinfo vewarn vebegin veend vewend veindent veoutdent \
 | 
				
			||||||
@@ -75,7 +69,6 @@ install: all
 | 
				
			|||||||
	if test "${MKPAM}" = pam; then \
 | 
						if test "${MKPAM}" = pam; then \
 | 
				
			||||||
		${INSTALL} -d ${DESTDIR}${PAMDIR}; \
 | 
							${INSTALL} -d ${DESTDIR}${PAMDIR}; \
 | 
				
			||||||
		${INSTALL} -m ${PAMMODE} start-stop-daemon.pam ${DESTDIR}${PAMDIR}/start-stop-daemon; \
 | 
							${INSTALL} -m ${PAMMODE} start-stop-daemon.pam ${DESTDIR}${PAMDIR}/start-stop-daemon; \
 | 
				
			||||||
		${INSTALL} -m ${PAMMODE} supervise-daemon.pam ${DESTDIR}${PAMDIR}/supervise-daemon; \
 | 
					 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
check test::
 | 
					check test::
 | 
				
			||||||
@@ -112,12 +105,12 @@ mountinfo: mountinfo.o _usage.o rc-misc.o
 | 
				
			|||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o _usage.o
 | 
					openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o _usage.o
 | 
				
			||||||
 | 
					ifeq (${MKSELINUX},yes)
 | 
				
			||||||
 | 
					openrc rc: rc-selinux.o
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o
 | 
					openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o
 | 
				
			||||||
ifeq (${MKSELINUX},yes)
 | 
					 | 
				
			||||||
openrc-run runscript: rc-selinux.o
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rc-abort: rc-abort.o
 | 
					rc-abort: rc-abort.o
 | 
				
			||||||
@@ -138,9 +131,6 @@ rc-update: rc-update.o _usage.o rc-misc.o
 | 
				
			|||||||
start-stop-daemon: start-stop-daemon.o _usage.o rc-misc.o
 | 
					start-stop-daemon: start-stop-daemon.o _usage.o rc-misc.o
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
supervise-daemon: supervise-daemon.o _usage.o rc-misc.o
 | 
					 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
service_get_value service_set_value get_options save_options: do_value.o rc-misc.o
 | 
					service_get_value service_set_value get_options save_options: do_value.o rc-misc.o
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,6 @@
 | 
				
			|||||||
#include <ctype.h>
 | 
					#include <ctype.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include "rc.h"
 | 
					 | 
				
			||||||
#include "rc-misc.h"
 | 
					#include "rc-misc.h"
 | 
				
			||||||
#include "_usage.h"
 | 
					#include "_usage.h"
 | 
				
			||||||
#include "version.h"
 | 
					#include "version.h"
 | 
				
			||||||
@@ -47,7 +46,10 @@ _noreturn void show_version(void)
 | 
				
			|||||||
	const char *systype = NULL;
 | 
						const char *systype = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printf("%s (OpenRC", applet);
 | 
						printf("%s (OpenRC", applet);
 | 
				
			||||||
	if ((systype = rc_sys()))
 | 
						systype = detect_container();
 | 
				
			||||||
 | 
						if (!systype)
 | 
				
			||||||
 | 
							systype = detect_vm();
 | 
				
			||||||
 | 
						if (systype)
 | 
				
			||||||
		printf(" [%s]", systype);
 | 
							printf(" [%s]", systype);
 | 
				
			||||||
	printf(") %s", VERSION);
 | 
						printf(") %s", VERSION);
 | 
				
			||||||
#ifdef BRANDING
 | 
					#ifdef BRANDING
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,6 @@
 | 
				
			|||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "einfo.h"
 | 
					#include "einfo.h"
 | 
				
			||||||
#include "rc.h"
 | 
					 | 
				
			||||||
#include "rc-misc.h"
 | 
					#include "rc-misc.h"
 | 
				
			||||||
#include "rc-selinux.h"
 | 
					#include "rc-selinux.h"
 | 
				
			||||||
#include "_usage.h"
 | 
					#include "_usage.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,6 @@
 | 
				
			|||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "einfo.h"
 | 
					#include "einfo.h"
 | 
				
			||||||
#include "rc.h"
 | 
					 | 
				
			||||||
#include "rc-misc.h"
 | 
					#include "rc-misc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *applet = NULL;
 | 
					const char *applet = NULL;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -178,9 +178,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* fail if there is no /etc/fstab */
 | 
					 | 
				
			||||||
	if (!exists("/etc/fstab"))
 | 
					 | 
				
			||||||
		eerrorx("/etc/fstab does not exist");
 | 
					 | 
				
			||||||
	/* Ensure that we are only quiet when explicitly told to be */
 | 
						/* Ensure that we are only quiet when explicitly told to be */
 | 
				
			||||||
	unsetenv("EINFO_QUIET");
 | 
						unsetenv("EINFO_QUIET");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "rc.h"
 | 
					 | 
				
			||||||
#include "rc-misc.h"
 | 
					#include "rc-misc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "rc.h"
 | 
					 | 
				
			||||||
#include "rc-misc.h"
 | 
					#include "rc-misc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -297,9 +297,6 @@ getmntfile(const char *file)
 | 
				
			|||||||
	struct mntent *ent = NULL;
 | 
						struct mntent *ent = NULL;
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!exists("/etc/fstab"))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fp = setmntent("/etc/fstab", "r");
 | 
						fp = setmntent("/etc/fstab", "r");
 | 
				
			||||||
	while ((ent = getmntent(fp)))
 | 
						while ((ent = getmntent(fp)))
 | 
				
			||||||
		if (strcmp(file, ent->mnt_dir) == 0)
 | 
							if (strcmp(file, ent->mnt_dir) == 0)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -390,14 +390,6 @@ svc_exec(const char *arg1, const char *arg2)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (exists(RC_SVCDIR "/openrc-run.sh")) {
 | 
							if (exists(RC_SVCDIR "/openrc-run.sh")) {
 | 
				
			||||||
			if (arg2)
 | 
					 | 
				
			||||||
				einfov("Executing: %s %s %s %s %s",
 | 
					 | 
				
			||||||
					RC_SVCDIR "/openrc-run.sh", RC_SVCDIR "/openrc-run.sh",
 | 
					 | 
				
			||||||
					service, arg1, arg2);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				einfov("Executing: %s %s %s %s",
 | 
					 | 
				
			||||||
					RC_SVCDIR "/openrc-run.sh", RC_SVCDIR "/openrc-run.sh",
 | 
					 | 
				
			||||||
					service, arg1);
 | 
					 | 
				
			||||||
			execl(RC_SVCDIR "/openrc-run.sh",
 | 
								execl(RC_SVCDIR "/openrc-run.sh",
 | 
				
			||||||
			    RC_SVCDIR "/openrc-run.sh",
 | 
								    RC_SVCDIR "/openrc-run.sh",
 | 
				
			||||||
			    service, arg1, arg2, (char *) NULL);
 | 
								    service, arg1, arg2, (char *) NULL);
 | 
				
			||||||
@@ -405,16 +397,6 @@ svc_exec(const char *arg1, const char *arg2)
 | 
				
			|||||||
			    service, strerror(errno));
 | 
								    service, strerror(errno));
 | 
				
			||||||
			_exit(EXIT_FAILURE);
 | 
								_exit(EXIT_FAILURE);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if (arg2)
 | 
					 | 
				
			||||||
				einfov("Executing: %s %s %s %s %s",
 | 
					 | 
				
			||||||
					RC_LIBEXECDIR "/sh/openrc-run.sh",
 | 
					 | 
				
			||||||
					RC_LIBEXECDIR "/sh/openrc-run.sh",
 | 
					 | 
				
			||||||
			    	service, arg1, arg2);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				einfov("Executing: %s %s %s %s",
 | 
					 | 
				
			||||||
					RC_LIBEXECDIR "/sh/openrc-run.sh",
 | 
					 | 
				
			||||||
					RC_LIBEXECDIR "/sh/openrc-run.sh",
 | 
					 | 
				
			||||||
			    	service, arg1);
 | 
					 | 
				
			||||||
			execl(RC_LIBEXECDIR "/sh/openrc-run.sh",
 | 
								execl(RC_LIBEXECDIR "/sh/openrc-run.sh",
 | 
				
			||||||
			    RC_LIBEXECDIR "/sh/openrc-run.sh",
 | 
								    RC_LIBEXECDIR "/sh/openrc-run.sh",
 | 
				
			||||||
			    service, arg1, arg2, (char *) NULL);
 | 
								    service, arg1, arg2, (char *) NULL);
 | 
				
			||||||
@@ -1106,7 +1088,6 @@ service_plugable(void)
 | 
				
			|||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bool doneone = false;
 | 
						bool doneone = false;
 | 
				
			||||||
	bool runscript = false;
 | 
					 | 
				
			||||||
	int retval, opt, depoptions = RC_DEP_TRACE;
 | 
						int retval, opt, depoptions = RC_DEP_TRACE;
 | 
				
			||||||
	RC_STRING *svc;
 | 
						RC_STRING *svc;
 | 
				
			||||||
	char path[PATH_MAX], lnk[PATH_MAX];
 | 
						char path[PATH_MAX], lnk[PATH_MAX];
 | 
				
			||||||
@@ -1122,10 +1103,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		exit(EXIT_FAILURE);
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	applet = basename_c(argv[0]);
 | 
					 | 
				
			||||||
	if (strcmp(applet, "runscript") == 0)
 | 
					 | 
				
			||||||
		runscript = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (stat(argv[1], &stbuf) != 0) {
 | 
						if (stat(argv[1], &stbuf) != 0) {
 | 
				
			||||||
		fprintf(stderr, "openrc-run `%s': %s\n",
 | 
							fprintf(stderr, "openrc-run `%s': %s\n",
 | 
				
			||||||
		    argv[1], strerror(errno));
 | 
							    argv[1], strerror(errno));
 | 
				
			||||||
@@ -1292,9 +1269,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	applet_list = rc_stringlist_new();
 | 
						applet_list = rc_stringlist_new();
 | 
				
			||||||
	rc_stringlist_add(applet_list, applet);
 | 
						rc_stringlist_add(applet_list, applet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (runscript)
 | 
					 | 
				
			||||||
		ewarn("%s uses runscript, please convert to openrc-run.", service);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Now run each option */
 | 
						/* Now run each option */
 | 
				
			||||||
	retval = EXIT_SUCCESS;
 | 
						retval = EXIT_SUCCESS;
 | 
				
			||||||
	while (optind < argc) {
 | 
						while (optind < argc) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -247,10 +247,6 @@ rc_logger_open(const char *level)
 | 
				
			|||||||
		logfile = rc_conf_value("rc_log_path");
 | 
							logfile = rc_conf_value("rc_log_path");
 | 
				
			||||||
		if (logfile == NULL)
 | 
							if (logfile == NULL)
 | 
				
			||||||
			logfile = DEFAULTLOG;
 | 
								logfile = DEFAULTLOG;
 | 
				
			||||||
		if (!strcmp(logfile, TMPLOG)) {
 | 
					 | 
				
			||||||
			eerror("Cowardly refusing to concatenate a logfile into itself.");
 | 
					 | 
				
			||||||
			eerrorx("Please change rc_log_path to something other than %s to get rid of this message", TMPLOG);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((plog = fopen(logfile, "ae"))) {
 | 
							if ((plog = fopen(logfile, "ae"))) {
 | 
				
			||||||
			if ((log = fopen(TMPLOG, "re"))) {
 | 
								if ((log = fopen(TMPLOG, "re"))) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										170
									
								
								src/rc/rc-misc.c
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								src/rc/rc-misc.c
									
									
									
									
									
								
							@@ -27,6 +27,7 @@
 | 
				
			|||||||
#include <ctype.h>
 | 
					#include <ctype.h>
 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
#include <limits.h>
 | 
					#include <limits.h>
 | 
				
			||||||
 | 
					#  include <regex.h>
 | 
				
			||||||
#include <signal.h>
 | 
					#include <signal.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
@@ -68,12 +69,6 @@ env_filter(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Add the user defined list of vars */
 | 
						/* Add the user defined list of vars */
 | 
				
			||||||
	env_allow = rc_stringlist_split(rc_conf_value("rc_env_allow"), " ");
 | 
						env_allow = rc_stringlist_split(rc_conf_value("rc_env_allow"), " ");
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * If '*' is an entry in rc_env_allow, do nothing as we are to pass
 | 
					 | 
				
			||||||
	 * through all environment variables.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (rc_stringlist_find(env_allow, "*"))
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	profile = rc_config_load(RC_PROFILE_ENV);
 | 
						profile = rc_config_load(RC_PROFILE_ENV);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Copy the env and work from this so we can manipulate it safely */
 | 
						/* Copy the env and work from this so we can manipulate it safely */
 | 
				
			||||||
@@ -131,7 +126,7 @@ env_config(void)
 | 
				
			|||||||
	char *np;
 | 
						char *np;
 | 
				
			||||||
	char *npp;
 | 
						char *npp;
 | 
				
			||||||
	char *tok;
 | 
						char *tok;
 | 
				
			||||||
	const char *sys = rc_sys();
 | 
						const char *sys = NULL;
 | 
				
			||||||
	char buffer[PATH_MAX];
 | 
						char buffer[PATH_MAX];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Ensure our PATH is prefixed with the system locations first
 | 
						/* Ensure our PATH is prefixed with the system locations first
 | 
				
			||||||
@@ -182,6 +177,10 @@ env_config(void)
 | 
				
			|||||||
	} else
 | 
						} else
 | 
				
			||||||
		setenv("RC_DEFAULTLEVEL", RC_LEVEL_DEFAULT, 1);
 | 
							setenv("RC_DEFAULTLEVEL", RC_LEVEL_DEFAULT, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sys = detect_container();
 | 
				
			||||||
 | 
						if (!sys)
 | 
				
			||||||
 | 
							sys = detect_vm();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sys)
 | 
						if (sys)
 | 
				
			||||||
		setenv("RC_SYS", sys, 1);
 | 
							setenv("RC_SYS", sys, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -339,6 +338,163 @@ is_writable(const char *path)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool file_regex(const char *file, const char *regex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE *fp;
 | 
				
			||||||
 | 
						char *line = NULL;
 | 
				
			||||||
 | 
						size_t len = 0;
 | 
				
			||||||
 | 
						regex_t re;
 | 
				
			||||||
 | 
						bool retval = true;
 | 
				
			||||||
 | 
						int result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(fp = fopen(file, "r")))
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
 | 
				
			||||||
 | 
							fclose(fp);
 | 
				
			||||||
 | 
							line = xmalloc(sizeof(char) * BUFSIZ);
 | 
				
			||||||
 | 
							regerror(result, &re, line, BUFSIZ);
 | 
				
			||||||
 | 
							fprintf(stderr, "file_regex: %s", line);
 | 
				
			||||||
 | 
							free(line);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((rc_getline(&line, &len, fp))) {
 | 
				
			||||||
 | 
							char *str = line;
 | 
				
			||||||
 | 
							/* some /proc files have \0 separated content so we have to
 | 
				
			||||||
 | 
							   loop through the 'line' */
 | 
				
			||||||
 | 
							do {
 | 
				
			||||||
 | 
								if (regexec(&re, str, 0, NULL, 0) == 0)
 | 
				
			||||||
 | 
									goto found;
 | 
				
			||||||
 | 
								str += strlen(str) + 1;
 | 
				
			||||||
 | 
								/* len is the size of allocated buffer and we don't
 | 
				
			||||||
 | 
								   want call regexec BUFSIZE times. find next str */
 | 
				
			||||||
 | 
								while (str < line + len && *str == '\0')
 | 
				
			||||||
 | 
									str++;
 | 
				
			||||||
 | 
							} while (str < line + len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						retval = false;
 | 
				
			||||||
 | 
					found:
 | 
				
			||||||
 | 
						fclose(fp);
 | 
				
			||||||
 | 
						free(line);
 | 
				
			||||||
 | 
						regfree(&re);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *detect_prefix(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef PREFIX
 | 
				
			||||||
 | 
						return RC_SYS_PREFIX;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *get_systype(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *systype = rc_conf_value("rc_sys");
 | 
				
			||||||
 | 
						if (systype) {
 | 
				
			||||||
 | 
							char *s = systype;
 | 
				
			||||||
 | 
							/* Convert to uppercase */
 | 
				
			||||||
 | 
							while (s && *s) {
 | 
				
			||||||
 | 
								if (islower((unsigned char) *s))
 | 
				
			||||||
 | 
									*s = toupper((unsigned char) *s);
 | 
				
			||||||
 | 
								s++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return systype;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *detect_container(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *systype = get_systype();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __FreeBSD__
 | 
				
			||||||
 | 
						if (systype && strcmp(systype, RC_SYS_JAIL) == 0)
 | 
				
			||||||
 | 
							return RC_SYS_JAIL;
 | 
				
			||||||
 | 
						int jailed = 0;
 | 
				
			||||||
 | 
						size_t len = sizeof(jailed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sysctlbyname("security.jail.jailed", &jailed, &len, NULL, 0) == 0)
 | 
				
			||||||
 | 
							if (jailed == 1)
 | 
				
			||||||
 | 
								return RC_SYS_JAIL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __linux__
 | 
				
			||||||
 | 
						if (systype) {
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_UML) == 0)
 | 
				
			||||||
 | 
								return RC_SYS_UML;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_VSERVER) == 0)
 | 
				
			||||||
 | 
								return RC_SYS_VSERVER;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_OPENVZ) == 0)
 | 
				
			||||||
 | 
								return RC_SYS_OPENVZ;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_LXC) == 0)
 | 
				
			||||||
 | 
								return RC_SYS_LXC;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_RKT) == 0)
 | 
				
			||||||
 | 
									return RC_SYS_RKT;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_SYSTEMD_NSPAWN) == 0)
 | 
				
			||||||
 | 
									return RC_SYS_SYSTEMD_NSPAWN;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_DOCKER) == 0)
 | 
				
			||||||
 | 
									return RC_SYS_DOCKER;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (file_regex("/proc/cpuinfo", "UML"))
 | 
				
			||||||
 | 
							return RC_SYS_UML;
 | 
				
			||||||
 | 
						else if (file_regex("/proc/self/status",
 | 
				
			||||||
 | 
							"(s_context|VxID):[[:space:]]*[1-9]"))
 | 
				
			||||||
 | 
							return RC_SYS_VSERVER;
 | 
				
			||||||
 | 
						else if (exists("/proc/vz/veinfo") && !exists("/proc/vz/version"))
 | 
				
			||||||
 | 
							return RC_SYS_OPENVZ;
 | 
				
			||||||
 | 
						else if (file_regex("/proc/self/status",
 | 
				
			||||||
 | 
							"envID:[[:space:]]*[1-9]"))
 | 
				
			||||||
 | 
							return RC_SYS_OPENVZ; /* old test */
 | 
				
			||||||
 | 
						else if (file_regex("/proc/1/environ", "container=lxc"))
 | 
				
			||||||
 | 
							return RC_SYS_LXC;
 | 
				
			||||||
 | 
						else if (file_regex("/proc/1/environ", "container=rkt"))
 | 
				
			||||||
 | 
							return RC_SYS_RKT;
 | 
				
			||||||
 | 
						else if (file_regex("/proc/1/environ", "container=systemd-nspawn"))
 | 
				
			||||||
 | 
							return RC_SYS_SYSTEMD_NSPAWN;
 | 
				
			||||||
 | 
						else if (file_regex("/proc/1/environ", "container=docker"))
 | 
				
			||||||
 | 
							return RC_SYS_DOCKER;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *detect_vm(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *systype = get_systype();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __NetBSD__
 | 
				
			||||||
 | 
						if (systype) {
 | 
				
			||||||
 | 
							if(strcmp(systype, RC_SYS_XEN0) == 0)
 | 
				
			||||||
 | 
									return RC_SYS_XEN0;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_XENU) == 0)
 | 
				
			||||||
 | 
								return RC_SYS_XENU;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (exists("/kern/xen/privcmd"))
 | 
				
			||||||
 | 
							return RC_SYS_XEN0;
 | 
				
			||||||
 | 
						if (exists("/kern/xen"))
 | 
				
			||||||
 | 
							return RC_SYS_XENU;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __linux__
 | 
				
			||||||
 | 
						if (systype) {
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_XEN0) == 0)
 | 
				
			||||||
 | 
								return RC_SYS_XEN0;
 | 
				
			||||||
 | 
							if (strcmp(systype, RC_SYS_XENU) == 0)
 | 
				
			||||||
 | 
								return RC_SYS_XENU;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (exists("/proc/xen")) {
 | 
				
			||||||
 | 
							if (file_regex("/proc/xen/capabilities", "control_d"))
 | 
				
			||||||
 | 
								return RC_SYS_XEN0;
 | 
				
			||||||
 | 
							return RC_SYS_XENU;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RC_DEPTREE * _rc_deptree_load(int force, int *regen)
 | 
					RC_DEPTREE * _rc_deptree_load(int force, int *regen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -370,7 +370,7 @@ void selinux_setup(char **argv)
 | 
				
			|||||||
	 * which will open the pty with initrc_devpts_t, if it doesnt exist,
 | 
						 * which will open the pty with initrc_devpts_t, if it doesnt exist,
 | 
				
			||||||
	 * fall back to plain exec
 | 
						 * fall back to plain exec
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!access("/usr/sbin/open_init_pty", X_OK)) {
 | 
						if (access("/usr/sbin/open_init_pty", X_OK)) {
 | 
				
			||||||
		if (execvp("/usr/sbin/open_init_pty", argv)) {
 | 
							if (execvp("/usr/sbin/open_init_pty", argv)) {
 | 
				
			||||||
			perror("execvp");
 | 
								perror("execvp");
 | 
				
			||||||
			exit(-1);
 | 
								exit(-1);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,12 +29,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const char *applet = NULL;
 | 
					const char *applet = NULL;
 | 
				
			||||||
const char *extraopts = NULL;
 | 
					const char *extraopts = NULL;
 | 
				
			||||||
const char *getoptstring = "e:ilr:IN" getoptstring_COMMON;
 | 
					const char *getoptstring = "e:ilr:" getoptstring_COMMON;
 | 
				
			||||||
const struct option longopts[] = {
 | 
					const struct option longopts[] = {
 | 
				
			||||||
	{ "exists",   1, NULL, 'e' },
 | 
						{ "exists",   1, NULL, 'e' },
 | 
				
			||||||
	{ "ifexists", 0, NULL, 'i' },
 | 
						{ "ifexists", 0, NULL, 'i' },
 | 
				
			||||||
	{ "ifinactive", 0, NULL, 'I' },
 | 
					 | 
				
			||||||
	{ "ifnotstarted", 0, NULL, 'N' },
 | 
					 | 
				
			||||||
	{ "list",     0, NULL, 'l' },
 | 
						{ "list",     0, NULL, 'l' },
 | 
				
			||||||
	{ "resolve",  1, NULL, 'r' },
 | 
						{ "resolve",  1, NULL, 'r' },
 | 
				
			||||||
	longopts_COMMON
 | 
						longopts_COMMON
 | 
				
			||||||
@@ -42,8 +40,6 @@ const struct option longopts[] = {
 | 
				
			|||||||
const char * const longopts_help[] = {
 | 
					const char * const longopts_help[] = {
 | 
				
			||||||
	"tests if the service exists or not",
 | 
						"tests if the service exists or not",
 | 
				
			||||||
	"if the service exists then run the command",
 | 
						"if the service exists then run the command",
 | 
				
			||||||
	"if the service is inactive then run the command",
 | 
					 | 
				
			||||||
	"if the service is not started then run the command",
 | 
					 | 
				
			||||||
	"list all available services",
 | 
						"list all available services",
 | 
				
			||||||
	"resolve the service name to an init script",
 | 
						"resolve the service name to an init script",
 | 
				
			||||||
	longopts_help_COMMON
 | 
						longopts_help_COMMON
 | 
				
			||||||
@@ -60,10 +56,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	char *service;
 | 
						char *service;
 | 
				
			||||||
	RC_STRINGLIST *list;
 | 
						RC_STRINGLIST *list;
 | 
				
			||||||
	RC_STRING *s;
 | 
						RC_STRING *s;
 | 
				
			||||||
	RC_SERVICE state;
 | 
					 | 
				
			||||||
	bool if_exists = false;
 | 
						bool if_exists = false;
 | 
				
			||||||
	bool if_inactive = false;
 | 
					 | 
				
			||||||
	bool if_notstarted = false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	applet = basename_c(argv[0]);
 | 
						applet = basename_c(argv[0]);
 | 
				
			||||||
	/* Ensure that we are only quiet when explicitly told to be */
 | 
						/* Ensure that we are only quiet when explicitly told to be */
 | 
				
			||||||
@@ -84,12 +77,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		case 'i':
 | 
							case 'i':
 | 
				
			||||||
			if_exists = true;
 | 
								if_exists = true;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'I':
 | 
					 | 
				
			||||||
			if_inactive = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'N':
 | 
					 | 
				
			||||||
			if_notstarted = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'l':
 | 
							case 'l':
 | 
				
			||||||
			list = rc_services_in_runlevel(NULL);
 | 
								list = rc_services_in_runlevel(NULL);
 | 
				
			||||||
			if (TAILQ_FIRST(list) == NULL)
 | 
								if (TAILQ_FIRST(list) == NULL)
 | 
				
			||||||
@@ -126,11 +113,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		eerrorx("%s: service `%s' does not exist", applet, *argv);
 | 
							eerrorx("%s: service `%s' does not exist", applet, *argv);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	state = rc_service_state(*argv);
 | 
					 | 
				
			||||||
	if (if_inactive && ! (state & RC_SERVICE_INACTIVE))
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	if (if_notstarted && (state & RC_SERVICE_STARTED))
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	*argv = service;
 | 
						*argv = service;
 | 
				
			||||||
	execv(*argv, argv);
 | 
						execv(*argv, argv);
 | 
				
			||||||
	eerrorx("%s: %s", applet, strerror(errno));
 | 
						eerrorx("%s: %s", applet, strerror(errno));
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								src/rc/rc.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/rc/rc.c
									
									
									
									
									
								
							@@ -281,10 +281,15 @@ open_shell(void)
 | 
				
			|||||||
	struct passwd *pw;
 | 
						struct passwd *pw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __linux__
 | 
					#ifdef __linux__
 | 
				
			||||||
	const char *sys = rc_sys();
 | 
						const char *sys = NULL;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* VSERVER systems cannot really drop to shells */
 | 
						sys = detect_container();
 | 
				
			||||||
	if (sys && strcmp(sys, RC_SYS_VSERVER) == 0)
 | 
						if (!sys)
 | 
				
			||||||
 | 
							sys = detect_vm();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* VSERVER and OPENVZ systems cannot really drop to shells */
 | 
				
			||||||
 | 
						if (sys &&
 | 
				
			||||||
 | 
						    (strcmp(sys, "VSERVER") == 0 || strcmp(sys, "OPENVZ") == 0))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		execl("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
 | 
							execl("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
 | 
				
			||||||
		eerrorx("%s: unable to exec `/sbin/halt': %s",
 | 
							eerrorx("%s: unable to exec `/sbin/halt': %s",
 | 
				
			||||||
@@ -486,7 +491,10 @@ do_sysinit()
 | 
				
			|||||||
	    uts.machine);
 | 
						    uts.machine);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((sys = rc_sys()))
 | 
						sys = detect_container();
 | 
				
			||||||
 | 
						if (!sys)
 | 
				
			||||||
 | 
							sys = detect_vm();
 | 
				
			||||||
 | 
						if (sys)
 | 
				
			||||||
		printf(" [%s]", sys);
 | 
							printf(" [%s]", sys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printf("%s\n\n", ecolor(ECOLOR_NORMAL));
 | 
						printf("%s\n\n", ecolor(ECOLOR_NORMAL));
 | 
				
			||||||
@@ -501,7 +509,10 @@ do_sysinit()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* init may have mounted /proc so we can now detect or real
 | 
						/* init may have mounted /proc so we can now detect or real
 | 
				
			||||||
	 * sys */
 | 
						 * sys */
 | 
				
			||||||
	if ((sys = rc_sys()))
 | 
						sys = detect_container();
 | 
				
			||||||
 | 
						if (!sys)
 | 
				
			||||||
 | 
							sys = detect_vm();
 | 
				
			||||||
 | 
						if (sys)
 | 
				
			||||||
		setenv("RC_SYS", sys, 1);
 | 
							setenv("RC_SYS", sys, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -821,7 +832,9 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			eerrorx("%s: %s", applet, strerror(errno));
 | 
								eerrorx("%s: %s", applet, strerror(errno));
 | 
				
			||||||
			/* NOTREACHED */
 | 
								/* NOTREACHED */
 | 
				
			||||||
		case 'S':
 | 
							case 'S':
 | 
				
			||||||
			systype = rc_sys();
 | 
								systype = detect_container();
 | 
				
			||||||
 | 
								if (!systype)
 | 
				
			||||||
 | 
									systype = detect_vm();
 | 
				
			||||||
			if (systype)
 | 
								if (systype)
 | 
				
			||||||
				printf("%s\n", systype);
 | 
									printf("%s\n", systype);
 | 
				
			||||||
			exit(EXIT_SUCCESS);
 | 
								exit(EXIT_SUCCESS);
 | 
				
			||||||
@@ -830,8 +843,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (strcmp(applet, "rc") == 0)
 | 
					 | 
				
			||||||
		ewarn("rc is deprecated, please use openrc instead.");
 | 
					 | 
				
			||||||
	newlevel = argv[optind++];
 | 
						newlevel = argv[optind++];
 | 
				
			||||||
	/* To make life easier, we only have the shutdown runlevel as
 | 
						/* To make life easier, we only have the shutdown runlevel as
 | 
				
			||||||
	 * nothing really needs to know that we're rebooting.
 | 
						 * nothing really needs to know that we're rebooting.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1242,7 +1242,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		if (redirect_stdout) {
 | 
							if (redirect_stdout) {
 | 
				
			||||||
			if ((stdout_fd = open(redirect_stdout,
 | 
								if ((stdout_fd = open(redirect_stdout,
 | 
				
			||||||
				    O_WRONLY | O_CREAT | O_APPEND,
 | 
									    O_WRONLY | O_CREAT | O_APPEND,
 | 
				
			||||||
				    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1)
 | 
									    S_IRUSR | S_IWUSR)) == -1)
 | 
				
			||||||
				eerrorx("%s: unable to open the logfile"
 | 
									eerrorx("%s: unable to open the logfile"
 | 
				
			||||||
				    " for stdout `%s': %s",
 | 
									    " for stdout `%s': %s",
 | 
				
			||||||
				    applet, redirect_stdout, strerror(errno));
 | 
									    applet, redirect_stdout, strerror(errno));
 | 
				
			||||||
@@ -1250,7 +1250,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		if (redirect_stderr) {
 | 
							if (redirect_stderr) {
 | 
				
			||||||
			if ((stderr_fd = open(redirect_stderr,
 | 
								if ((stderr_fd = open(redirect_stderr,
 | 
				
			||||||
				    O_WRONLY | O_CREAT | O_APPEND,
 | 
									    O_WRONLY | O_CREAT | O_APPEND,
 | 
				
			||||||
				    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1)
 | 
									    S_IRUSR | S_IWUSR)) == -1)
 | 
				
			||||||
				eerrorx("%s: unable to open the logfile"
 | 
									eerrorx("%s: unable to open the logfile"
 | 
				
			||||||
				    " for stderr `%s': %s",
 | 
									    " for stderr `%s': %s",
 | 
				
			||||||
				    applet, redirect_stderr, strerror(errno));
 | 
									    applet, redirect_stderr, strerror(errno));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,726 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * supervise-daemon
 | 
					 | 
				
			||||||
 * This is an experimental supervisor for daemons.
 | 
					 | 
				
			||||||
 * It will start a deamon and make sure it restarts if it crashes.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2016 The OpenRC Authors.
 | 
					 | 
				
			||||||
 * See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
 * https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
 * the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
 * distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
 * This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
 *    except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* nano seconds */
 | 
					 | 
				
			||||||
#define POLL_INTERVAL   20000000
 | 
					 | 
				
			||||||
#define WAIT_PIDFILE   500000000
 | 
					 | 
				
			||||||
#define ONE_SECOND    1000000000
 | 
					 | 
				
			||||||
#define ONE_MS           1000000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
#include <sys/ioctl.h>
 | 
					 | 
				
			||||||
#include <sys/resource.h>
 | 
					 | 
				
			||||||
#include <sys/stat.h>
 | 
					 | 
				
			||||||
#include <termios.h>
 | 
					 | 
				
			||||||
#include <sys/time.h>
 | 
					 | 
				
			||||||
#include <sys/wait.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __linux__
 | 
					 | 
				
			||||||
#include <sys/syscall.h> /* For io priority */
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <ctype.h>
 | 
					 | 
				
			||||||
#include <errno.h>
 | 
					 | 
				
			||||||
#include <fcntl.h>
 | 
					 | 
				
			||||||
#include <getopt.h>
 | 
					 | 
				
			||||||
#include <limits.h>
 | 
					 | 
				
			||||||
#include <grp.h>
 | 
					 | 
				
			||||||
#include <pwd.h>
 | 
					 | 
				
			||||||
#include <signal.h>
 | 
					 | 
				
			||||||
#include <stddef.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <syslog.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef HAVE_PAM
 | 
					 | 
				
			||||||
#include <security/pam_appl.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* We are not supporting authentication conversations */
 | 
					 | 
				
			||||||
static struct pam_conv conv = { NULL, NULL};
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "einfo.h"
 | 
					 | 
				
			||||||
#include "queue.h"
 | 
					 | 
				
			||||||
#include "rc.h"
 | 
					 | 
				
			||||||
#include "rc-misc.h"
 | 
					 | 
				
			||||||
#include "_usage.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const char *applet = NULL;
 | 
					 | 
				
			||||||
const char *extraopts = NULL;
 | 
					 | 
				
			||||||
const char *getoptstring = "d:e:g:I:Kk:N:p:r:Su:1:2:" \
 | 
					 | 
				
			||||||
	getoptstring_COMMON;
 | 
					 | 
				
			||||||
const struct option longopts[] = {
 | 
					 | 
				
			||||||
	{ "chdir",        1, NULL, 'd'},
 | 
					 | 
				
			||||||
	{ "env",          1, NULL, 'e'},
 | 
					 | 
				
			||||||
	{ "group",        1, NULL, 'g'},
 | 
					 | 
				
			||||||
	{ "ionice",       1, NULL, 'I'},
 | 
					 | 
				
			||||||
	{ "stop",         0, NULL, 'K'},
 | 
					 | 
				
			||||||
	{ "umask",        1, NULL, 'k'},
 | 
					 | 
				
			||||||
	{ "nicelevel",    1, NULL, 'N'},
 | 
					 | 
				
			||||||
	{ "pidfile",      1, NULL, 'p'},
 | 
					 | 
				
			||||||
	{ "user",         1, NULL, 'u'},
 | 
					 | 
				
			||||||
	{ "chroot",       1, NULL, 'r'},
 | 
					 | 
				
			||||||
	{ "start",        0, NULL, 'S'},
 | 
					 | 
				
			||||||
	{ "stdout",       1, NULL, '1'},
 | 
					 | 
				
			||||||
	{ "stderr",       1, NULL, '2'},
 | 
					 | 
				
			||||||
	longopts_COMMON
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
const char * const longopts_help[] = {
 | 
					 | 
				
			||||||
	"Change the PWD",
 | 
					 | 
				
			||||||
	"Set an environment string",
 | 
					 | 
				
			||||||
	"Change the process group",
 | 
					 | 
				
			||||||
	"Set an ionice class:data when starting",
 | 
					 | 
				
			||||||
	"Stop daemon",
 | 
					 | 
				
			||||||
	"Set the umask for the daemon",
 | 
					 | 
				
			||||||
	"Set a nicelevel when starting",
 | 
					 | 
				
			||||||
	"Match pid found in this file",
 | 
					 | 
				
			||||||
	"Change the process user",
 | 
					 | 
				
			||||||
	"Chroot to this directory",
 | 
					 | 
				
			||||||
	"Start daemon",
 | 
					 | 
				
			||||||
	"Redirect stdout to file",
 | 
					 | 
				
			||||||
	"Redirect stderr to file",
 | 
					 | 
				
			||||||
	longopts_help_COMMON
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
const char *usagestring = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int nicelevel = 0;
 | 
					 | 
				
			||||||
static int ionicec = -1;
 | 
					 | 
				
			||||||
static int ioniced = 0;
 | 
					 | 
				
			||||||
static char *changeuser, *ch_root, *ch_dir;
 | 
					 | 
				
			||||||
static uid_t uid = 0;
 | 
					 | 
				
			||||||
static gid_t gid = 0;
 | 
					 | 
				
			||||||
static int devnull_fd = -1;
 | 
					 | 
				
			||||||
static int stdin_fd;
 | 
					 | 
				
			||||||
static int stdout_fd;
 | 
					 | 
				
			||||||
static int stderr_fd;
 | 
					 | 
				
			||||||
static char *redirect_stderr = NULL;
 | 
					 | 
				
			||||||
static char *redirect_stdout = NULL;
 | 
					 | 
				
			||||||
static bool exiting = false;
 | 
					 | 
				
			||||||
#ifdef TIOCNOTTY
 | 
					 | 
				
			||||||
static int tty_fd = -1;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern char **environ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if !defined(SYS_ioprio_set) && defined(__NR_ioprio_set)
 | 
					 | 
				
			||||||
# define SYS_ioprio_set __NR_ioprio_set
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#if !defined(__DragonFly__)
 | 
					 | 
				
			||||||
static inline int ioprio_set(int which, int who, int ioprio)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#ifdef SYS_ioprio_set
 | 
					 | 
				
			||||||
	return syscall(SYS_ioprio_set, which, who, ioprio);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void cleanup(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	free(changeuser);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static pid_t get_pid(const char *pidfile)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	FILE *fp;
 | 
					 | 
				
			||||||
	pid_t pid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (! pidfile)
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((fp = fopen(pidfile, "r")) == NULL) {
 | 
					 | 
				
			||||||
		ewarnv("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (fscanf(fp, "%d", &pid) != 1) {
 | 
					 | 
				
			||||||
		ewarnv("%s: no pid found in `%s'", applet, pidfile);
 | 
					 | 
				
			||||||
		fclose(fp);
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fclose(fp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return pid;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void child_process(char *exec, char **argv)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	RC_STRINGLIST *env_list;
 | 
					 | 
				
			||||||
	RC_STRING *env;
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	char *p;
 | 
					 | 
				
			||||||
	char *token;
 | 
					 | 
				
			||||||
	size_t len;
 | 
					 | 
				
			||||||
	char *newpath;
 | 
					 | 
				
			||||||
	char *np;
 | 
					 | 
				
			||||||
	char **c;
 | 
					 | 
				
			||||||
	char cmdline[PATH_MAX];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef HAVE_PAM
 | 
					 | 
				
			||||||
	pam_handle_t *pamh = NULL;
 | 
					 | 
				
			||||||
	int pamr;
 | 
					 | 
				
			||||||
	const char *const *pamenv = NULL;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	setsid();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (nicelevel) {
 | 
					 | 
				
			||||||
		if (setpriority(PRIO_PROCESS, getpid(), nicelevel) == -1)
 | 
					 | 
				
			||||||
			eerrorx("%s: setpriority %d: %s", applet, nicelevel,
 | 
					 | 
				
			||||||
					strerror(errno));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ionicec != -1 && ioprio_set(1, getpid(), ionicec | ioniced) == -1)
 | 
					 | 
				
			||||||
		eerrorx("%s: ioprio_set %d %d: %s", applet, ionicec, ioniced,
 | 
					 | 
				
			||||||
				strerror(errno));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ch_root && chroot(ch_root) < 0)
 | 
					 | 
				
			||||||
		eerrorx("%s: chroot `%s': %s", applet, ch_root, strerror(errno));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ch_dir && chdir(ch_dir) < 0)
 | 
					 | 
				
			||||||
		eerrorx("%s: chdir `%s': %s", applet, ch_dir, strerror(errno));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef HAVE_PAM
 | 
					 | 
				
			||||||
	if (changeuser != NULL) {
 | 
					 | 
				
			||||||
		pamr = pam_start("supervise-daemon",
 | 
					 | 
				
			||||||
		    changeuser, &conv, &pamh);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pamr == PAM_SUCCESS)
 | 
					 | 
				
			||||||
			pamr = pam_acct_mgmt(pamh, PAM_SILENT);
 | 
					 | 
				
			||||||
		if (pamr == PAM_SUCCESS)
 | 
					 | 
				
			||||||
			pamr = pam_open_session(pamh, PAM_SILENT);
 | 
					 | 
				
			||||||
		if (pamr != PAM_SUCCESS)
 | 
					 | 
				
			||||||
			eerrorx("%s: pam error: %s", applet, pam_strerror(pamh, pamr));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (gid && setgid(gid))
 | 
					 | 
				
			||||||
		eerrorx("%s: unable to set groupid to %d", applet, gid);
 | 
					 | 
				
			||||||
	if (changeuser && initgroups(changeuser, gid))
 | 
					 | 
				
			||||||
		eerrorx("%s: initgroups (%s, %d)", applet, changeuser, gid);
 | 
					 | 
				
			||||||
	if (uid && setuid(uid))
 | 
					 | 
				
			||||||
		eerrorx ("%s: unable to set userid to %d", applet, uid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Close any fd's to the passwd database */
 | 
					 | 
				
			||||||
	endpwent();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef TIOCNOTTY
 | 
					 | 
				
			||||||
	ioctl(tty_fd, TIOCNOTTY, 0);
 | 
					 | 
				
			||||||
	close(tty_fd);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Clean the environment of any RC_ variables */
 | 
					 | 
				
			||||||
	env_list = rc_stringlist_new();
 | 
					 | 
				
			||||||
	i = 0;
 | 
					 | 
				
			||||||
	while (environ[i])
 | 
					 | 
				
			||||||
		rc_stringlist_add(env_list, environ[i++]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef HAVE_PAM
 | 
					 | 
				
			||||||
	if (changeuser != NULL) {
 | 
					 | 
				
			||||||
		pamenv = (const char *const *)pam_getenvlist(pamh);
 | 
					 | 
				
			||||||
		if (pamenv) {
 | 
					 | 
				
			||||||
			while (*pamenv) {
 | 
					 | 
				
			||||||
				/* Don't add strings unless they set a var */
 | 
					 | 
				
			||||||
				if (strchr(*pamenv, '='))
 | 
					 | 
				
			||||||
					putenv(xstrdup(*pamenv));
 | 
					 | 
				
			||||||
				else
 | 
					 | 
				
			||||||
					unsetenv(*pamenv);
 | 
					 | 
				
			||||||
				pamenv++;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	TAILQ_FOREACH(env, env_list, entries) {
 | 
					 | 
				
			||||||
		if ((strncmp(env->value, "RC_", 3) == 0 &&
 | 
					 | 
				
			||||||
			strncmp(env->value, "RC_SERVICE=", 10) != 0 &&
 | 
					 | 
				
			||||||
			strncmp(env->value, "RC_SVCNAME=", 10) != 0) ||
 | 
					 | 
				
			||||||
		    strncmp(env->value, "SSD_NICELEVEL=", 14) == 0)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			p = strchr(env->value, '=');
 | 
					 | 
				
			||||||
			*p = '\0';
 | 
					 | 
				
			||||||
			unsetenv(env->value);
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rc_stringlist_free(env_list);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* For the path, remove the rcscript bin dir from it */
 | 
					 | 
				
			||||||
	if ((token = getenv("PATH"))) {
 | 
					 | 
				
			||||||
		len = strlen(token);
 | 
					 | 
				
			||||||
		newpath = np = xmalloc(len + 1);
 | 
					 | 
				
			||||||
		while (token && *token) {
 | 
					 | 
				
			||||||
			p = strchr(token, ':');
 | 
					 | 
				
			||||||
			if (p) {
 | 
					 | 
				
			||||||
				*p++ = '\0';
 | 
					 | 
				
			||||||
				while (*p == ':')
 | 
					 | 
				
			||||||
					p++;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (strcmp(token, RC_LIBEXECDIR "/bin") != 0 &&
 | 
					 | 
				
			||||||
			    strcmp(token, RC_LIBEXECDIR "/sbin") != 0)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				len = strlen(token);
 | 
					 | 
				
			||||||
				if (np != newpath)
 | 
					 | 
				
			||||||
					*np++ = ':';
 | 
					 | 
				
			||||||
				memcpy(np, token, len);
 | 
					 | 
				
			||||||
				np += len;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			token = p;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		*np = '\0';
 | 
					 | 
				
			||||||
		unsetenv("PATH");
 | 
					 | 
				
			||||||
		setenv("PATH", newpath, 1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stdin_fd = devnull_fd;
 | 
					 | 
				
			||||||
	stdout_fd = devnull_fd;
 | 
					 | 
				
			||||||
	stderr_fd = devnull_fd;
 | 
					 | 
				
			||||||
	if (redirect_stdout) {
 | 
					 | 
				
			||||||
		if ((stdout_fd = open(redirect_stdout,
 | 
					 | 
				
			||||||
			    O_WRONLY | O_CREAT | O_APPEND,
 | 
					 | 
				
			||||||
			    S_IRUSR | S_IWUSR)) == -1)
 | 
					 | 
				
			||||||
			eerrorx("%s: unable to open the logfile"
 | 
					 | 
				
			||||||
				    " for stdout `%s': %s",
 | 
					 | 
				
			||||||
				    applet, redirect_stdout, strerror(errno));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (redirect_stderr) {
 | 
					 | 
				
			||||||
		if ((stderr_fd = open(redirect_stderr,
 | 
					 | 
				
			||||||
			    O_WRONLY | O_CREAT | O_APPEND,
 | 
					 | 
				
			||||||
			    S_IRUSR | S_IWUSR)) == -1)
 | 
					 | 
				
			||||||
			eerrorx("%s: unable to open the logfile"
 | 
					 | 
				
			||||||
			    " for stderr `%s': %s",
 | 
					 | 
				
			||||||
			    applet, redirect_stderr, strerror(errno));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dup2(stdin_fd, STDIN_FILENO);
 | 
					 | 
				
			||||||
	if (redirect_stdout || rc_yesno(getenv("EINFO_QUIET")))
 | 
					 | 
				
			||||||
		dup2(stdout_fd, STDOUT_FILENO);
 | 
					 | 
				
			||||||
	if (redirect_stderr || rc_yesno(getenv("EINFO_QUIET")))
 | 
					 | 
				
			||||||
		dup2(stderr_fd, STDERR_FILENO);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = getdtablesize() - 1; i >= 3; --i)
 | 
					 | 
				
			||||||
		close(i);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*cmdline = '\0';
 | 
					 | 
				
			||||||
	c = argv;
 | 
					 | 
				
			||||||
	while (*c) {
 | 
					 | 
				
			||||||
		strcat(cmdline, *c);
 | 
					 | 
				
			||||||
		strcat(cmdline, " ");
 | 
					 | 
				
			||||||
		c++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	syslog(LOG_INFO, "Running command line: %s", cmdline);
 | 
					 | 
				
			||||||
	execvp(exec, argv);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef HAVE_PAM
 | 
					 | 
				
			||||||
	if (changeuser != NULL && pamr == PAM_SUCCESS)
 | 
					 | 
				
			||||||
		pam_close_session(pamh, PAM_SILENT);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	eerrorx("%s: failed to exec `%s': %s", applet, exec,strerror(errno));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void handle_signal(int sig)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int serrno = errno;
 | 
					 | 
				
			||||||
	char signame[10] = { '\0' };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (sig) {
 | 
					 | 
				
			||||||
	case SIGINT:
 | 
					 | 
				
			||||||
		snprintf(signame, sizeof(signame), "SIGINT");
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case SIGTERM:
 | 
					 | 
				
			||||||
		snprintf(signame, sizeof(signame), "SIGTERM");
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case SIGQUIT:
 | 
					 | 
				
			||||||
		snprintf(signame, sizeof(signame), "SIGQUIT");
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (*signame != 0) {
 | 
					 | 
				
			||||||
		syslog(LOG_INFO, "%s: caught signal %s, exiting", applet, signame);
 | 
					 | 
				
			||||||
		exiting = true;
 | 
					 | 
				
			||||||
	} else
 | 
					 | 
				
			||||||
		syslog(LOG_INFO, "%s: caught unknown signal %d", applet, sig);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Restore errno */
 | 
					 | 
				
			||||||
	errno = serrno;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char * expand_home(const char *home, const char *path)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char *opath, *ppath, *p, *nh;
 | 
					 | 
				
			||||||
	size_t len;
 | 
					 | 
				
			||||||
	struct passwd *pw;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!path || *path != '~')
 | 
					 | 
				
			||||||
		return xstrdup(path);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	opath = ppath = xstrdup(path);
 | 
					 | 
				
			||||||
	if (ppath[1] != '/' && ppath[1] != '\0') {
 | 
					 | 
				
			||||||
		p = strchr(ppath + 1, '/');
 | 
					 | 
				
			||||||
		if (p)
 | 
					 | 
				
			||||||
			*p = '\0';
 | 
					 | 
				
			||||||
		pw = getpwnam(ppath + 1);
 | 
					 | 
				
			||||||
		if (pw) {
 | 
					 | 
				
			||||||
			home = pw->pw_dir;
 | 
					 | 
				
			||||||
			ppath = p;
 | 
					 | 
				
			||||||
			if (ppath)
 | 
					 | 
				
			||||||
				*ppath = '/';
 | 
					 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			home = NULL;
 | 
					 | 
				
			||||||
	} else
 | 
					 | 
				
			||||||
		ppath++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!home) {
 | 
					 | 
				
			||||||
	free(opath);
 | 
					 | 
				
			||||||
		return xstrdup(path);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!ppath) {
 | 
					 | 
				
			||||||
		free(opath);
 | 
					 | 
				
			||||||
		return xstrdup(home);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	len = strlen(ppath) + strlen(home) + 1;
 | 
					 | 
				
			||||||
	nh = xmalloc(len);
 | 
					 | 
				
			||||||
	snprintf(nh, len, "%s%s", home, ppath);
 | 
					 | 
				
			||||||
	free(opath);
 | 
					 | 
				
			||||||
	return nh;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, char **argv)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int opt;
 | 
					 | 
				
			||||||
	bool start = false;
 | 
					 | 
				
			||||||
	bool stop = false;
 | 
					 | 
				
			||||||
	char *exec = NULL;
 | 
					 | 
				
			||||||
	char *pidfile = NULL;
 | 
					 | 
				
			||||||
	char *home = NULL;
 | 
					 | 
				
			||||||
	int tid = 0;
 | 
					 | 
				
			||||||
	pid_t child_pid, pid;
 | 
					 | 
				
			||||||
	char *svcname = getenv("RC_SVCNAME");
 | 
					 | 
				
			||||||
	char *tmp;
 | 
					 | 
				
			||||||
	char *p;
 | 
					 | 
				
			||||||
	char *token;
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	char exec_file[PATH_MAX];
 | 
					 | 
				
			||||||
	struct passwd *pw;
 | 
					 | 
				
			||||||
	struct group *gr;
 | 
					 | 
				
			||||||
	FILE *fp;
 | 
					 | 
				
			||||||
	mode_t numask = 022;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	applet = basename_c(argv[0]);
 | 
					 | 
				
			||||||
	atexit(cleanup);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	signal_setup(SIGINT, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup(SIGQUIT, handle_signal);
 | 
					 | 
				
			||||||
	signal_setup(SIGTERM, handle_signal);
 | 
					 | 
				
			||||||
	openlog(applet, LOG_PID, LOG_DAEMON);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((tmp = getenv("SSD_NICELEVEL")))
 | 
					 | 
				
			||||||
		if (sscanf(tmp, "%d", &nicelevel) != 1)
 | 
					 | 
				
			||||||
			eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
 | 
					 | 
				
			||||||
			    applet, tmp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Get our user name and initial dir */
 | 
					 | 
				
			||||||
	p = getenv("USER");
 | 
					 | 
				
			||||||
	home = getenv("HOME");
 | 
					 | 
				
			||||||
	if (home == NULL || p == NULL) {
 | 
					 | 
				
			||||||
		pw = getpwuid(getuid());
 | 
					 | 
				
			||||||
		if (pw != NULL) {
 | 
					 | 
				
			||||||
			if (p == NULL)
 | 
					 | 
				
			||||||
				setenv("USER", pw->pw_name, 1);
 | 
					 | 
				
			||||||
			if (home == NULL) {
 | 
					 | 
				
			||||||
				setenv("HOME", pw->pw_dir, 1);
 | 
					 | 
				
			||||||
				home = pw->pw_dir;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while ((opt = getopt_long(argc, argv, getoptstring, longopts,
 | 
					 | 
				
			||||||
		    (int *) 0)) != -1)
 | 
					 | 
				
			||||||
		switch (opt) {
 | 
					 | 
				
			||||||
		case 'I': /* --ionice */
 | 
					 | 
				
			||||||
			if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
 | 
					 | 
				
			||||||
				eerrorx("%s: invalid ionice `%s'",
 | 
					 | 
				
			||||||
				    applet, optarg);
 | 
					 | 
				
			||||||
			if (ionicec == 0)
 | 
					 | 
				
			||||||
				ioniced = 0;
 | 
					 | 
				
			||||||
			else if (ionicec == 3)
 | 
					 | 
				
			||||||
				ioniced = 7;
 | 
					 | 
				
			||||||
			ionicec <<= 13; /* class shift */
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'K':  /* --stop */
 | 
					 | 
				
			||||||
			stop = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'N':  /* --nice */
 | 
					 | 
				
			||||||
			if (sscanf(optarg, "%d", &nicelevel) != 1)
 | 
					 | 
				
			||||||
				eerrorx("%s: invalid nice level `%s'",
 | 
					 | 
				
			||||||
				    applet, optarg);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'S':  /* --start */
 | 
					 | 
				
			||||||
			start = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'd':  /* --chdir /new/dir */
 | 
					 | 
				
			||||||
			ch_dir = optarg;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'e': /* --env */
 | 
					 | 
				
			||||||
			putenv(optarg);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'g':  /* --group <group>|<gid> */
 | 
					 | 
				
			||||||
			if (sscanf(optarg, "%d", &tid) != 1)
 | 
					 | 
				
			||||||
				gr = getgrnam(optarg);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				gr = getgrgid((gid_t)tid);
 | 
					 | 
				
			||||||
			if (gr == NULL)
 | 
					 | 
				
			||||||
				eerrorx("%s: group `%s' not found",
 | 
					 | 
				
			||||||
				    applet, optarg);
 | 
					 | 
				
			||||||
			gid = gr->gr_gid;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'k':
 | 
					 | 
				
			||||||
			if (parse_mode(&numask, optarg))
 | 
					 | 
				
			||||||
				eerrorx("%s: invalid mode `%s'",
 | 
					 | 
				
			||||||
				    applet, optarg);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'p':  /* --pidfile <pid-file> */
 | 
					 | 
				
			||||||
			pidfile = optarg;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'r':  /* --chroot /new/root */
 | 
					 | 
				
			||||||
			ch_root = optarg;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'u':  /* --user <username>|<uid> */
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			p = optarg;
 | 
					 | 
				
			||||||
			tmp = strsep(&p, ":");
 | 
					 | 
				
			||||||
			changeuser = xstrdup(tmp);
 | 
					 | 
				
			||||||
			if (sscanf(tmp, "%d", &tid) != 1)
 | 
					 | 
				
			||||||
				pw = getpwnam(tmp);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				pw = getpwuid((uid_t)tid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (pw == NULL)
 | 
					 | 
				
			||||||
				eerrorx("%s: user `%s' not found",
 | 
					 | 
				
			||||||
				    applet, tmp);
 | 
					 | 
				
			||||||
			uid = pw->pw_uid;
 | 
					 | 
				
			||||||
			home = pw->pw_dir;
 | 
					 | 
				
			||||||
			unsetenv("HOME");
 | 
					 | 
				
			||||||
			if (pw->pw_dir)
 | 
					 | 
				
			||||||
				setenv("HOME", pw->pw_dir, 1);
 | 
					 | 
				
			||||||
			unsetenv("USER");
 | 
					 | 
				
			||||||
			if (pw->pw_name)
 | 
					 | 
				
			||||||
				setenv("USER", pw->pw_name, 1);
 | 
					 | 
				
			||||||
			if (gid == 0)
 | 
					 | 
				
			||||||
				gid = pw->pw_gid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (p) {
 | 
					 | 
				
			||||||
				tmp = strsep (&p, ":");
 | 
					 | 
				
			||||||
				if (sscanf(tmp, "%d", &tid) != 1)
 | 
					 | 
				
			||||||
					gr = getgrnam(tmp);
 | 
					 | 
				
			||||||
				else
 | 
					 | 
				
			||||||
					gr = getgrgid((gid_t) tid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (gr == NULL)
 | 
					 | 
				
			||||||
					eerrorx("%s: group `%s'"
 | 
					 | 
				
			||||||
					    " not found",
 | 
					 | 
				
			||||||
					    applet, tmp);
 | 
					 | 
				
			||||||
				gid = gr->gr_gid;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case '1':   /* --stdout /path/to/stdout.lgfile */
 | 
					 | 
				
			||||||
			redirect_stdout = optarg;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case '2':  /* --stderr /path/to/stderr.logfile */
 | 
					 | 
				
			||||||
			redirect_stderr = optarg;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case_RC_COMMON_GETOPT
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!pidfile)
 | 
					 | 
				
			||||||
		eerrorx("%s: --pidfile must be specified", applet);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	endpwent();
 | 
					 | 
				
			||||||
	argc -= optind;
 | 
					 | 
				
			||||||
	argv += optind;
 | 
					 | 
				
			||||||
	exec = *argv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (start) {
 | 
					 | 
				
			||||||
		if (!exec)
 | 
					 | 
				
			||||||
			eerrorx("%s: nothing to start", applet);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Expand ~ */
 | 
					 | 
				
			||||||
	if (ch_dir && *ch_dir == '~')
 | 
					 | 
				
			||||||
		ch_dir = expand_home(home, ch_dir);
 | 
					 | 
				
			||||||
	if (ch_root && *ch_root == '~')
 | 
					 | 
				
			||||||
		ch_root = expand_home(home, ch_root);
 | 
					 | 
				
			||||||
	if (exec) {
 | 
					 | 
				
			||||||
		if (*exec == '~')
 | 
					 | 
				
			||||||
			exec = expand_home(home, exec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Validate that the binary exists if we are starting */
 | 
					 | 
				
			||||||
		if (*exec == '/' || *exec == '.') {
 | 
					 | 
				
			||||||
			/* Full or relative path */
 | 
					 | 
				
			||||||
			if (ch_root)
 | 
					 | 
				
			||||||
				snprintf(exec_file, sizeof(exec_file),
 | 
					 | 
				
			||||||
				    "%s/%s", ch_root, exec);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				snprintf(exec_file, sizeof(exec_file),
 | 
					 | 
				
			||||||
				    "%s", exec);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			/* Something in $PATH */
 | 
					 | 
				
			||||||
			p = tmp = xstrdup(getenv("PATH"));
 | 
					 | 
				
			||||||
			*exec_file = '\0';
 | 
					 | 
				
			||||||
			while ((token = strsep(&p, ":"))) {
 | 
					 | 
				
			||||||
				if (ch_root)
 | 
					 | 
				
			||||||
					snprintf(exec_file, sizeof(exec_file),
 | 
					 | 
				
			||||||
					    "%s/%s/%s",
 | 
					 | 
				
			||||||
					    ch_root, token, exec);
 | 
					 | 
				
			||||||
				else
 | 
					 | 
				
			||||||
					snprintf(exec_file, sizeof(exec_file),
 | 
					 | 
				
			||||||
					    "%s/%s", token, exec);
 | 
					 | 
				
			||||||
				if (exists(exec_file))
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				*exec_file = '\0';
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			free(tmp);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (start && !exists(exec_file))
 | 
					 | 
				
			||||||
		eerrorx("%s: %s does not exist", applet,
 | 
					 | 
				
			||||||
		    *exec_file ? exec_file : exec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (stop) {
 | 
					 | 
				
			||||||
		pid = get_pid(pidfile);
 | 
					 | 
				
			||||||
		if (pid == -1)
 | 
					 | 
				
			||||||
			i = pid;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			i = kill(pid, SIGTERM);
 | 
					 | 
				
			||||||
		if (i != 0)
 | 
					 | 
				
			||||||
			/* We failed to stop something */
 | 
					 | 
				
			||||||
			exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Even if we have not actually killed anything, we should
 | 
					 | 
				
			||||||
		 * remove information about it as it may have unexpectedly
 | 
					 | 
				
			||||||
		 * crashed out. We should also return success as the end
 | 
					 | 
				
			||||||
		 * result would be the same. */
 | 
					 | 
				
			||||||
		if (pidfile && exists(pidfile))
 | 
					 | 
				
			||||||
			unlink(pidfile);
 | 
					 | 
				
			||||||
		if (svcname)
 | 
					 | 
				
			||||||
			rc_service_daemon_set(svcname, exec,
 | 
					 | 
				
			||||||
			    (const char *const *)argv,
 | 
					 | 
				
			||||||
			    pidfile, false);
 | 
					 | 
				
			||||||
		exit(EXIT_SUCCESS);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pid = get_pid(pidfile);
 | 
					 | 
				
			||||||
	if (pid != -1)
 | 
					 | 
				
			||||||
		if (kill(pid, 0) == 0)
 | 
					 | 
				
			||||||
			eerrorx("%s: %s is already running", applet, exec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	einfov("Detaching to start `%s'", exec);
 | 
					 | 
				
			||||||
	eindentv();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Remove existing pidfile */
 | 
					 | 
				
			||||||
	if (pidfile)
 | 
					 | 
				
			||||||
		unlink(pidfile);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Make sure we can write a pid file
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	fp = fopen(pidfile, "w");
 | 
					 | 
				
			||||||
	if (! fp)
 | 
					 | 
				
			||||||
		eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
 | 
					 | 
				
			||||||
		fclose(fp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	child_pid = fork();
 | 
					 | 
				
			||||||
	if (child_pid == -1)
 | 
					 | 
				
			||||||
		eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* first parent process, do nothing. */
 | 
					 | 
				
			||||||
	if (child_pid != 0)
 | 
					 | 
				
			||||||
		exit(EXIT_SUCCESS);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	child_pid = fork();
 | 
					 | 
				
			||||||
	if (child_pid == -1)
 | 
					 | 
				
			||||||
		eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (child_pid != 0) {
 | 
					 | 
				
			||||||
		/* this is the supervisor */
 | 
					 | 
				
			||||||
		umask(numask);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef TIOCNOTTY
 | 
					 | 
				
			||||||
		tty_fd = open("/dev/tty", O_RDWR);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		devnull_fd = open("/dev/null", O_RDWR);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		fp = fopen(pidfile, "w");
 | 
					 | 
				
			||||||
		if (! fp)
 | 
					 | 
				
			||||||
			eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
 | 
					 | 
				
			||||||
		fprintf(fp, "%d\n", getpid());
 | 
					 | 
				
			||||||
		fclose(fp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * Supervisor main loop
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		i = 0;
 | 
					 | 
				
			||||||
		while (!exiting) {
 | 
					 | 
				
			||||||
			wait(&i);
 | 
					 | 
				
			||||||
			if (exiting) {
 | 
					 | 
				
			||||||
				syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
 | 
					 | 
				
			||||||
				kill(child_pid, SIGTERM);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				if (WIFEXITED(i))
 | 
					 | 
				
			||||||
					syslog(LOG_INFO, "%s, pid %d, exited with return code %d",
 | 
					 | 
				
			||||||
							exec, child_pid, WEXITSTATUS(i));
 | 
					 | 
				
			||||||
				else if (WIFSIGNALED(i))
 | 
					 | 
				
			||||||
					syslog(LOG_INFO, "%s, pid %d, terminated by signal %d",
 | 
					 | 
				
			||||||
							exec, child_pid, WTERMSIG(i));
 | 
					 | 
				
			||||||
				child_pid = fork();
 | 
					 | 
				
			||||||
				if (child_pid == -1)
 | 
					 | 
				
			||||||
					eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
					 | 
				
			||||||
				if (child_pid == 0)
 | 
					 | 
				
			||||||
					child_process(exec, argv);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (svcname)
 | 
					 | 
				
			||||||
			rc_service_daemon_set(svcname, exec,
 | 
					 | 
				
			||||||
									(const char * const *) argv, pidfile, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		exit(EXIT_SUCCESS);
 | 
					 | 
				
			||||||
	} else if (child_pid == 0)
 | 
					 | 
				
			||||||
		child_process(exec, argv);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
#%PAM-1.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
auth            required        pam_permit.so
 | 
					 | 
				
			||||||
account         required        pam_permit.so
 | 
					 | 
				
			||||||
password        required        pam_deny.so
 | 
					 | 
				
			||||||
session         optional        pam_limits.so
 | 
					 | 
				
			||||||
@@ -30,7 +30,6 @@
 | 
				
			|||||||
#include <utime.h>
 | 
					#include <utime.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "einfo.h"
 | 
					#include "einfo.h"
 | 
				
			||||||
#include "rc.h"
 | 
					 | 
				
			||||||
#include "rc-misc.h"
 | 
					#include "rc-misc.h"
 | 
				
			||||||
#include "_usage.h"
 | 
					#include "_usage.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,14 +85,12 @@ eend $? "Trailing newlines need to be deleted:"$'\n'"${out}"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
ebegin "Checking for obsolete functions"
 | 
					ebegin "Checking for obsolete functions"
 | 
				
			||||||
out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
 | 
					out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
 | 
				
			||||||
	! -name queue.h \
 | 
					 | 
				
			||||||
	-exec grep -n -E '\<(malloc|memory|sys/(errno|fcntl|signal|stropts|termios|unistd))\.h\>' {} +)
 | 
						-exec grep -n -E '\<(malloc|memory|sys/(errno|fcntl|signal|stropts|termios|unistd))\.h\>' {} +)
 | 
				
			||||||
[ -z "${out}" ]
 | 
					[ -z "${out}" ]
 | 
				
			||||||
eend $? "Avoid these obsolete functions:"$'\n'"${out}"
 | 
					eend $? "Avoid these obsolete functions:"$'\n'"${out}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ebegin "Checking for x* func usage"
 | 
					ebegin "Checking for x* func usage"
 | 
				
			||||||
out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
 | 
					out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
 | 
				
			||||||
	! -name queue.h \
 | 
					 | 
				
			||||||
	-exec grep -n -E '\<(malloc|strdup)[[:space:]]*\(' {} + \
 | 
						-exec grep -n -E '\<(malloc|strdup)[[:space:]]*\(' {} + \
 | 
				
			||||||
	| grep -v \
 | 
						| grep -v \
 | 
				
			||||||
		-e src/includes/helpers.h \
 | 
							-e src/includes/helpers.h \
 | 
				
			||||||
@@ -102,7 +100,6 @@ eend $? "These need to be using the x* variant:"$'\n'"${out}"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
ebegin "Checking spacing style"
 | 
					ebegin "Checking spacing style"
 | 
				
			||||||
out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
 | 
					out=$(cd ${top_srcdir}; find src -name '*.[ch]' \
 | 
				
			||||||
	! -name queue.h \
 | 
					 | 
				
			||||||
	-exec grep -n -E \
 | 
						-exec grep -n -E \
 | 
				
			||||||
		-e '\<(for|if|switch|while)\(' \
 | 
							-e '\<(for|if|switch|while)\(' \
 | 
				
			||||||
		-e '\<(for|if|switch|while) \( ' \
 | 
							-e '\<(for|if|switch|while) \( ' \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,49 +0,0 @@
 | 
				
			|||||||
# Using supervise-daemon
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Beginning with OpenRC-0.21 we have our own daemon supervisor,
 | 
					 | 
				
			||||||
supervise-daemon., which can start a daemon and restart it if it
 | 
					 | 
				
			||||||
terminates unexpectedly.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The following is a brief guide on using this capability.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Use Default start, stop and status functions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you write your own start, stop and status functions in your service
 | 
					 | 
				
			||||||
script, none of this will work. You must allow OpenRC to use the default
 | 
					 | 
				
			||||||
functions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Daemons must not fork
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Any deamon that you would like to have monitored by supervise-daemon
 | 
					 | 
				
			||||||
must not fork. Instead, it must stay in the foreground. If the daemon
 | 
					 | 
				
			||||||
itself forks, the supervisor will be unable to monitor it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If the daemon can be configured to not fork, this should be done in the
 | 
					 | 
				
			||||||
daemon's configuration file, or by adding a command line option that
 | 
					 | 
				
			||||||
instructs it not to fork to the command_args_foreground variable shown
 | 
					 | 
				
			||||||
below.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Variable Settings
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The most important setting is the supervisor variable. At the top of
 | 
					 | 
				
			||||||
your service script, you should set this variable as follows:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
supervisor=supervise-daemon
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Several other variables affect the way services behave under
 | 
					 | 
				
			||||||
supervise-daemon. They are documented on the  openrc-run man page, but I
 | 
					 | 
				
			||||||
will list them here for convenience:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pidfile=/pid/of/supervisor.pid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you are using start-stop-daemon to monitor your scripts, the pidfile
 | 
					 | 
				
			||||||
is the path to the pidfile the daemon creates. If, on the other hand,
 | 
					 | 
				
			||||||
you are using supervise-daemon, this is the path to the pidfile the
 | 
					 | 
				
			||||||
supervisor creates.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
command_args_foreground should be used if the daemon you want to monitor
 | 
					 | 
				
			||||||
forks and goes to the background by default. This should be set to the
 | 
					 | 
				
			||||||
command line option that instructs the daemon to stay in the foreground.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is very early support, so feel free to file bugs if you have
 | 
					 | 
				
			||||||
issues.
 | 
					 | 
				
			||||||
@@ -21,3 +21,7 @@ LD_LIBRARY_PATH=${top_builddir}/src/libeinfo:${top_builddir}/src/librc:${LD_LIBR
 | 
				
			|||||||
PATH=${top_builddir}/src/rc:${PATH}
 | 
					PATH=${top_builddir}/src/rc:${PATH}
 | 
				
			||||||
export LD_LIBRARY_PATH PATH
 | 
					export LD_LIBRARY_PATH PATH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cd ${top_srcdir}/src/rc
 | 
				
			||||||
 | 
					${MAKE:-make} links >/dev/null
 | 
				
			||||||
 | 
					cd -
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user