Add --start-daemon option to ui programs
authorGeoff Levand <geoff@infradead.org>
Fri, 9 Mar 2012 04:48:21 +0000 (20:48 -0800)
committerGeoff Levand <geoff@infradead.org>
Fri, 9 Mar 2012 04:51:37 +0000 (20:51 -0800)
Add the option --start-daemon to automatically start
pb-discover if it is not already started.  For use
when running as a stand-alone app.

Signed-off-by: Geoff Levand <geoff@infradead.org>
17 files changed:
discover/device-handler.c
lib/Makefile.am
lib/system/system.c
lib/system/system.h
man/petitboot-nc.8
man/petitboot-twin.8
ui/common/loader.c
ui/common/ui-system.c
ui/common/ui-system.h
ui/ncurses/generic-main.c
ui/ncurses/nc-cui.c
ui/ncurses/nc-cui.h
ui/twin/main-generic.c
ui/twin/pbt-client.c
ui/twin/pbt-client.h
ui/twin/pbt-main.c
ui/twin/pbt-main.h

index 6457dce6b68c5acf39ff8b8e5525a25b7caf9612..28889144c8f0285c3f90b0e5dd4dc4650c6f0a6f 100644 (file)
@@ -201,10 +201,10 @@ static int mount_device(struct discover_context *ctx)
        argv[4] = "ro";
        argv[5] = NULL;
 
-       if (pb_run_cmd(argv))
+       if (pb_run_cmd(argv, 1))
                argv[3] = NULL; /* try without ro */
 
-       if (pb_run_cmd(argv))
+       if (pb_run_cmd(argv, 1))
                goto out_rmdir;
 
        setup_device_links(ctx);
index 7b3d50d09dab4b4ad070f111e55b273cb19904e1..6440fe4a4865ff04465e541653a29e414b5fa904 100644 (file)
@@ -12,7 +12,8 @@
 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 
-AM_CPPFLAGS = -I$(top_srcdir)/lib $(DEFAULT_CPPFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir)/lib $(DEFAULT_CPPFLAGS) \
+       -DPREFIX='"$(prefix)"'
 
 AM_CFLAGS = $(DEFAULT_CFLAGS)
 
index 7371445a876d0bdbd8e7ad2d7da49a5aa266e743..1b506d2edaf6b5e84f9ea4211e0cac1b189f3d31 100644 (file)
@@ -17,6 +17,7 @@
 #include "system.h"
 
 const struct pb_system_apps pb_system_apps = {
+       .prefix = PREFIX,
        .cp = "/bin/cp",
        .kexec = "/sbin/kexec",
        .mount = "/bin/mount",
@@ -104,7 +105,7 @@ int pb_rmdir_recursive(const char *base, const char *dir)
  * @cmd_argv: An argument list array for execv.
  */
 
-int pb_run_cmd(const char *const *cmd_argv)
+int pb_run_cmd(const char *const *cmd_argv, int wait)
 {
 #if defined(DEBUG)
        enum {do_debug = 1};
@@ -149,6 +150,9 @@ int pb_run_cmd(const char *const *cmd_argv)
                exit(EXIT_FAILURE);
        }
 
+       if (!wait && !waitpid(pid, &status, WNOHANG))
+               return 0;
+
        if (waitpid(pid, &status, 0) == -1) {
                pb_log("%s: waitpid failed: %s\n", __func__,
                                strerror(errno));
index 191830913b2e3831eaa6ec1e98b77227c027b19c..d39280d1bcb7d10f58bd92921a098907be8a08b4 100644 (file)
@@ -2,6 +2,7 @@
 #define _PB_LIB_SYSTEM_H
 
 struct pb_system_apps {
+       const char *prefix;
        const char *cp;
        const char *kexec;
        const char *mount;
@@ -14,7 +15,7 @@ struct pb_system_apps {
 
 extern const struct pb_system_apps pb_system_apps;
 
-int pb_run_cmd(const char *const *cmd_argv);
+int pb_run_cmd(const char *const *cmd_argv, int wait);
 int pb_mkdir_recursive(const char *dir);
 int pb_rmdir_recursive(const char *base, const char *dir);
 
index 313565599b8ce6b8143e88a0540a4cd272a33c4e..4c2bea43ba3b784a6798e1432543266db80f47fc 100644 (file)
@@ -26,6 +26,7 @@
 .Sh SYNOPSIS
 .\" ========
 .Nm
+.Op Fl d, -start-daemon
 .Op Fl h, -help
 .Op Fl l, -log Ar log-file
 .Op Fl V, -version
@@ -44,6 +45,11 @@ protocols.
 .\" =======
 .Bl -tag -width indent
 .\"
+.It Fl d, -start-daemon
+Start pb-discover, the petitboot dynamic device discovery daemon, if it has
+not been started.  This option is mainly useful when running petitboot as a
+stand-alone application.
+.\"
 .It Fl h, -help
 Print a help message.
 .\"
index eef9ff36115a82974d064c129a6bdc3484fdf54b..25e22d13e20316fa70fe53566173bb86cfe6fe84 100644 (file)
 .Sh SYNOPSIS
 .\" ========
 .Nm
+.Op Fl d, -start-daemon
 .Op Fl h, -help
 .Op Fl l, -log Ar log-file
 .Op Fl V, -version
-.Op Fl V, -version
 .Op Fl f, -fbdev
 .Op Fl x, -x11
 .\"
@@ -47,6 +47,11 @@ protocols.
 .\" =======
 .Bl -tag -width indent
 .\"
+.It Fl d, -start-daemon
+Start pb-discover, the petitboot dynamic device discovery daemon, if it has
+not been started.  This option is mainly useful when running petitboot as a
+stand-alone application.
+.\"
 .It Fl h, -help
 Print a help message.
 .\"
index 5c69533ff3cc821f96bbc313259bcb29d0cedf0f..009871d3109ee348f5704bd530bc0e4422903382 100644 (file)
@@ -94,7 +94,7 @@ static char *pb_load_nfs(void *ctx, struct pb_url *url)
        *p++ = local;                   /* 7 */
        *p++ = NULL;                    /* 8 */
 
-       result = pb_run_cmd(argv);
+       result = pb_run_cmd(argv, 1);
 
        talloc_free(opts);
 
@@ -138,7 +138,7 @@ static char *pb_load_sftp(void *ctx, struct pb_url __attribute__((unused)) *url)
        *p++ = local;                   /* 4 */
        *p++ = NULL;                    /* 5 */
 
-       result = pb_run_cmd(argv);
+       result = pb_run_cmd(argv, 1);
 
        if (result)
                goto fail;
@@ -183,7 +183,7 @@ static char *pb_load_tftp(void *ctx, struct pb_url *url)
                *p++ = url->port;       /* 8 */
        *p++ = NULL;                    /* 9 */
 
-       result = pb_run_cmd(argv);
+       result = pb_run_cmd(argv, 1);
 
        if (!result)
                return local;
@@ -203,7 +203,7 @@ static char *pb_load_tftp(void *ctx, struct pb_url *url)
        *p++ = local;                   /* 9 */
        *p++ = NULL;                    /* 10 */
 
-       result = pb_run_cmd(argv);
+       result = pb_run_cmd(argv, 1);
 
        if (!result)
                return local;
@@ -248,7 +248,7 @@ static char *pb_load_wget(void *ctx, struct pb_url *url, enum wget_flags flags)
                *p++ = "--no-check-certificate";        /* 6 */
        *p++ = NULL;                                    /* 7 */
 
-       result = pb_run_cmd(argv);
+       result = pb_run_cmd(argv, 1);
 
        if (result)
                goto fail;
index 0140f0e484eedfc2757795ebc2fe9abd4520ad95..8604848e4c5363c13686cae1897b5c10f02f6b6e 100644 (file)
 #include "loader.h"
 #include "ui-system.h"
 
+/**
+ * pb_start_daemon - start the pb-discover daemon.
+ */
+
+int pb_start_daemon(void)
+{
+       int result;
+       const char *argv[2];
+       char *name = talloc_asprintf(NULL, "%s/sbin/pb-discover",
+               pb_system_apps.prefix);
+
+       argv[0] = name;
+       argv[1] =  NULL;
+
+       result = pb_run_cmd(argv, 0);
+
+       talloc_free(name);
+
+       if (result)
+               pb_log("%s: failed: (%d)\n", __func__, result);
+
+       return result;
+}
+
 /**
  * kexec_load - kexec load helper.
  * @l_image: The local image file for kexec to execute.
@@ -67,7 +91,7 @@ static int kexec_load(const char *l_image, const char *l_initrd,
        *p++ = l_image;                 /* 5 */
        *p++ = NULL;                    /* 6 */
 
-       result = pb_run_cmd(argv);
+       result = pb_run_cmd(argv, 1);
 
        if (result)
                pb_log("%s: failed: (%d)\n", __func__, result);
@@ -98,7 +122,7 @@ static int kexec_reboot(void)
        *p++ =  "now";                  /* 3 */
        *p++ =  NULL;                   /* 4 */
 
-       result = pb_run_cmd(argv);
+       result = pb_run_cmd(argv, 1);
 
        /* On error, force a kexec with the -e option */
 
@@ -108,7 +132,7 @@ static int kexec_reboot(void)
                *p++ = "-e";                    /* 2 */
                *p++ = NULL;                    /* 3 */
 
-               result = pb_run_cmd(argv);
+               result = pb_run_cmd(argv, 1);
        }
 
        if (result)
index ca5edb4d8e60210ebfdee0d736de08641d159015..87ab89126f8b6494a1df0e5faaf4a1340124ab4e 100644 (file)
@@ -32,6 +32,7 @@ struct pb_kexec_data {
 };
 
 int pb_run_kexec(const struct pb_kexec_data *kd);
+int pb_start_daemon(void);
 
 unsigned int pb_elf_hash(const char *str);
 unsigned int pb_cat_hash(const char *a, const char *b);
index 2d342c3ecbd74c2a93630dacfeff588a0fc6fef5..6b8f5bacd92eb95c155727904d6bea5c7a910d8d 100644 (file)
@@ -45,7 +45,8 @@ static void print_usage(void)
 {
        print_version();
        printf(
-"Usage: petitboot-nc [-h, --help] [-l, --log log-file] [-V, --version]\n");
+"Usage: petitboot-nc [-d, --start-daemon] [-h, --help] [-l, --log log-file]\n"
+"                    [-V, --version]\n");
 }
 
 /**
@@ -59,6 +60,7 @@ enum opt_value {opt_undef = 0, opt_yes, opt_no};
  */
 
 struct opts {
+       enum opt_value start_daemon;
        enum opt_value show_help;
        const char *log_file;
        enum opt_value show_version;
@@ -71,12 +73,13 @@ struct opts {
 static int opts_parse(struct opts *opts, int argc, char *argv[])
 {
        static const struct option long_options[] = {
-               {"help",    no_argument,       NULL, 'h'},
-               {"log",     required_argument, NULL, 'l'},
-               {"version", no_argument,       NULL, 'V'},
-               { NULL,     0,                 NULL, 0},
+               {"start-daemon", no_argument,       NULL, 'd'},
+               {"help",         no_argument,       NULL, 'h'},
+               {"log",          required_argument, NULL, 'l'},
+               {"version",      no_argument,       NULL, 'V'},
+               { NULL,          0,                 NULL, 0},
        };
-       static const char short_options[] = "hl:V";
+       static const char short_options[] = "dhl:V";
        static const struct opts default_values = {
                .log_file = "/var/log/petitboot/petitboot-nc.log",
        };
@@ -91,6 +94,9 @@ static int opts_parse(struct opts *opts, int argc, char *argv[])
                        break;
 
                switch (c) {
+               case 'd':
+                       opts->start_daemon = opt_yes;
+                       break;
                case 'h':
                        opts->show_help = opt_yes;
                        break;
@@ -269,7 +275,7 @@ int main(int argc, char *argv[])
                return EXIT_FAILURE;
        }
 
-       pb.cui = cui_init(&pb, pb_kexec_cb, NULL);
+       pb.cui = cui_init(&pb, pb_kexec_cb, NULL, opts.start_daemon);
 
        if (!pb.cui)
                return EXIT_FAILURE;
index aed5ff7befdcbdec665b3cfea0f344ea00321e94..09e7a57fafe9454eb11cb24fa90fee11234718d1 100644 (file)
@@ -111,7 +111,7 @@ int cui_run_cmd(struct pmenu_item *item)
 
        def_prog_mode();
 
-       result = pb_run_cmd(cmd_argv);
+       result = pb_run_cmd(cmd_argv, 1);
 
        reset_prog_mode();
        redrawwin(cui->current->main_ncw);
@@ -534,7 +534,7 @@ static struct discover_client_ops cui_client_ops = {
 
 struct cui *cui_init(void* platform_info,
        int (*on_kexec)(struct cui *, struct cui_opt_data *),
-       int (*js_map)(const struct js_event *e))
+       int (*js_map)(const struct js_event *e), int start_deamon)
 {
        struct cui *cui;
        struct discover_client *client;
@@ -555,6 +555,7 @@ struct cui *cui_init(void* platform_info,
 
        /* Loop here for scripts that just started the server. */
 
+start_deamon:
        for (i = 10; i; i--) {
                client = discover_client_init(&cui_client_ops, cui);
                if (client)
@@ -563,6 +564,24 @@ struct cui *cui_init(void* platform_info,
                sleep(1);
        }
 
+       if (!client && start_deamon) {
+               int result;
+
+               start_deamon = 0;
+
+               result = pb_start_daemon();
+
+               if (!result)
+                       goto start_deamon;
+
+               pb_log("%s: discover_client_init failed.\n", __func__);
+               fprintf(stderr, "%s: error: discover_client_init failed.\n",
+                       __func__);
+               fprintf(stderr, "could not start pb-discover, the petitboot "
+                       "daemon.\n");
+               goto fail_client_init;
+       }
+
        if (!client) {
                pb_log("%s: discover_client_init failed.\n", __func__);
                fprintf(stderr, "%s: error: discover_client_init failed.\n",
index 94fef6b90bf489b3e0abe15b34f88b8e0be97f0a..a4ac2e885a4341b2674b3838a6a5abe80786e2ad 100644 (file)
@@ -62,7 +62,7 @@ struct cui {
 
 struct cui *cui_init(void* platform_info,
        int (*on_kexec)(struct cui *, struct cui_opt_data *),
-       int (*js_map)(const struct js_event *e));
+       int (*js_map)(const struct js_event *e), int start_deamon);
 struct nc_scr *cui_set_current(struct cui *cui, struct nc_scr *scr);
 int cui_run(struct cui *cui, struct pmenu *main, unsigned int default_item);
 int cui_ked_run(struct pmenu_item *item);
index 5020fa2f345ff8319a8805f07de400fc3b073379..53c32dda750b81a005f20621c7b87ec81de0f81f 100644 (file)
@@ -327,7 +327,8 @@ int main(int argc, char *argv[])
                return EXIT_FAILURE;
        }
 
-       client = pbt_client_init(opts.backend, 900, 300, kexec_cb);
+       client = pbt_client_init(opts.backend, 900, 300, kexec_cb,
+               opts.start_daemon);
 
        if (!client) {
                ui_result = EXIT_FAILURE;
index a2c3e931204bc639af070ea2d26b618b547bbd48..711248a61dec2da4870f835f0d24538948804f3e 100644 (file)
@@ -264,7 +264,8 @@ static void pbt_client_destructor(struct pbt_client *client)
 
 struct pbt_client *pbt_client_init(enum pbt_twin_backend backend, unsigned int width,
        unsigned int height,
-       int (*kexec_cb)(struct pbt_client *, struct pb_opt_data *))
+       int (*kexec_cb)(struct pbt_client *, struct pb_opt_data *),
+       int start_deamon)
 {
        struct pbt_client *pbt_client;
        unsigned int i;
@@ -289,17 +290,34 @@ struct pbt_client *pbt_client_init(enum pbt_twin_backend backend, unsigned int w
 
        /* Loop here for scripts that just started the server. */
 if (1) {
+start_deamon:
        for (i = 10; i; i--) {
                pbt_client->discover_client
                        = discover_client_init(&pbt_client_ops, pbt_client);
-
                if (pbt_client->discover_client)
                        break;
-
                pb_log("%s: waiting for server %d\n", __func__, i);
                sleep(1);
        }
 
+       if (!pbt_client->discover_client && start_deamon) {
+               int result;
+
+               start_deamon = 0;
+
+               result = pb_start_daemon();
+
+               if (!result)
+                       goto start_deamon;
+
+               pb_log("%s: discover_client_init failed.\n", __func__);
+               fprintf(stderr, "%s: error: discover_client_init failed.\n",
+                       __func__);
+               fprintf(stderr, "could not start pb-discover, the petitboot "
+                       "daemon.\n");
+               goto fail_client_init;
+       }
+
        if (!pbt_client->discover_client) {
                pb_log("%s: discover_client_init failed.\n", __func__);
                fprintf(stderr, "%s: error: discover_client_init failed.\n",
index 731bf03388a8f97ad8ee413416c80572b51367db..119bc9465065ab8cf2852574b7353c9ced8c4070 100644 (file)
@@ -52,7 +52,8 @@ struct pbt_client {
 
 struct pbt_client *pbt_client_init(enum pbt_twin_backend backend,
        unsigned int width, unsigned int height,
-       int (*kexec_cb)(struct pbt_client *, struct pb_opt_data *));
+       int (*kexec_cb)(struct pbt_client *, struct pb_opt_data *),
+       int start_deamon);
 void pbt_client_destroy(struct pbt_client *client);
 void pbt_client_resize(struct pbt_client *client);
 
index 51ff5f2cdf1f85118b9fc7f5559caf78991648cb..a8c1ea5fe2408acfceda14079087fc62e2373eda 100644 (file)
@@ -34,8 +34,8 @@ void pbt_print_usage(void)
 {
        pbt_print_version();
        printf(
-"Usage: petitboot-twin [-h, --help] [-l, --log log-file]\n"
-"                      [-r, --reset-defaults][-t, --timeout] [-V, --version]"
+"Usage: petitboot-twin [-d, --start-daemon] [-h, --help] [-l, --log log-file]\n"
+"                      [-r, --reset-defaults][-t, --timeout] [-V, --version]\n"
 "                      [[-f --fbdev] | [-x --x11]]\n");
 }
 
@@ -46,6 +46,7 @@ void pbt_print_usage(void)
 int pbt_opts_parse(struct pbt_opts *opts, int argc, char *argv[])
 {
        static const struct option long_options[] = {
+               {"start-daemon",   no_argument,       NULL, 'd'},
                {"fbdev",          no_argument,       NULL, 'f'},
                {"help",           no_argument,       NULL, 'h'},
                {"log",            required_argument, NULL, 'l'},
@@ -55,7 +56,7 @@ int pbt_opts_parse(struct pbt_opts *opts, int argc, char *argv[])
                {"x11",            no_argument,       NULL, 'x'},
                { NULL, 0, NULL, 0},
        };
-       static const char short_options[] = "fhl:trVx";
+       static const char short_options[] = "dfhl:trVx";
        static const struct pbt_opts default_values = {
                .backend = pbt_twin_x11,
                .log_file = "/var/log/petitboot/petitboot-twin.log",
@@ -71,6 +72,9 @@ int pbt_opts_parse(struct pbt_opts *opts, int argc, char *argv[])
                        break;
 
                switch (c) {
+               case 'd':
+                       opts->start_daemon = pbt_opt_yes;
+                       break;
                case 'f':
                        opts->backend = pbt_twin_fbdev;
                        break;
index 5f0e906466d795d880a3a2ba83c2da2d0a0e4335..47985a1002cebee672b665566260aa51f82572cb 100644 (file)
@@ -31,6 +31,7 @@ enum pbt_opt_value {pbt_opt_undef = 0, pbt_opt_yes, pbt_opt_no};
  */
 
 struct pbt_opts {
+       enum pbt_opt_value start_daemon;
        enum pbt_twin_backend backend;
        enum pbt_opt_value show_help;
        const char *log_file;