Re: [PATCH] rtas_errd: Add support for hotplugging qemu pci devices via RTAS event
Nathan Fontenot <[email protected]> Fri, 21 Feb 2014 10:28:16 -0600
| Newsgroups | gmane.linux.tools.diag.devel |
|---|---|
| Message-ID | <[email protected]> |
On 02/20/2014 05:44 PM, Tyrel Datwyler wrote: > 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]> Acked-by: Nathan Fontenot <[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 */ > ------------------------------------------------------------------------------ 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