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