summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--discover/boot.c38
-rw-r--r--discover/device-handler.c52
-rw-r--r--discover/network.c109
-rw-r--r--discover/paths.c38
-rw-r--r--lib/system/system.c79
-rw-r--r--ui/common/ui-system.c26
-rw-r--r--ui/common/ui-system.h2
-rw-r--r--ui/ncurses/nc-cui.c6
-rw-r--r--ui/twin/pbt-client.c2
9 files changed, 115 insertions, 237 deletions
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 <log/log.h>
#include <types/types.h>
#include <system/system.h>
+#include <process/process.h>
#include <url/url.h>
#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 <talloc/talloc.h>
#include <waiter/waiter.h>
#include <pb-config/pb-config.h>
+#include <process/process.h>
#include <system/system.h>
#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 <talloc/talloc.h>
#include <system/system.h>
+#include <process/process.h>
#include <url/url.h>
#include <log/log.h>
@@ -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 <system/system.h>
+#include <process/process.h>
#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 <signal.h>
-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;
OpenPOWER on IntegriCloud