Looks good,

Ethan

On Fri, Jan 27, 2012 at 12:50, Ben Pfaff <b...@nicira.com> wrote:
> This eliminates a kluge that was duplicated in three different daemons.
>
> Signed-off-by: Ben Pfaff <b...@nicira.com>
> ---
>  lib/daemon.c          |   36 ++++++++++++++++++++++++++++++------
>  lib/daemon.h          |    3 ++-
>  ovsdb/ovsdb-client.c  |    8 ++------
>  tests/test-netflow.c  |   11 ++---------
>  utilities/ovs-ofctl.c |   10 ++--------
>  5 files changed, 38 insertions(+), 30 deletions(-)
>
> diff --git a/lib/daemon.c b/lib/daemon.c
> index 3dd5a1a..8ef5491 100644
> --- a/lib/daemon.c
> +++ b/lib/daemon.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
> + * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
> @@ -16,6 +16,7 @@
>
>  #include <config.h>
>  #include "daemon.h"
> +#include <assert.h>
>  #include <errno.h>
>  #include <fcntl.h>
>  #include <signal.h>
> @@ -61,6 +62,10 @@ static int daemonize_fd = -1;
>  * it dies due to an error signal? */
>  static bool monitor;
>
> +/* For each of the standard file descriptors, whether to replace it by
> + * /dev/null (if false) or keep it for the daemon to use (if true). */
> +static bool save_fds[3];
> +
>  static void check_already_running(void);
>  static int lock_pidfile(FILE *, int command);
>
> @@ -142,6 +147,20 @@ daemon_set_monitor(void)
>     monitor = true;
>  }
>
> +/* A daemon doesn't normally have any use for the file descriptors for stdin,
> + * stdout, and stderr after it detaches.  To keep these file descriptors from
> + * e.g. holding an SSH session open, by default detaching replaces each of
> + * these file descriptors by /dev/null.  But a few daemons expect the user to
> + * redirect stdout or stderr to a file, in which case it is desirable to keep
> + * these file descriptors.  This function, therefore, disables replacing 'fd'
> + * by /dev/null when the daemon detaches. */
> +void
> +daemon_save_fd(int fd)
> +{
> +    assert(fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO);
> +    save_fds[fd] = true;
> +}
> +
>  /* If a pidfile has been configured, creates it and stores the running
>  * process's pid in it.  Ensures that the pidfile will be deleted when the
>  * process exits. */
> @@ -402,16 +421,21 @@ monitor_daemon(pid_t daemon_pid)
>     program_name = saved_program_name;
>  }
>
> -/* Close stdin, stdout, stderr.  If we're started from e.g. an SSH session,
> - * then this keeps us from holding that session open artificially. */
> +/* Close standard file descriptors (except any that the client has requested 
> we
> + * leave open by calling daemon_save_fd()).  If we're started from e.g. an 
> SSH
> + * session, then this keeps us from holding that session open artificially. 
> */
>  static void
>  close_standard_fds(void)
>  {
>     int null_fd = get_null_fd();
>     if (null_fd >= 0) {
> -        dup2(null_fd, STDIN_FILENO);
> -        dup2(null_fd, STDOUT_FILENO);
> -        dup2(null_fd, STDERR_FILENO);
> +        int fd;
> +
> +        for (fd = 0; fd < 3; fd++) {
> +            if (!save_fds[fd]) {
> +                dup2(null_fd, fd);
> +            }
> +        }
>     }
>
>     /* Disable logging to stderr to avoid wasting CPU time. */
> diff --git a/lib/daemon.h b/lib/daemon.h
> index eb38d5d..1b4f988 100644
> --- a/lib/daemon.h
> +++ b/lib/daemon.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
> + * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
> @@ -64,6 +64,7 @@ bool is_chdir_enabled(void);
>  void set_detach(void);
>  bool get_detach(void);
>  void daemon_set_monitor(void);
> +void daemon_save_fd(int fd);
>  void daemonize(void);
>  void daemonize_start(void);
>  void daemonize_complete(void);
> diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c
> index d2a9de1..03dd6c0 100644
> --- a/ovsdb/ovsdb-client.c
> +++ b/ovsdb/ovsdb-client.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2009, 2010, 2011 Nicira Networks.
> + * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
> @@ -722,12 +722,8 @@ do_monitor(struct jsonrpc *rpc, const char *database,
>             monitor_print(msg->result, table, &columns, true);
>             fflush(stdout);
>             if (get_detach()) {
> -                /* daemonize() closes the standard file descriptors.  We 
> output
> -                 * to stdout, so we need to save and restore STDOUT_FILENO. 
> */
> -                int fd = dup(STDOUT_FILENO);
> +                daemon_save_fd(STDOUT_FILENO);
>                 daemonize();
> -                dup2(fd, STDOUT_FILENO);
> -                close(fd);
>             }
>         } else if (msg->type == JSONRPC_NOTIFY
>                    && !strcmp(msg->method, "update")) {
> diff --git a/tests/test-netflow.c b/tests/test-netflow.c
> index 5a88ada..b85c663 100644
> --- a/tests/test-netflow.c
> +++ b/tests/test-netflow.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2011 Nicira Networks.
> + * Copyright (c) 2011, 2012 Nicira Networks.
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
> @@ -190,7 +190,6 @@ main(int argc, char *argv[])
>     bool exiting = false;
>     int error;
>     int sock;
> -    int fd;
>     int n;
>
>     proctitle_init(argc, argv);
> @@ -208,10 +207,7 @@ main(int argc, char *argv[])
>         ovs_fatal(0, "%s: failed to open (%s)", argv[1], strerror(-sock));
>     }
>
> -    /* Daemonization will close stdout but we really want to keep it, so 
> make a
> -     * copy. */
> -    fd = dup(STDOUT_FILENO);
> -
> +    daemon_save_fd(STDOUT_FILENO);
>     daemonize_start();
>
>     error = unixctl_server_create(NULL, &server);
> @@ -222,9 +218,6 @@ main(int argc, char *argv[])
>
>     daemonize_complete();
>
> -    /* Now get stdout back. */
> -    dup2(fd, STDOUT_FILENO);
> -
>     ofpbuf_init(&buf, MAX_RECV);
>     n = 0;
>     for (;;) {
> diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
> index 3d3a7b7..d14575e 100644
> --- a/utilities/ovs-ofctl.c
> +++ b/utilities/ovs-ofctl.c
> @@ -828,12 +828,9 @@ monitor_vconn(struct vconn *vconn)
>  {
>     struct unixctl_server *server;
>     bool exiting = false;
> -    int error, fd;
> -
> -    /* Daemonization will close stderr but we really want to keep it, so 
> make a
> -     * copy. */
> -    fd = dup(STDERR_FILENO);
> +    int error;
>
> +    daemon_save_fd(STDERR_FILENO);
>     daemonize_start();
>     error = unixctl_server_create(NULL, &server);
>     if (error) {
> @@ -842,9 +839,6 @@ monitor_vconn(struct vconn *vconn)
>     unixctl_command_register("exit", "", 0, 0, ofctl_exit, &exiting);
>     daemonize_complete();
>
> -    /* Now get stderr back. */
> -    dup2(fd, STDERR_FILENO);
> -
>     for (;;) {
>         struct ofpbuf *b;
>         int retval;
> --
> 1.7.2.5
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to