qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC PATCH v2 2/7] Add plugin support


From: Alex Bennée
Subject: Re: [Qemu-devel] [RFC PATCH v2 2/7] Add plugin support
Date: Fri, 07 Sep 2018 15:14:15 +0100
User-agent: mu4e 1.1.0; emacs 26.1.50

Pavel Dovgalyuk <address@hidden> writes:

> This patch adds support for dynamically loaded plugins.
> Every plugin is a dynamic library with a set of optional exported
> functions that will be called from QEMU.
>
<snip>
> +
> +static QLIST_HEAD(, QemuPluginInfo) qemu_plugins
> +                                = QLIST_HEAD_INITIALIZER(qemu_plugins);
> +
> +static QemuOptsList qemu_plugin_opts = {
> +    .name = "plugin",
> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_plugin_opts.head),
> +    .desc = {
> +        {
> +            .name = "file",
> +            .type = QEMU_OPT_STRING,
> +        },{
> +            .name = "args",
> +            .type = QEMU_OPT_STRING,
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
> +void qemu_plugin_parse_cmd_args(const char *optarg)
> +{
> +    QemuOpts *opts = qemu_opts_parse_noisily(&qemu_plugin_opts, optarg, 
> false);
> +    qemu_plugin_load(qemu_opt_get(opts, "file"),
> +        qemu_opt_get(opts, "args"));
> +}

Currently this is only available to system mode emulation. Can it be
extended to include linux-user as well?

> +
> +void qemu_plugin_load(const char *filename, const char *args)
> +{
> +    GModule *g_module;
> +    QemuPluginInfo *info = NULL;
> +    if (!filename) {
> +        error_report("plugin name was not specified");
> +        return;
> +    }
> +    g_module = g_module_open(filename,
> +        G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
> +    if (!g_module) {
> +        error_report("can't load plugin '%s'", filename);
> +        return;
> +    }
> +    info = g_new0(QemuPluginInfo, 1);
> +    info->filename = g_strdup(filename);
> +    info->g_module = g_module;
> +    if (args) {
> +        info->args = g_strdup(args);
> +    }
> +
> +    g_module_symbol(g_module, "plugin_init", (gpointer*)&info->init);
> +
> +    /* Get the instrumentation callbacks */
> +    g_module_symbol(g_module, "plugin_needs_before_insn",
> +        (gpointer*)&info->needs_before_insn);
> +    g_module_symbol(g_module, "plugin_before_insn",
> +        (gpointer*)&info->before_insn);
> +
> +    QLIST_INSERT_HEAD(&qemu_plugins, info, next);
> +
> +    return;
> +}
> +
> +void qemu_plugins_init(void)
> +{
> +    QemuPluginInfo *info;
> +    QLIST_FOREACH(info, &qemu_plugins, next) {
> +        if (info->init) {
> +            info->init(info->args);
> +        }
> +    }
> +}
> diff --git a/qemu-options.hx b/qemu-options.hx
> index c0d3951..d171544 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -3950,6 +3950,16 @@ Dump json-encoded vmstate information for current 
> machine type to file
>  in @var{file}
>  ETEXI
>
> +#ifdef CONFIG_PLUGINS
> +DEF("plugin", HAS_ARG, QEMU_OPTION_plugin, \
> +           "-plugin file=<file>[,args=<args>] load <dso> plugin with 
> <args>\n", QEMU_ARCH_ALL)
> +STEXI
> address@hidden -plugin address@hidden,address@hidden
> address@hidden -plugin
> +Load @var{file} plugin passing @var{args} arguments.
> +ETEXI
> +#endif
> +
>  STEXI
>  @end table
>  ETEXI
> diff --git a/vl.c b/vl.c
> index 0603171..05420bf 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -129,6 +129,7 @@ int main(int argc, char **argv)
>  #include "qapi/qapi-commands-run-state.h"
>  #include "qapi/qmp/qerror.h"
>  #include "sysemu/iothread.h"
> +#include "qemu/plugins.h"
>
>  #define MAX_VIRTIO_CONSOLES 1
>
> @@ -3925,6 +3926,11 @@ int main(int argc, char **argv, char **envp)
>                      exit(1);
>                  }
>                  break;
> +#ifdef CONFIG_PLUGINS
> +            case QEMU_OPTION_plugin:
> +                qemu_plugin_parse_cmd_args(optarg);
> +                break;
> +#endif
>              case QEMU_OPTION_nodefconfig:
>              case QEMU_OPTION_nouserconfig:
>                  /* Nothing to be parsed here. Especially, do not error out 
> below. */
> @@ -4470,6 +4476,8 @@ int main(int argc, char **argv, char **envp)
>      }
>      parse_numa_opts(current_machine);
>
> +    qemu_plugins_init();
> +
>      /* do monitor/qmp handling at preconfig state if requested */
>      main_loop();
>


--
Alex Bennée



reply via email to

[Prev in Thread] Current Thread [Next in Thread]