On Wed, Dec 12, 2012 at 07:14:20PM +0100, Michal Privoznik wrote: > On 11.12.2012 21:41, Daniel P. Berrange wrote: > > +static int > > +virLockDaemonForkIntoBackground(const char *argv0) > > +{ > > + int statuspipe[2]; > > + if (pipe(statuspipe) < 0) > > + return -1; > > + > > + pid_t pid = fork(); > > + switch (pid) { > > + case 0: > > + { > > + int stdinfd = -1; > > + int stdoutfd = -1; > > + int nextpid; > > + > > + VIR_FORCE_CLOSE(statuspipe[0]); > > + > > + if ((stdinfd = open("/dev/null", O_RDONLY)) < 0) > > + goto cleanup; > > + if ((stdoutfd = open("/dev/null", O_WRONLY)) < 0) > > + goto cleanup; > > + if (dup2(stdinfd, STDIN_FILENO) != STDIN_FILENO) > > + goto cleanup; > > + if (dup2(stdoutfd, STDOUT_FILENO) != STDOUT_FILENO) > > + goto cleanup; > > + if (dup2(stdoutfd, STDERR_FILENO) != STDERR_FILENO) > > + goto cleanup; > > + if (VIR_CLOSE(stdinfd) < 0) > > + goto cleanup; > > + if (VIR_CLOSE(stdoutfd) < 0) > > + goto cleanup; > > + > > + if (setsid() < 0) > > + goto cleanup; > > + > > + nextpid = fork(); > > + switch (nextpid) { > > + case 0: > > + return statuspipe[1]; > > + case -1: > > + return -1; > > + default: > > + _exit(0); > > + } > > + > > + cleanup: > > + VIR_FORCE_CLOSE(stdoutfd); > > + VIR_FORCE_CLOSE(stdinfd); > > + return -1; > > + > > + } > > + > > + case -1: > > + return -1; > > + > > + default: > > + { > > + int got, exitstatus = 0; > > + int ret; > > + char status; > > + > > + VIR_FORCE_CLOSE(statuspipe[1]); > > + > > + /* We wait to make sure the first child forked successfully */ > > + if ((got = waitpid(pid, &exitstatus, 0)) < 0 || > > + got != pid || > > + exitstatus != 0) { > > + return -1; > > + } > > + > > + /* Now block until the second child initializes successfully */ > > + again: > > + ret = read(statuspipe[0], &status, 1); > > + if (ret == -1 && errno == EINTR) > > + goto again; > > + > > + if (ret == 1 && status != 0) { > > + fprintf(stderr, > > + _("%s: error: %s. Check /var/log/messages or run without " > > + "--daemon for more info.\n"), argv0, > > + virDaemonErrTypeToString(status)); > > + } > > + _exit(ret == 1 && status == 0 ? 0 : 1); > > + } > > + } > > +} > > This is basically a copy-paste of daemonForkIntoBackground(). I wonder > if we can use (modified) version of it instead of this. Yep, it would be nice to share more code between the daemons in the future, but I didn't want to tackle that right now. > > +/* > > + * Set up the logging environment > > + * By default if daemonized all errors go to the logfile libvirtd.log, > > + * but if verbose or error debugging is asked for then also output > > + * informational and debug messages. Default size if 64 kB. > > + */ > > +static int > > +virLockDaemonSetupLogging(virLockDaemonConfigPtr config, > > + bool privileged, > > + bool verbose, > > + bool godaemon) > > +{ > > + virLogReset(); > > + > > + /* > > + * Libvirtd's order of precedence is: > > + * cmdline > environment > config > > + * > > + * In order to achieve this, we must process configuration in > > + * different order for the log level versus the filters and > > + * outputs. Because filters and outputs append, we have to look at > > + * the environment first and then only check the config file if > > + * there was no result from the environment. The default output is > > + * then applied only if there was no setting from either of the > > + * first two. Because we don't have a way to determine if the log > > + * level has been set, we must process variables in the opposite > > + * order, each one overriding the previous. > > + */ > > + if (config->log_level != 0) > > + virLogSetDefaultPriority(config->log_level); > > + > > + virLogSetFromEnv(); > > + > > + virLogSetBufferSize(config->log_buffer_size); > > + > > + if (virLogGetNbFilters() == 0) > > + virLogParseFilters(config->log_filters); > > + > > + if (virLogGetNbOutputs() == 0) > > + virLogParseOutputs(config->log_outputs); > > + > > + /* > > + * If no defined outputs, and either running > > + * as daemon or not on a tty, then first try > > + * to direct it to the systemd journal > > + * (if it exists).... > > + */ > > + if (virLogGetNbOutputs() == 0 && > > + (godaemon || !isatty(STDIN_FILENO))) { > > + char *tmp; > > + if (access("/run/systemd/journal/socket", W_OK) >= 0) { > > + if (virAsprintf(&tmp, "%d:journald", virLogGetDefaultPriority()) < 0) > > + goto no_memory; > > + virLogParseOutputs(tmp); > > + VIR_FREE(tmp); > > + } > > + } > > + > > + /* > > + * otherwise direct to libvirtd.log when running > > + * as daemon. Otherwise the default output is stderr. > > + */ > > + if (virLogGetNbOutputs() == 0) { > > + char *tmp = NULL; > > + > > + if (godaemon) { > > + if (privileged) { > > + if (virAsprintf(&tmp, "%d:file:%s/log/libvirt/virtlockd.log", > > + virLogGetDefaultPriority(), > > + LOCALSTATEDIR) == -1) > > + goto no_memory; > > + } else { > > + char *logdir = virGetUserCacheDirectory(); > > + mode_t old_umask; > > + > > + if (!logdir) > > + goto error; > > + > > + old_umask = umask(077); > > + if (virFileMakePath(logdir) < 0) { > > + umask(old_umask); > > + goto error; > > + } > > + umask(old_umask); > > + > > + if (virAsprintf(&tmp, "%d:file:%s/virtlockd.log", > > + virLogGetDefaultPriority(), logdir) == -1) { > > + VIR_FREE(logdir); > > + goto no_memory; > > + } > > + VIR_FREE(logdir); > > + } > > + } else { > > + if (virAsprintf(&tmp, "%d:stderr", virLogGetDefaultPriority()) < 0) > > + goto no_memory; > > + } > > + virLogParseOutputs(tmp); > > + VIR_FREE(tmp); > > + } > > + > > + /* > > + * Command line override for --verbose > > + */ > > + if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO)) > > + virLogSetDefaultPriority(VIR_LOG_INFO); > > + > > + return 0; > > + > > +no_memory: > > + virReportOOMError(); > > +error: > > + return -1; > > +} > > Same here. This one is even closer to daemonSetupLogging() Yep, as above. > > +#define MAX_LISTEN 5 > > +int main(int argc, char **argv) { > > + char *remote_config_file = NULL; > > + int statuswrite = -1; > > + int ret = 1; > > + int verbose = 0; > > + int godaemon = 0; > > + int timeout = 0; > > timeout seems dummy to me. Yep, it is not required. > ACK if you either remove it or (more likely) implement it. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list