Punt the dodgy ebuffer code. We now force prefixing for parallel starts which also reduces our variable pollution.

This commit is contained in:
Roy Marples 2007-07-11 12:06:37 +00:00
parent 35d860710a
commit 356c41f77c
9 changed files with 13 additions and 189 deletions

View File

@ -1,16 +1,11 @@
# /etc/conf.d/rc: Global config file for the Gentoo RC System
# Set to "yes" if you want the rc system to try and start services
# in parallel for a slight speed improvement.
# in parallel for a slight speed improvement. When running in parallel we
# prefix the service output with it's name as the output will get
# jumbled up.
RC_PARALLEL="no"
# If we're running in parallel then the output of each service is buffered
# until the service finishes. This is so the output one service is not mixed
# with the output of another service.
# To avoid buffering can prefix each line of output to see the service which
# it belongs to by setting the RC_PREFIX="yes".
RC_PREFIX="no"
# Set RC_INTERACTIVE to "yes" and you'll be able to press the I key during
# boot so you can choose to start specific services. Set to "no" to disable
# this feature.
@ -25,7 +20,6 @@ RC_VERBOSE="no"
# output.
RC_QUIET="no"
# Do we allow any started service in the runlevel to satisfy the depedency
# or do we want all of them regardless of state? For example, if net.eth0
# and net.eth0 are in the default runlevel then with RC_STRICT_DEPEND="no"

View File

@ -67,20 +67,20 @@ _wait_for_carrier() {
# Incase users don't want this nice feature ...
[ ${timeout} -le 0 ] && return 0
[ -n "${RC_EBUFFER}" -o "${RC_PREFIX}" = "yes" ] && efunc=einfo
[ "${RC_PARALLEL}" = "yes" ] && efunc=einfo
${efunc} "Waiting for carrier (${timeout} seconds) "
while [ ${timeout} -gt 0 ] ; do
sleep 1
if _has_carrier ; then
[ -z "${RC_EBUFFER}" ] && echo
[ "${efunc}" = "einfon" ] && echo
eend 0
return 0
fi
timeout=$((${timeout} - 1))
[ -z "${RC_EBUFFER}" -a "${RC_PREFIX}" != "yes" ] && printf "."
[ "${efunc}" = "einfon" ] && printf "."
done
[ -z "${RC_EBUFFER}" -a "${RC_PREFIX}" != "yes" ] && echo
[ "${efunc}" = "einfon" ] && echo
eend 1
return 1
}

View File

@ -41,7 +41,7 @@ SYS_WHITELIST = env_whitelist
TARGET = $(LIB_TARGETS) $(BIN_TARGETS) $(SBIN_TARGETS) $(PRIV_BIN_TARGETS)
RCLINKS = einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
eindent eoutdent eflush eval_ecolors \
eindent eoutdent eval_ecolors \
veinfo vewarn vebegin veend vewend veindent veoutdent \
service_starting service_inactive service_started \
service_stopping service_stopped \

View File

@ -67,12 +67,4 @@ void eoutdentv (void);
/* Pointer to a string that is always prefixed to einfo/ewarn/error */
void eprefix (const char *prefix);
/* Handy utils to buffer stdout and stderr so our output is always
* sane when forking around.
* Don't depend on these being here though as we may take a different
* approach at a later date. */
void ebuffer (const char *file);
void eflush (void);
void eclose (void);
#endif

View File

@ -32,8 +32,6 @@ hidden_proto(eendv)
hidden_proto(eerror)
hidden_proto(eerrorn)
hidden_proto(eerrorx)
hidden_proto(eflush)
hidden_proto(eclose)
hidden_proto(eindent)
hidden_proto(eindentv)
hidden_proto(einfo)
@ -64,8 +62,6 @@ hidden_proto(ewendv)
/* How wide can the indent go? */
#define INDENT_MAX 40
#define EBUFFER_LOCK RC_SVCDIR "ebuffer/.lock"
/* Default colours */
#define ECOLOR_GOOD "\033[32;01m"
#define ECOLOR_WARN "\033[33;01m"
@ -120,10 +116,6 @@ static const char *color_terms[] = {
NULL
};
/* We use this array to save the stdout/stderr fd's for buffering */
static int stdfd[2] = {-1, -1};
static FILE *ebfp = NULL;
static char ebfile[PATH_MAX] = { '\0' };
static const char *term = NULL;
static bool term_is_cons25 = false;
@ -201,126 +193,6 @@ void eprefix (const char *prefix) {
_eprefix = prefix;
}
void ebuffer (const char *file)
{
/* Don't ebuffer if we don't have a file or we already are */
if (! file || stdfd[0] >= 0 || ! isatty (fileno (stdout)))
return;
/* Save the current fd's */
stdfd[0] = dup (fileno (stdout));
stdfd[1] = dup (fileno (stderr));
if (! (ebfp = fopen (file, "w+"))) {
fprintf (stderr, "fopen `%s': %s\n", file, strerror (errno));
return;
}
snprintf (ebfile, sizeof (ebfile), "%s", file);
fflush (stdout);
fflush (stderr);
/* Now redirect stdout and stderr */
if ((dup2 (fileno (ebfp), fileno (stdout))) < 0)
fprintf (stderr, "dup2: %s", strerror (errno));
if ((dup2 (fileno (ebfp), fileno (stderr))) < 0)
fprintf (stderr, "dup2: %s", strerror (errno));
/* Store the filename in our environment so scripts can tell if we're
* buffering or not */
unsetenv ("RC_EBUFFER");
setenv ("RC_EBUFFER", file, 1);
return;
}
static void _eflush (bool reopen)
{
char buffer[RC_LINEBUFFER];
int serrno = errno;
/* eflush called from an init script? */
if (! ebfp) {
char *file = getenv ("RC_EBUFFER");
if (file)
ebfp = fopen (file, "a+");
}
if (! ebfp)
return;
fflush (stdout);
fflush (stderr);
/* Restore stdout and stderr now */
if (stdfd[0] >= 0) {
dup2 (stdfd[0], fileno (stdout));
dup2 (stdfd[1], fileno (stderr));
} else {
char *tty = getenv ("RC_TTY");
if (tty) {
freopen (tty, "w+", stdout);
dup2 (fileno (stdout), fileno (stderr));
}
}
/* Spin until we can lock the ebuffer */
while (true) {
struct timeval tv;
errno = 0;
if (mkfifo (EBUFFER_LOCK, 0700) == 0)
break;
if (errno != EEXIST)
eerror ("mkfifo `%s': %s\n", EBUFFER_LOCK, strerror (errno));
tv.tv_sec = 0;
tv.tv_usec = 20000;
select (0, NULL, NULL, NULL, &tv);
}
errno = serrno;
/* Dump the file to stdout */
memset (buffer, 0, RC_LINEBUFFER);
if (fseek (ebfp, (off_t) 0, SEEK_SET) < 0)
eerror ("fseek: %s", strerror (errno));
else {
while (fgets (buffer, RC_LINEBUFFER, ebfp))
printf ("%s", buffer);
}
fflush (stdout);
fflush (stderr);
if (unlink (EBUFFER_LOCK))
eerror ("unlink `%s': %s", EBUFFER_LOCK, strerror (errno));
if (reopen) {
ftruncate (fileno (ebfp), (off_t) 0);
fseek (ebfp, (off_t) 0, SEEK_SET);
dup2 (fileno (ebfp), fileno (stdout));
dup2 (fileno (ebfp), fileno (stderr));
} else {
stdfd[0] = -1;
stdfd[1] = -1;
fclose (ebfp);
ebfp = NULL;
unlink (ebfile);
ebfile[0] = '\0';
unsetenv ("RC_EBUFFER");
}
return;
}
void eflush () {
_eflush (true);
}
hidden_def(eflush)
void eclose () {
_eflush (false);
}
hidden_def(eclose)
static void elog (int level, const char *fmt, va_list ap)
{
char *e = getenv ("RC_ELOG");
@ -518,7 +390,6 @@ void ewarnx (const char *fmt, ...)
int retval;
va_list ap;
eclose ();
if (fmt && ! is_env ("RC_QUIET", "yes")) {
va_start (ap, fmt);
elog (LOG_WARNING, fmt, ap);
@ -544,7 +415,6 @@ int eerror (const char *fmt, ...)
va_end (ap);
retval += fprintf (stderr, "\n");
eflush ();
return (retval);
}
hidden_def(eerror)
@ -553,7 +423,6 @@ void eerrorx (const char *fmt, ...)
{
va_list ap;
eclose ();
if (fmt) {
va_start (ap, fmt);
elog (LOG_ERR, fmt, ap);

View File

@ -583,7 +583,6 @@ static const char *depdirs[] =
RC_SVCDIR "options",
RC_SVCDIR "exclusive",
RC_SVCDIR "scheduled",
RC_SVCDIR "ebuffer",
NULL
};

View File

@ -113,8 +113,6 @@ void rc_plugin_run (rc_hook_t hook, const char *value)
if (rc_in_plugin)
return;
eflush ();
while (plugin) {
if (plugin->hook) {
int i;
@ -186,8 +184,6 @@ void rc_plugin_run (rc_hook_t hook, const char *value)
}
plugin = plugin->next;
}
eflush ();
}
void rc_plugin_unload (void)

View File

@ -211,8 +211,6 @@ static int do_e (int argc, char **argv)
eindentv ();
else if (strcmp (applet, "veoutdent") == 0)
eoutdentv ();
else if (strcmp (applet, "eflush") == 0)
eflush ();
else {
eerror ("%s: unknown applet", applet);
retval = EXIT_FAILURE;

View File

@ -237,9 +237,6 @@ static void cleanup (void)
if (! rc_in_plugin && prefix_locked)
unlink (PREFIX_LOCK);
/* Flush our buffered output if any */
eclose ();
if (hook_out)
rc_plugin_run (hook_out, applet);
rc_plugin_unload ();
@ -317,7 +314,7 @@ static int write_prefix (int fd, const char *buffer, size_t bytes, bool *prefixe
ret += write (fd, ec, strlen (ec));
ret += write (fd, prefix, strlen (prefix));
ret += write (fd, ec_normal, strlen (ec_normal));
ret += write (fd, "|", 2);
ret += write (fd, "|", 1);
*prefixed = true;
}
@ -335,12 +332,8 @@ static bool svc_exec (const char *arg1, const char *arg2)
int stdout_pipes[2];
int stderr_pipes[2];
/* To ensure any output has hit our ebuffer */
fflush (stdout);
fflush (stderr);
/* Setup our pipes for prefixed output */
if (rc_is_env ("RC_PREFIX", "yes")) {
if (prefix) {
if (pipe (stdout_pipes))
eerror ("pipe: %s", strerror (errno));
if (pipe (stderr_pipes))
@ -356,7 +349,7 @@ static bool svc_exec (const char *arg1, const char *arg2)
if (service_pid == -1)
eerrorx ("%s: vfork: %s", service, strerror (errno));
if (service_pid == 0) {
if (rc_is_env ("RC_PREFIX", "yes")) {
if (prefix) {
int flags;
if (dup2 (stdout_pipes[1], fileno (stdout)) == -1)
@ -391,7 +384,7 @@ static bool svc_exec (const char *arg1, const char *arg2)
}
/* Prefix our piped output */
if (rc_is_env ("RC_PREFIX", "yes")) {
if (prefix) {
bool stdout_done = false;
bool stdout_prefix_shown = false;
bool stderr_done = false;
@ -958,9 +951,6 @@ static void svc_restart (bool deps)
if (! rc_service_state (service, rc_service_stopped)) {
get_started_services ();
svc_stop (deps);
/* Flush our buffered output if any */
eflush ();
}
svc_start (deps);
@ -1079,7 +1069,7 @@ int main (int argc, char **argv)
setenv ("RC_RUNSCRIPT_PID", pid, 1);
/* eprefix is kinda klunky, but it works for our purposes */
if (rc_is_env ("RC_PREFIX", "yes")) {
if (rc_is_env ("RC_PARALLEL", "yes")) {
int l = 0;
int ll;
@ -1100,17 +1090,6 @@ int main (int argc, char **argv)
eprefix (prefix);
}
/* If we're in parallel and we're not prefixing then we need the ebuffer */
if (rc_is_env ("RC_PARALLEL", "yes") && ! rc_is_env ("RC_PREFIX", "yes")) {
char ebname[PATH_MAX];
char *eb;
snprintf (ebname, sizeof (ebname), "%s.%s", applet, pid);
eb = rc_strcatpaths (RC_SVCDIR "ebuffer", ebname, (char *) NULL);
ebuffer (eb);
free (eb);
}
#ifdef __linux__
/* Ok, we are ready to go, so setup selinux if applicable */
setup_selinux (argc, argv);
@ -1265,9 +1244,6 @@ int main (int argc, char **argv)
} else
svc_exec (optarg, NULL);
/* Flush our buffered output if any */
eflush ();
/* We should ensure this list is empty after an action is done */
rc_strlist_free (restart_services);
restart_services = NULL;