From: Jeremy Kerr Date: Tue, 13 Aug 2013 05:03:53 +0000 (+0800) Subject: lib/process: replace pb_run_cmd X-Git-Tag: v1.0.0~509 X-Git-Url: https://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=51c6aaf7864eb65779d548ee2549caa357f71e2c lib/process: replace pb_run_cmd This change replaces the pb_run_cmd() function with proper usage of the process API. Signed-off-by: Jeremy Kerr --- diff --git a/discover/boot.c b/discover/boot.c index d9c606f..8ad83be 100644 --- a/discover/boot.c +++ b/discover/boot.c @@ -77,7 +77,7 @@ static int kexec_load(struct boot_task *boot_task) *p++ = boot_task->local_image; /* 6 */ *p++ = NULL; /* 7 */ - result = pb_run_cmd(argv, 1, boot_task->dry_run); + result = process_run_simple_argv(boot_task, argv); if (result) pb_log("%s: failed: (%d)\n", __func__, result); @@ -91,31 +91,18 @@ static int kexec_load(struct boot_task *boot_task) * Must only be called after a successful call to kexec_load(). */ -static int kexec_reboot(bool dry_run) +static int kexec_reboot(struct boot_task *task) { - int result = 0; - const char *argv[4]; - const char **p; + int result; /* First try running shutdown. Init scripts should run 'exec -e' */ - - p = argv; - *p++ = pb_system_apps.shutdown; /* 1 */ - *p++ = "-r"; /* 2 */ - *p++ = "now"; /* 3 */ - *p++ = NULL; /* 4 */ - - result = pb_run_cmd(argv, 1, dry_run); + result = process_run_simple(task, pb_system_apps.shutdown, "-r", + "now", NULL); /* On error, force a kexec with the -e option */ - if (result) { - p = argv; - *p++ = pb_system_apps.kexec; /* 1 */ - *p++ = "-e"; /* 2 */ - *p++ = NULL; /* 3 */ - - result = pb_run_cmd(argv, 1, 0); + result = process_run_simple(task, pb_system_apps.kexec, + "-e", NULL); } if (result) @@ -123,13 +110,8 @@ static int kexec_reboot(bool dry_run) /* okay, kexec -e -f */ if (result) { - p = argv; - *p++ = pb_system_apps.kexec; /* 1 */ - *p++ = "-e"; /* 2 */ - *p++ = "-f"; /* 3 */ - *p++ = NULL; /* 4 */ - - result = pb_run_cmd(argv, 1, 0); + result = process_run_simple(task, pb_system_apps.kexec, + "-e", "-f", NULL); } if (result) @@ -395,7 +377,7 @@ no_load: update_status(status_fn, status_arg, BOOT_STATUS_INFO, "performing kexec reboot"); - result = kexec_reboot(boot_task->dry_run); + result = kexec_reboot(boot_task); if (result) { update_status(status_fn, status_arg, BOOT_STATUS_ERROR, diff --git a/discover/device-handler.c b/discover/device-handler.c index d14e54f..ccc7cc3 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "device-handler.h" @@ -207,7 +208,7 @@ void device_handler_add_device(struct device_handler *handler, static int mount_device(struct discover_device *dev) { - const char *argv[6]; + int rc; if (!dev->device_path) return -1; @@ -220,29 +221,20 @@ static int mount_device(struct discover_device *dev) pb_log("couldn't create mount directory %s: %s\n", dev->mount_path, strerror(errno)); - argv[0] = pb_system_apps.mount; - argv[1] = dev->device_path; - argv[2] = dev->mount_path; - argv[3] = "-o"; - argv[4] = "ro"; - argv[5] = NULL; - - if (pb_run_cmd(argv, 1, 0)) { + rc = process_run_simple(dev, pb_system_apps.mount, + dev->device_path, dev->mount_path, + "-o", "ro", NULL); - /* Retry mount without ro option. */ - - argv[0] = pb_system_apps.mount; - argv[1] = dev->device_path; - argv[2] = dev->mount_path; - argv[3] = NULL; + if (!rc) + return 0; - if (pb_run_cmd(argv, 1, 0)) - goto out_rmdir; - } + /* Retry mount without ro option. */ + rc = process_run_simple(dev, pb_system_apps.mount, + dev->device_path, dev->mount_path, NULL); - return 0; + if (!rc) + return 0; -out_rmdir: pb_rmdir_recursive(mount_base(), dev->mount_path); return -1; } @@ -250,28 +242,12 @@ out_rmdir: static int umount_device(struct discover_device *dev) { int status; - pid_t pid; if (!dev->mount_path) return 0; - pid = fork(); - if (pid == -1) { - pb_log("%s: fork failed: %s\n", __func__, strerror(errno)); - return -1; - } - - if (pid == 0) { - execl(pb_system_apps.umount, pb_system_apps.umount, - dev->mount_path, NULL); - exit(EXIT_FAILURE); - } - - if (waitpid(pid, &status, 0) == -1) { - pb_log("%s: waitpid failed: %s\n", __func__, - strerror(errno)); - return -1; - } + status = process_run_simple(dev, pb_system_apps.umount, + dev->mount_path, NULL); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) return -1; diff --git a/discover/network.c b/discover/network.c index 4b9e4f1..28e3a29 100644 --- a/discover/network.c +++ b/discover/network.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "file.h" @@ -45,6 +46,7 @@ struct interface { } state; struct list_item list; + struct process *udhcpc_process; }; struct network { @@ -136,22 +138,21 @@ static int network_send_link_query(struct network *network) return 0; } -static int interface_change(struct network *network, - struct interface *interface, - bool up) +static int interface_change(struct interface *interface, bool up) { - int rc; const char *statestr = up ? "up" : "down"; - const char *argv[] = { - pb_system_apps.ip, - "link", - "set", - interface->name, - statestr, - NULL, - }; + int rc; - rc = pb_run_cmd(argv, 1, network->dry_run); + if (!up && interface->udhcpc_process) { + /* we don't care about the callback from here */ + interface->udhcpc_process->exit_cb = NULL; + interface->udhcpc_process->data = NULL; + process_stop_async(interface->udhcpc_process); + process_release(interface->udhcpc_process); + } + + rc = process_run_simple(interface, pb_system_apps.ip, + "link", "set", interface->name, statestr, NULL); if (rc) { pb_log("failed to bring interface %s %s\n", interface->name, statestr); @@ -160,22 +161,30 @@ static int interface_change(struct network *network, return 0; } -static int interface_up(struct network *network, - struct interface *interface) +static int interface_up(struct interface *interface) { - return interface_change(network, interface, true); + return interface_change(interface, true); } -static int interface_down(struct network *network, - struct interface *interface) +static int interface_down(struct interface *interface) { - return interface_change(network, interface, false); + return interface_change(interface, false); } -static void configure_interface_dhcp(struct network *network, - struct interface *interface) +static void udhcpc_process_exit(struct process *process) { + struct interface *interface = process->data; + pb_log("udhcp client [pid %d] for interface %s exited, rc %d\n", + process->pid, interface->name, process->exit_status); + interface->udhcpc_process = NULL; + process_release(process); +} + +static void configure_interface_dhcp(struct interface *interface) +{ + struct process *process; char pidfile[256]; + int rc; const char *argv[] = { pb_system_apps.udhcpc, "-R", @@ -187,36 +196,33 @@ static void configure_interface_dhcp(struct network *network, snprintf(pidfile, sizeof(pidfile), "%s/udhcpc-%s.pid", PIDFILE_BASE, interface->name); - pb_run_cmd(argv, 0, network->dry_run); + process = process_create(interface); + + process->path = pb_system_apps.udhcpc; + process->argv = argv; + process->exit_cb = udhcpc_process_exit; + process->data = interface; + + rc = process_run_async(process); + + if (rc) + process_release(process); + else + interface->udhcpc_process = process; + return; } -static void configure_interface_static(struct network *network, - struct interface *interface, +static void configure_interface_static(struct interface *interface, const struct interface_config *config) { - const char *addr_argv[] = { - pb_system_apps.ip, - "address", - "add", - config->static_config.address, - "dev", - interface->name, - NULL, - }; - const char *route_argv[] = { - pb_system_apps.ip, - "route", - "add", - "default", - "via", - config->static_config.gateway, - NULL, - }; int rc; + rc = process_run_simple(interface, pb_system_apps.ip, + "address", "add", config->static_config.address, + "dev", interface->name, NULL); + - rc = pb_run_cmd(addr_argv, 1, network->dry_run); if (rc) { pb_log("failed to add address %s to interface %s\n", config->static_config.address, @@ -225,12 +231,15 @@ static void configure_interface_static(struct network *network, } /* we need the interface up before we can route through it */ - rc = interface_up(network, interface); + rc = interface_up(interface); if (rc) return; if (config->static_config.gateway) - rc = pb_run_cmd(route_argv, 1, network->dry_run); + rc = process_run_simple(interface, pb_system_apps.ip, + "route", "add", "default", + "via", config->static_config.gateway, + NULL); if (rc) { pb_log("failed to add default route %s on interface %s\n", @@ -262,7 +271,7 @@ static void configure_interface(struct network *network, /* always up the lookback, no other handling required */ if (!strcmp(interface->name, "lo")) { if (interface->state == IFSTATE_NEW) - interface_up(network, interface); + interface_up(interface); interface->state = IFSTATE_CONFIGURED; return; } @@ -286,7 +295,7 @@ static void configure_interface(struct network *network, /* new interface? bring up to the point so we can detect a link */ if (interface->state == IFSTATE_NEW) { if (!up) { - interface_up(network, interface); + interface_up(interface); pb_log("network: bringing up interface %s\n", interface->name); return; @@ -303,10 +312,10 @@ static void configure_interface(struct network *network, pb_log("network: configuring interface %s\n", interface->name); if (!config || config->method == CONFIG_METHOD_DHCP) { - configure_interface_dhcp(network, interface); + configure_interface_dhcp(interface); } else if (config->method == CONFIG_METHOD_STATIC) { - configure_interface_static(network, interface, config); + configure_interface_static(interface, config); } } @@ -497,7 +506,7 @@ int network_shutdown(struct network *network) waiter_remove(network->waiter); list_for_each_entry(&network->interfaces, interface, list) - interface_down(network, interface); + interface_down(interface); close(network->netlink_sd); talloc_free(network); diff --git a/discover/paths.c b/discover/paths.c index 26fb7cb..ce90cae 100644 --- a/discover/paths.c +++ b/discover/paths.c @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -56,11 +57,8 @@ static char *local_name(void *ctx) */ static char *load_nfs(void *ctx, struct pb_url *url) { + char *local, *opts; int result; - const char *argv[8]; - const char **p; - char *local; - char *opts; local = local_name(ctx); @@ -77,17 +75,8 @@ static char *load_nfs(void *ctx, struct pb_url *url) if (url->port) opts = talloc_asprintf_append(opts, ",port=%s", url->port); - p = argv; - *p++ = pb_system_apps.mount; /* 1 */ - *p++ = "-t"; /* 2 */ - *p++ = "nfs"; /* 3 */ - *p++ = opts; /* 4 */ - *p++ = url->host; /* 5 */ - *p++ = url->dir; /* 6 */ - *p++ = local; /* 7 */ - *p++ = NULL; /* 8 */ - - result = pb_run_cmd(argv, 1, 0); + result = process_run_simple(ctx, pb_system_apps.mount, "-t", "nfs", + opts, url->host, url->dir, local, NULL); talloc_free(opts); @@ -113,23 +102,18 @@ fail: */ static char *load_sftp(void *ctx, struct pb_url *url) { + char *host_path, *local; int result; - const char *argv[4]; - const char **p; - char *local; local = local_name(ctx); if (!local) return NULL; - p = argv; - *p++ = pb_system_apps.sftp; /* 1 */ - *p++ = talloc_asprintf(local, "%s:%s", url->host, url->path); /* 2 */ - *p++ = local; /* 3 */ - *p++ = NULL; /* 4 */ + host_path = talloc_asprintf(local, "%s:%s", url->host, url->path); - result = pb_run_cmd(argv, 1, 0); + result = process_run_simple(ctx, pb_system_apps.sftp, host_path, + local, NULL); if (result) goto fail; @@ -174,7 +158,7 @@ static char *load_tftp(void *ctx, struct pb_url *url) *p++ = url->port; /* 8 */ *p++ = NULL; /* 9 */ - result = pb_run_cmd(argv, 1, 0); + result = process_run_simple_argv(ctx, argv); if (!result) return local; @@ -194,7 +178,7 @@ static char *load_tftp(void *ctx, struct pb_url *url) *p++ = local; /* 9 */ *p++ = NULL; /* 10 */ - result = pb_run_cmd(argv, 1, 0); + result = process_run_simple_argv(ctx, argv); if (!result) return local; @@ -239,7 +223,7 @@ static char *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, 1, 0); + result = process_run_simple_argv(ctx, argv); if (result) goto fail; diff --git a/lib/system/system.c b/lib/system/system.c index ff4ae99..6e80b24 100644 --- a/lib/system/system.c +++ b/lib/system/system.c @@ -101,82 +101,3 @@ int pb_rmdir_recursive(const char *base, const char *dir) return 0; } - -/** - * pb_run_cmd - Run the supplied command. - * @cmd_argv: An argument list array for execv. - * @wait: Wait for the child process to complete before returning. - * @dry_run: Don't actually fork and exec. - */ -int pb_run_cmd(const char *const *cmd_argv, int wait, int dry_run) -{ -#if defined(DEBUG) - enum {do_debug = 1}; -#else - enum {do_debug = 0}; -#endif - int status; - pid_t pid; - - if (do_debug) { - const char *const *p = cmd_argv; - - pb_log("%s: %s", __func__, (dry_run ? "(dry-run) " : "")); - - while (*p) { - pb_log("%s ", *p); - p++; - } - pb_log("\n"); - } else - pb_log("%s: %s%s\n", __func__, (dry_run ? "(dry-run) " : ""), - cmd_argv[0]); - - if (dry_run) - return 0; - - pid = fork(); - - if (pid == -1) { - pb_log("%s: fork failed: %s\n", __func__, strerror(errno)); - return -1; - } - - - if (pid == 0) { - int log = fileno(pb_log_get_stream()); - - /* Redirect child output to log. */ - - status = dup2(log, STDOUT_FILENO); - assert(status != -1); - status = dup2(log, STDERR_FILENO); - assert(status != -1); - - execvp(cmd_argv[0], (char *const *)cmd_argv); - pb_log("%s: exec failed: %s\n", __func__, strerror(errno)); - 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)); - return -1; - } - - if (do_debug && WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) - pb_log("%s: signaled\n", __func__); - - if (!WIFEXITED(status)) { - pb_log("%s: %s failed\n", __func__, cmd_argv[0]); - return -1; - } - - if (WEXITSTATUS(status)) - pb_log("%s: WEXITSTATUS %d\n", __func__, WEXITSTATUS(status)); - - return WEXITSTATUS(status); -} diff --git a/ui/common/ui-system.c b/ui/common/ui-system.c index ad3bfba..9ab8dec 100644 --- a/ui/common/ui-system.c +++ b/ui/common/ui-system.c @@ -28,6 +28,7 @@ #include "log/log.h" #include +#include #include "talloc/talloc.h" #include "ui-system.h" @@ -35,22 +36,27 @@ * pb_start_daemon - start the pb-discover daemon. */ -int pb_start_daemon(void) +int pb_start_daemon(void *ctx) { + struct process *process; + const char **argv; int result; - const char *argv[2]; - char *name = talloc_asprintf(NULL, "%s/sbin/pb-discover", - pb_system_apps.prefix); + char *name; - argv[0] = name; - argv[1] = NULL; + process = process_create(ctx); + + argv = talloc_array(process, const char *, 2); + name = talloc_asprintf(process, "%s/sbin/pb-discover", + pb_system_apps.prefix); - result = pb_run_cmd(argv, 0, 0); + argv[0] = name; + argv[1] = NULL; - talloc_free(name); + process->path = name; + process->argv = argv; - if (result) - pb_log("%s: failed: (%d)\n", __func__, result); + result = process_run_async(process); + process_release(process); return result; } diff --git a/ui/common/ui-system.h b/ui/common/ui-system.h index 5ce501a..3b7d341 100644 --- a/ui/common/ui-system.h +++ b/ui/common/ui-system.h @@ -28,7 +28,7 @@ #include -int pb_start_daemon(void); +int pb_start_daemon(void *ctx); unsigned int pb_elf_hash(const char *str); unsigned int pb_cat_hash(const char *a, const char *b); diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index 0dc8d4b..b09f030 100644 --- a/ui/ncurses/nc-cui.c +++ b/ui/ncurses/nc-cui.c @@ -81,13 +81,13 @@ int cui_run_cmd(struct pmenu_item *item) { int result; struct cui *cui = cui_from_item(item); - const char *const *cmd_argv = item->data; + const char **cmd_argv = item->data; nc_scr_status_printf(cui->current, "Running %s...", cmd_argv[0]); def_prog_mode(); - result = pb_run_cmd(cmd_argv, 1, 0); + result = process_run_simple_argv(item, cmd_argv); reset_prog_mode(); redrawwin(cui->current->main_ncw); @@ -529,7 +529,7 @@ retry_start: start_deamon = 0; - result = pb_start_daemon(); + result = pb_start_daemon(cui); if (!result) goto retry_start; diff --git a/ui/twin/pbt-client.c b/ui/twin/pbt-client.c index 1de532d..20ce31a 100644 --- a/ui/twin/pbt-client.c +++ b/ui/twin/pbt-client.c @@ -298,7 +298,7 @@ retry_start: start_deamon = 0; - result = pb_start_daemon(); + result = pb_start_daemon(pbt_client); if (!result) goto retry_start;