From: Geoff Levand Date: Fri, 9 Mar 2012 04:48:21 +0000 (-0800) Subject: Add --start-daemon option to ui programs X-Git-Tag: v1.0.0~784 X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=604a1ccf072f9f33326fb6dc919c1b6233d40866;hp=ae0ba68f475ae5b057aad6538765bc8702134b9a Add --start-daemon option to ui programs 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 --- diff --git a/discover/device-handler.c b/discover/device-handler.c index 6457dce..2888914 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -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); diff --git a/lib/Makefile.am b/lib/Makefile.am index 7b3d50d..6440fe4 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -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) diff --git a/lib/system/system.c b/lib/system/system.c index 7371445..1b506d2 100644 --- a/lib/system/system.c +++ b/lib/system/system.c @@ -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)); diff --git a/lib/system/system.h b/lib/system/system.h index 1918309..d39280d 100644 --- a/lib/system/system.h +++ b/lib/system/system.h @@ -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); diff --git a/man/petitboot-nc.8 b/man/petitboot-nc.8 index 3135655..4c2bea4 100644 --- a/man/petitboot-nc.8 +++ b/man/petitboot-nc.8 @@ -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. .\" diff --git a/man/petitboot-twin.8 b/man/petitboot-twin.8 index eef9ff3..25e22d1 100644 --- a/man/petitboot-twin.8 +++ b/man/petitboot-twin.8 @@ -26,10 +26,10 @@ .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. .\" diff --git a/ui/common/loader.c b/ui/common/loader.c index 5c69533..009871d 100644 --- a/ui/common/loader.c +++ b/ui/common/loader.c @@ -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; diff --git a/ui/common/ui-system.c b/ui/common/ui-system.c index 0140f0e..8604848 100644 --- a/ui/common/ui-system.c +++ b/ui/common/ui-system.c @@ -32,6 +32,30 @@ #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) diff --git a/ui/common/ui-system.h b/ui/common/ui-system.h index ca5edb4..87ab891 100644 --- a/ui/common/ui-system.h +++ b/ui/common/ui-system.h @@ -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); diff --git a/ui/ncurses/generic-main.c b/ui/ncurses/generic-main.c index 2d342c3..6b8f5ba 100644 --- a/ui/ncurses/generic-main.c +++ b/ui/ncurses/generic-main.c @@ -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; diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index aed5ff7..09e7a57 100644 --- a/ui/ncurses/nc-cui.c +++ b/ui/ncurses/nc-cui.c @@ -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", diff --git a/ui/ncurses/nc-cui.h b/ui/ncurses/nc-cui.h index 94fef6b..a4ac2e8 100644 --- a/ui/ncurses/nc-cui.h +++ b/ui/ncurses/nc-cui.h @@ -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); diff --git a/ui/twin/main-generic.c b/ui/twin/main-generic.c index 5020fa2..53c32dd 100644 --- a/ui/twin/main-generic.c +++ b/ui/twin/main-generic.c @@ -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; diff --git a/ui/twin/pbt-client.c b/ui/twin/pbt-client.c index a2c3e93..711248a 100644 --- a/ui/twin/pbt-client.c +++ b/ui/twin/pbt-client.c @@ -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", diff --git a/ui/twin/pbt-client.h b/ui/twin/pbt-client.h index 731bf03..119bc94 100644 --- a/ui/twin/pbt-client.h +++ b/ui/twin/pbt-client.h @@ -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); diff --git a/ui/twin/pbt-main.c b/ui/twin/pbt-main.c index 51ff5f2..a8c1ea5 100644 --- a/ui/twin/pbt-main.c +++ b/ui/twin/pbt-main.c @@ -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; diff --git a/ui/twin/pbt-main.h b/ui/twin/pbt-main.h index 5f0e906..47985a1 100644 --- a/ui/twin/pbt-main.h +++ b/ui/twin/pbt-main.h @@ -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;