Add rc-service and update all softlevel refs to runlevel.
This commit is contained in:
parent
089caec283
commit
d9ec62b22a
@ -126,7 +126,7 @@ start()
|
|||||||
stop()
|
stop()
|
||||||
{
|
{
|
||||||
# Write a halt record if we're shutting down
|
# Write a halt record if we're shutting down
|
||||||
case "${RC_SOFTLEVEL}" in
|
case "${RC_RUNLEVEL}" in
|
||||||
reboot|shutdown) [ "${RC_UNAME}" = "Linux" ] && halt -w;;
|
reboot|shutdown) [ "${RC_UNAME}" = "Linux" ] && halt -w;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ _abort() {
|
|||||||
|
|
||||||
# We should only reboot when first booting
|
# We should only reboot when first booting
|
||||||
_reboot() {
|
_reboot() {
|
||||||
if [ "${RC_SOFTLEVEL}" = "${RC_BOOTLEVEL}" ]; then
|
if [ "${RC_RUNLEVEL}" = "${RC_BOOTLEVEL}" ]; then
|
||||||
reboot "$@"
|
reboot "$@"
|
||||||
_abort || return 1
|
_abort || return 1
|
||||||
fi
|
fi
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
MAN3= einfo.3 \
|
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-status.8 rc-update.8 rc.8 runscript.8 start-stop-daemon.8
|
MAN8= rc-service.8 rc-status.8 rc-update.8 rc.8 runscript.8 \
|
||||||
|
start-stop-daemon.8
|
||||||
|
|
||||||
# Handy macro to create symlinks
|
# Handy macro to create symlinks
|
||||||
# This does rely on correctly formatting our manpages!
|
# This does rely on correctly formatting our manpages!
|
||||||
|
42
man/rc-service.8
Normal file
42
man/rc-service.8
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
.\" Copyright 2008 Roy Marples
|
||||||
|
.\" All rights reserved
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.Dd Mar 19, 2008
|
||||||
|
.Dt RC-SERVICE 8 SMM
|
||||||
|
.Os OpenRC
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rc-service
|
||||||
|
.Nd locate and run an OpenRC service with the given arguments
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Ar service cmd
|
||||||
|
.Op Ar ...
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
Service scripts could be in different places on different systems.
|
||||||
|
.Nm
|
||||||
|
locates the specified service and runs it with the given arguments.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rc 8 ,
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An "Roy Marples" Aq roy@marples.name
|
@ -278,7 +278,7 @@ sets the following environment variables for use in the service scripts:
|
|||||||
.Bl -tag -width "RC_DEFAULTLEVEL"
|
.Bl -tag -width "RC_DEFAULTLEVEL"
|
||||||
.It Va SVCNAME
|
.It Va SVCNAME
|
||||||
Name of the service.
|
Name of the service.
|
||||||
.It Va RC_SOFTLEVEL
|
.It Va RC_RUNLEVEL
|
||||||
Current runlevel that rc is in.
|
Current runlevel that rc is in.
|
||||||
.It Va RC_BOOTLEVEL
|
.It Va RC_BOOTLEVEL
|
||||||
Boot runlevel chosen. Default is boot.
|
Boot runlevel chosen. Default is boot.
|
||||||
@ -293,7 +293,7 @@ The result of `uname -s`.
|
|||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Pp
|
.Pp
|
||||||
Configuration files, relative to the location of the service.
|
Configuration files, relative to the location of the service.
|
||||||
If a file ending with .${RC_SOFTLEVEL} exists then we use that instead.
|
If a file ending with .${RC_RUNLEVEL} exists then we use that instead.
|
||||||
.Bl -ohang
|
.Bl -ohang
|
||||||
.It Pa ../conf.d/${SVCNAME%%.*}
|
.It Pa ../conf.d/${SVCNAME%%.*}
|
||||||
mulitplexed configuration file.
|
mulitplexed configuration file.
|
||||||
|
2
mk/os.mk
2
mk/os.mk
@ -13,7 +13,7 @@ _PREFIX_SH= if test -n "${PREFIX}" && test "${PREFIX}" != "/"; then echo "-DPREF
|
|||||||
_PREFIX!= ${_PREFIX_SH}
|
_PREFIX!= ${_PREFIX_SH}
|
||||||
CFLAGS+= ${_PREFIX}$(shell ${_PREFIX_SH})
|
CFLAGS+= ${_PREFIX}$(shell ${_PREFIX_SH})
|
||||||
|
|
||||||
_PKG_PREFIX_SH= if test -n "${PKG_PREFIX}" && test "${PKG_PREFIX}" != "/"; then echo "-DPKG_PREFIX=\\\"${PKG_PREFIX}\\\""; else echo ""; fi
|
_PKG_PREFIX_SH= if test -n "${PKG_PREFIX}" && test "${PKG_PREFIX}" != "/" && test "${PKG_PREFIX}" != "${PREFIX}"; then echo "-DPKG_PREFIX=\\\"${PKG_PREFIX}\\\""; else echo ""; fi
|
||||||
_PKG_PREFIX!= ${_PKG_PREFIX_SH}
|
_PKG_PREFIX!= ${_PKG_PREFIX_SH}
|
||||||
CFLAGS+= ${_PKG_PREFIX}$(shell ${_PKG_PREFIX_SH})
|
CFLAGS+= ${_PKG_PREFIX}$(shell ${_PKG_PREFIX_SH})
|
||||||
|
|
||||||
|
@ -47,8 +47,8 @@ _conf_d=${1%/*}/../conf.d
|
|||||||
# If we're net.eth0 or openvpn.work then load net or openvpn config
|
# If we're net.eth0 or openvpn.work then load net or openvpn config
|
||||||
_c=${SVCNAME%%.*}
|
_c=${SVCNAME%%.*}
|
||||||
if [ -n "${_c}" -a "${_c}" != "${SVCNAME}" ]; then
|
if [ -n "${_c}" -a "${_c}" != "${SVCNAME}" ]; then
|
||||||
if [ -e "${_conf_d}/${_c}.${RC_SOFTLEVEL}" ]; then
|
if [ -e "${_conf_d}/${_c}.${RC_RUNLEVEL}" ]; then
|
||||||
. "${_conf_d}/${_c}.${RC_SOFTLEVEL}"
|
. "${_conf_d}/${_c}.${RC_RUNLEVEL}"
|
||||||
elif [ -e "${_conf_d}/${_c}" ]; then
|
elif [ -e "${_conf_d}/${_c}" ]; then
|
||||||
. "${_conf_d}//${_c}"
|
. "${_conf_d}//${_c}"
|
||||||
fi
|
fi
|
||||||
@ -56,8 +56,8 @@ fi
|
|||||||
unset _c
|
unset _c
|
||||||
|
|
||||||
# Overlay with our specific config
|
# Overlay with our specific config
|
||||||
if [ -e "${_conf_d}/${SVCNAME}.${RC_SOFTLEVEL}" ]; then
|
if [ -e "${_conf_d}/${SVCNAME}.${RC_RUNLEVEL}" ]; then
|
||||||
. "${_conf_d}/${SVCNAME}.${RC_SOFTLEVEL}"
|
. "${_conf_d}/${SVCNAME}.${RC_RUNLEVEL}"
|
||||||
elif [ -e "${_conf_d}/${SVCNAME}" ]; then
|
elif [ -e "${_conf_d}/${SVCNAME}" ]; then
|
||||||
. "${_conf_d}/${SVCNAME}"
|
. "${_conf_d}/${SVCNAME}"
|
||||||
fi
|
fi
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
# define RC_LOCAL_CONFDIR LOCAL_PREFIX SYSCONFDIR "/conf.d"
|
# define RC_LOCAL_CONFDIR LOCAL_PREFIX SYSCONFDIR "/conf.d"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RC_KSOFTLEVEL RC_SVCDIR "/ksoftlevel"
|
#define RC_KRUNLEVEL RC_SVCDIR "/krunlevel"
|
||||||
#define RC_STARTING RC_SVCDIR "/rc.starting"
|
#define RC_STARTING RC_SVCDIR "/rc.starting"
|
||||||
#define RC_STOPPING RC_SVCDIR "/rc.stopping"
|
#define RC_STOPPING RC_SVCDIR "/rc.stopping"
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ const char librc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
|
|||||||
#endif
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#define SOFTLEVEL RC_SVCDIR "/softlevel"
|
#define RC_RUNLEVEL RC_SVCDIR "/softlevel"
|
||||||
|
|
||||||
#ifndef S_IXUGO
|
#ifndef S_IXUGO
|
||||||
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
||||||
@ -268,7 +268,7 @@ char *rc_runlevel_get(void)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *runlevel = NULL;
|
char *runlevel = NULL;
|
||||||
|
|
||||||
if ((fp = fopen(SOFTLEVEL, "r"))) {
|
if ((fp = fopen(RC_RUNLEVEL, "r"))) {
|
||||||
runlevel = xmalloc(sizeof(char) * PATH_MAX);
|
runlevel = xmalloc(sizeof(char) * PATH_MAX);
|
||||||
if (fgets(runlevel, PATH_MAX, fp)) {
|
if (fgets(runlevel, PATH_MAX, fp)) {
|
||||||
int i = strlen(runlevel) - 1;
|
int i = strlen(runlevel) - 1;
|
||||||
@ -290,7 +290,7 @@ librc_hidden_def(rc_runlevel_get)
|
|||||||
|
|
||||||
bool rc_runlevel_set(const char *runlevel)
|
bool rc_runlevel_set(const char *runlevel)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(SOFTLEVEL, "w");
|
FILE *fp = fopen(RC_RUNLEVEL, "w");
|
||||||
|
|
||||||
if (! fp)
|
if (! fp)
|
||||||
return false;
|
return false;
|
||||||
|
@ -11,7 +11,7 @@ SBINDIR= ${PREFIX}/sbin
|
|||||||
LINKDIR= ${PREFIX}/${LIBNAME}/${PROG}
|
LINKDIR= ${PREFIX}/${LIBNAME}/${PROG}
|
||||||
|
|
||||||
BINLINKS= rc-status
|
BINLINKS= rc-status
|
||||||
SBINLINKS= rc-update runscript start-stop-daemon
|
SBINLINKS= rc-service rc-update runscript start-stop-daemon
|
||||||
RC_BINLINKS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
RC_BINLINKS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
||||||
eindent eoutdent esyslog eval_ecolors \
|
eindent eoutdent esyslog eval_ecolors \
|
||||||
veinfo vewarn vebegin veend vewend veindent veoutdent \
|
veinfo vewarn vebegin veend vewend veindent veoutdent \
|
||||||
|
@ -362,6 +362,18 @@ static int do_shell_var(int argc, char **argv)
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rc_service(_unused int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *service = rc_service_resolve(argv[1]);
|
||||||
|
|
||||||
|
if (!service)
|
||||||
|
eerrorx("%s: service `%s' does not exist", applet, optarg);
|
||||||
|
|
||||||
|
*++argv = service;
|
||||||
|
execv(*argv, argv);
|
||||||
|
eerrorx("%s: %s", applet, strerror(errno));
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
void run_applets(int argc, char **argv)
|
void run_applets(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -377,6 +389,8 @@ void run_applets(int argc, char **argv)
|
|||||||
exit(mountinfo(argc, argv));
|
exit(mountinfo(argc, argv));
|
||||||
else if (strcmp(applet, "rc-depend") == 0)
|
else if (strcmp(applet, "rc-depend") == 0)
|
||||||
exit(rc_depend(argc, argv));
|
exit(rc_depend(argc, argv));
|
||||||
|
else if (strcmp(applet, "rc-service") == 0)
|
||||||
|
exit(rc_service(argc, argv));
|
||||||
else if (strcmp(applet, "rc-status") == 0)
|
else if (strcmp(applet, "rc-status") == 0)
|
||||||
exit(rc_status(argc, argv));
|
exit(rc_status(argc, argv));
|
||||||
else if (strcmp(applet, "rc-update") == 0 ||
|
else if (strcmp(applet, "rc-update") == 0 ||
|
||||||
|
@ -107,7 +107,7 @@ int rc_depend(int argc, char **argv)
|
|||||||
int options = RC_DEP_TRACE;
|
int options = RC_DEP_TRACE;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
bool update = false;
|
bool update = false;
|
||||||
char *runlevel = xstrdup(getenv("RC_SOFTLEVEL"));
|
char *runlevel = xstrdup(getenv("RC_RUNLEVEL"));
|
||||||
int opt;
|
int opt;
|
||||||
char *token;
|
char *token;
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ void env_config(void)
|
|||||||
setenv("RC_RUNLEVEL", e, 1);
|
setenv("RC_RUNLEVEL", e, 1);
|
||||||
free(e);
|
free(e);
|
||||||
|
|
||||||
if ((fp = fopen(RC_KSOFTLEVEL, "r"))) {
|
if ((fp = fopen(RC_KRUNLEVEL, "r"))) {
|
||||||
memset(buffer, 0, sizeof (buffer));
|
memset(buffer, 0, sizeof (buffer));
|
||||||
if (fgets(buffer, sizeof (buffer), fp)) {
|
if (fgets(buffer, sizeof (buffer), fp)) {
|
||||||
l = strlen (buffer) - 1;
|
l = strlen (buffer) - 1;
|
||||||
|
33
src/rc/rc.c
33
src/rc/rc.c
@ -367,14 +367,14 @@ static bool set_ksoftlevel(const char *level)
|
|||||||
strcmp(level, RC_LEVEL_SINGLE) == 0 ||
|
strcmp(level, RC_LEVEL_SINGLE) == 0 ||
|
||||||
strcmp(level, RC_LEVEL_SYSINIT) == 0)
|
strcmp(level, RC_LEVEL_SYSINIT) == 0)
|
||||||
{
|
{
|
||||||
if (exists(RC_KSOFTLEVEL) &&
|
if (exists(RC_KRUNLEVEL) &&
|
||||||
unlink(RC_KSOFTLEVEL) != 0)
|
unlink(RC_KRUNLEVEL) != 0)
|
||||||
eerror("unlink `%s': %s", RC_KSOFTLEVEL, strerror(errno));
|
eerror("unlink `%s': %s", RC_KRUNLEVEL, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (fp = fopen(RC_KSOFTLEVEL, "w"))) {
|
if (! (fp = fopen(RC_KRUNLEVEL, "w"))) {
|
||||||
eerror("fopen `%s': %s", RC_KSOFTLEVEL, strerror(errno));
|
eerror("fopen `%s': %s", RC_KRUNLEVEL, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,11 +388,11 @@ static int get_ksoftlevel(char *buffer, int buffer_len)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (! exists(RC_KSOFTLEVEL))
|
if (! exists(RC_KRUNLEVEL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (! (fp = fopen(RC_KSOFTLEVEL, "r"))) {
|
if (! (fp = fopen(RC_KRUNLEVEL, "r"))) {
|
||||||
eerror("fopen `%s': %s", RC_KSOFTLEVEL, strerror(errno));
|
eerror("fopen `%s': %s", RC_KRUNLEVEL, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,7 +683,7 @@ static void do_newlevel(const char *newlevel)
|
|||||||
printf("Press %sI%s to enter interactive boot mode\n\n",
|
printf("Press %sI%s to enter interactive boot mode\n\n",
|
||||||
ecolor(ECOLOR_GOOD), ecolor(ECOLOR_NORMAL));
|
ecolor(ECOLOR_GOOD), ecolor(ECOLOR_NORMAL));
|
||||||
|
|
||||||
setenv("RC_SOFTLEVEL", newlevel, 1);
|
setenv("RC_RUNLEVEL", newlevel, 1);
|
||||||
rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, newlevel);
|
rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, newlevel);
|
||||||
hook_out = RC_HOOK_RUNLEVEL_START_OUT;
|
hook_out = RC_HOOK_RUNLEVEL_START_OUT;
|
||||||
run_script(INITSH);
|
run_script(INITSH);
|
||||||
@ -902,10 +902,12 @@ interactive_option:
|
|||||||
#define getoptstring "o:" getoptstring_COMMON
|
#define getoptstring "o:" getoptstring_COMMON
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
{ "override", 1, NULL, 'o' },
|
{ "override", 1, NULL, 'o' },
|
||||||
|
{ "service", 1, NULL, 's' },
|
||||||
longopts_COMMON
|
longopts_COMMON
|
||||||
};
|
};
|
||||||
static const char * const longopts_help[] = {
|
static const char * const longopts_help[] = {
|
||||||
"override the next runlevel to change into\nwhen leaving single user or boot runlevels",
|
"override the next runlevel to change into\nwhen leaving single user or boot runlevels",
|
||||||
|
"runs the service specified with the rest\nof the arguments",
|
||||||
longopts_help_COMMON
|
longopts_help_COMMON
|
||||||
};
|
};
|
||||||
#include "_usage.c"
|
#include "_usage.c"
|
||||||
@ -958,8 +960,7 @@ int main(int argc, char **argv)
|
|||||||
chdir("/");
|
chdir("/");
|
||||||
|
|
||||||
/* RUNLEVEL is set by sysvinit as is a magic number
|
/* RUNLEVEL is set by sysvinit as is a magic number
|
||||||
* RC_SOFTLEVEL is set by us and is the name for this magic number
|
* RC_RUNLEVEL is set by us and is the name for this magic number */
|
||||||
* even though all our userland documentation refers to runlevel */
|
|
||||||
RUNLEVEL = getenv("RUNLEVEL");
|
RUNLEVEL = getenv("RUNLEVEL");
|
||||||
PREVLEVEL = getenv("PREVLEVEL");
|
PREVLEVEL = getenv("PREVLEVEL");
|
||||||
|
|
||||||
@ -979,6 +980,16 @@ int main(int argc, char **argv)
|
|||||||
optarg = NULL;
|
optarg = NULL;
|
||||||
exit(set_ksoftlevel(optarg) ? EXIT_SUCCESS : EXIT_FAILURE);
|
exit(set_ksoftlevel(optarg) ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
case 's':
|
||||||
|
newlevel = rc_service_resolve(optarg);
|
||||||
|
if (!newlevel)
|
||||||
|
eerrorx("%s: service `%s' does not exist",
|
||||||
|
applet, optarg);
|
||||||
|
argv += optind - 1;
|
||||||
|
*argv = newlevel;
|
||||||
|
execv(*argv, argv);
|
||||||
|
eerrorx("%s: %s", applet, strerror(errno));
|
||||||
|
/* NOTREACHED */
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user