[PATCH] rtas_errd: Add support for hotplugging qemu pci devices via RTAS event
Tyrel Datwyler <[email protected]> Thu, 20 Feb 2014 15:44:12 -0800
| Newsgroups | gmane.linux.tools.diag.devel |
|---|---|
| Message-ID | <[email protected]> |
QEMU uses the newly defined hotplug event in librtasevent to initiate hotplug of virtio pci devices in a pseries guest. This patch catches hotplug events and invokes the drmgr commad with the necessary parameters to fufill the hotplug request. Current support is limited to pci devices identified by a drc-index. Signed-off-by: Tyrel Datwyler <[email protected]> --- rtas_errd/Makefile | 2 +- rtas_errd/hotplug.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++ rtas_errd/rtas_errd.c | 5 +++ rtas_errd/rtas_errd.h | 3 ++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 rtas_errd/hotplug.c diff --git a/rtas_errd/Makefile b/rtas_errd/Makefile index d5427d5..d2a366f 100644 --- a/rtas_errd/Makefile +++ b/rtas_errd/Makefile @@ -10,7 +10,7 @@ PRRN_HOTPLUG = prrn_hotplug RTAS_ERRD_OBJS = rtas_errd.o epow.o dump.o guard.o eeh.o update.o \ files.o config.o diag_support.o ela.o v6ela.o servicelog.o \ - signal.o prrn.o + signal.o prrn.o hotplug.o RTAS_ERRD_LIBS = -lrtas -lrtasevent -lservicelog -lsqlite3 diff --git a/rtas_errd/hotplug.c b/rtas_errd/hotplug.c new file mode 100644 index 0000000..298d1a4 --- /dev/null +++ b/rtas_errd/hotplug.c @@ -0,0 +1,99 @@ +/** + * @file hotplug.c + * + * Copyright (C) 2013 IBM Corporation + */ + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/wait.h> + +#include <librtas.h> +#include "rtas_errd.h" + +#define DRMGR_PROGRAM "/usr/sbin/drmgr" +#define DRMGR_PROGRAM_NOPATH "drmgr" + +void handle_hotplug_event(struct event *re) +{ + struct rtas_event_hdr *rtas_hdr = re->rtas_hdr; + struct rtas_hotplug_scn *hotplug; + pid_t child; + int status, rc; + char drc_index[11]; + char *drmgr_args[] = { DRMGR_PROGRAM_NOPATH, "-c", NULL, NULL, NULL, + NULL, NULL, "-d4", "-V", NULL}; + + /* Retrieve Hotplug section */ + if (rtas_hdr->version >= 6) { + hotplug = rtas_get_hotplug_scn(re->rtas_event); + + /* Build drmgr argument list */ + dbg("Build drmgr command\n"); + + switch (hotplug->type) { + case RTAS_HP_TYPE_PCI: + drmgr_args[2] = "pci"; + drmgr_args[6] = "-n"; + break; + default: + dbg("Unknown or unsupported hotplug type %d\n", + hotplug->type); + return; + } + + switch (hotplug->action) { + case RTAS_HP_ACTION_ADD: + drmgr_args[3] = "-a"; + break; + case RTAS_HP_ACTION_REMOVE: + drmgr_args[3] = "-r"; + break; + default: + dbg("Unknown hotplug action %d\n", hotplug->action); + return; + } + + switch (hotplug->identifier) { + case RTAS_HP_ID_DRC_INDEX: + drmgr_args[4] = "-s"; + snprintf(drc_index, 11, "%#x", hotplug->u1.drc_index); + drmgr_args[5] = drc_index; + break; + default: + dbg("Unknown or unsupported hotplug identifier %d\n", + hotplug->identifier); + return; + } + + + dbg("run: %s %s %s %s %s %s %s\n", drmgr_args[0], + drmgr_args[1], drmgr_args[2], drmgr_args[3], + drmgr_args[4], drmgr_args[5], drmgr_args[6]); + + /* invoke drmgr */ + dbg("Invoke drmgr command\n"); + + child = fork(); + if (child == -1) { + log_msg(NULL, "%s cannot be run to handle a hotplug event, %s", + DRMGR_PROGRAM, strerror(errno)); + return; + } else if (child == 0) { + /* child process */ + rc = execv(DRMGR_PROGRAM, drmgr_args); + + /* shouldn't get here */ + log_msg(NULL, "Couldn not exec %s in response to hotplug event, %s", + DRMGR_PROGRAM, strerror(errno)); + exit(1); + } + + child = waitpid(child, &status, 0); + + dbg("drmgr call exited with %d\n", WEXITSTATUS(status)); + } +} diff --git a/rtas_errd/rtas_errd.c b/rtas_errd/rtas_errd.c index c911641..e94d1a8 100644 --- a/rtas_errd/rtas_errd.c +++ b/rtas_errd/rtas_errd.c @@ -160,6 +160,11 @@ handle_rtas_event(struct event *event) */ return 0; + case RTAS_HDR_TYPE_HOTPLUG: + dbg("Entering Hotplug handler"); + handle_hotplug_event(event); + break; + default: /* Nothing to do for this event */ break; diff --git a/rtas_errd/rtas_errd.h b/rtas_errd/rtas_errd.h index c59255d..f7b2e8e 100644 --- a/rtas_errd/rtas_errd.h +++ b/rtas_errd/rtas_errd.h @@ -169,4 +169,7 @@ void setup_sigchld_handler(void); /* prrn.c */ void handle_prrn_event(struct event *); +/* hotplug.c */ +void handle_hotplug_event(struct event *); + #endif /* _RTAS_ERRD_H */ -- 1.7.12.2 ------------------------------------------------------------------------------ Managing the Performance of Cloud-Based Applications Take advantage of what the Cloud has to offer - Avoid Common Pitfalls. Read the Whitepaper. http://pubads.g.doubleclick.net/gampad/clk?id=121054471&iu=/4140/ostg.clktrk