|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [livepatch: independ. modules v2 2/3] livepatch: Allow to override inter-modules buildid dependency
> On 20. Aug 2019, at 15:35, Julien Grall <julien.grall@xxxxxxx> wrote:
>
> Hi,
>
> Something looks fishy in the threading:
>
> - The patch #1 is answered in reply-to the patch #1 of version 1.
> - This patch (#2) is answered in reply-to the patch #2 of version 1.
> - The patch #3 is labeled as v3 an in reply-to the patch #3 of version 1.
>
> If you send them as series, then they should be sent together for a new
> version and in a new thread. Not mangled to the previous thread as this makes
> quite difficult to follow what's going on.
>
> Also it looks like the series is still lacking of the cover letter. So I
> still have no clue what "livepatch: independ. modules" in your [...] refers
> to.
>
Yeah, since I got feedback and reviews on various patches that I have already
submitted the way I did,
I simply continue with what I have until all comments are addressed (I do not
want to lose anything).
Then, I will re-send the patches in 2 series: livepatch-build-tools and xen
with all changes,
Reviewed-by/Acked-by and cover letters. This is the way recommended by Andrew.
Unfortunately, it will be also quite confusing I think, because various changes
belonging to different topics,
are distributed between those 2 distinct repos.
Best,
Pawel
> Cheers,
>
> On 20/08/2019 14:28, Pawel Wieczorkiewicz wrote:
>> By default Livepatch enforces the following buildid-based dependency
>> chain between hotpatch modules:
>> 1) first module depends on given hypervisor buildid
>> 2) every consecutive module depends on previous module's buildid
>> This way proper hotpatch stack order is maintained and enforced.
>> While it is important for production hotpatches it limits agility and
>> blocks usage of testing or debug hotpatches. These kinds of hotpatch
>> modules are typically expected to be loaded at any time irrespective
>> of current state of the modules stack.
>> To enable testing and debug hotpatches allow user dynamically ignore
>> the inter-modules dependency. In this case only hypervisor buildid
>> match is verified and enforced.
>> To allow userland pass additional paremeters for livepatch actions
>> add support for action flags.
>> Each of the apply, revert, unload and revert action gets additional
>> 64-bit parameter 'flags' where extra flags can be applied in a mask
>> form.
>> Initially only one flag '--nodeps' is added for the apply action.
>> This flag modifies the default buildid dependency check as described
>> above.
>> The global sysctl interface input flag parameter is defined with a
>> single corresponding flag macro:
>> LIVEPATCH_ACTION_APPLY_NODEPS (1 << 0)
>> The userland xen-livepatch tool is modified to support the '--nodeps'
>> flag for apply and load commands. A general mechanism for specifying
>> more flags in the future for apply and other action is however added.
>> Signed-off-by: Pawel Wieczorkiewicz <wipawel@xxxxxxxxx>
>> Reviewed-by: Andra-Irina Paraschiv <andraprs@xxxxxxxxxx>
>> Reviewed-by: Eslam Elnikety <elnikety@xxxxxxxxx>
>> Reviewed-by: Petre Eftime <epetre@xxxxxxxxxx>
>> Reviewed-by: Leonard Foerster <foersleo@xxxxxxxxx>
>> Reviewed-by: Martin Pohlack <mpohlack@xxxxxxxxx>
>> Reviewed-by: Norbert Manthey <nmanthey@xxxxxxxxx>
>> ---
>> v2:
>> * Bump XEN_SYSCTL_INTERFACE_VERSION to 0x00000013
>> ---
>> tools/libxc/include/xenctrl.h | 9 ++--
>> tools/libxc/xc_misc.c | 20 +++----
>> tools/misc/xen-livepatch.c | 121
>> +++++++++++++++++++++++++++++++++++-------
>> xen/common/livepatch.c | 14 +++--
>> xen/include/public/sysctl.h | 11 +++-
>> 5 files changed, 139 insertions(+), 36 deletions(-)
>> diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
>> index 0ff6ed9e70..725697c132 100644
>> --- a/tools/libxc/include/xenctrl.h
>> +++ b/tools/libxc/include/xenctrl.h
>> @@ -2607,11 +2607,12 @@ int xc_livepatch_list(xc_interface *xch, unsigned
>> int max, unsigned int start,
>> * to complete them. The `timeout` offers an option to expire the
>> * operation if it could not be completed within the specified time
>> * (in ns). Value of 0 means let hypervisor decide the best timeout.
>> + * The `flags` allows to pass extra parameters to the actions.
>> */
>> -int xc_livepatch_apply(xc_interface *xch, char *name, uint32_t timeout);
>> -int xc_livepatch_revert(xc_interface *xch, char *name, uint32_t timeout);
>> -int xc_livepatch_unload(xc_interface *xch, char *name, uint32_t timeout);
>> -int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout);
>> +int xc_livepatch_apply(xc_interface *xch, char *name, uint32_t timeout,
>> uint64_t flags);
>> +int xc_livepatch_revert(xc_interface *xch, char *name, uint32_t timeout,
>> uint64_t flags);
>> +int xc_livepatch_unload(xc_interface *xch, char *name, uint32_t timeout,
>> uint64_t flags);
>> +int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout,
>> uint64_t flags);
>> /*
>> * Ensure cache coherency after memory modifications. A call to this
>> function
>> diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
>> index 8e60b6e9f0..a8e9e7d1e2 100644
>> --- a/tools/libxc/xc_misc.c
>> +++ b/tools/libxc/xc_misc.c
>> @@ -854,7 +854,8 @@ int xc_livepatch_list(xc_interface *xch, unsigned int
>> max, unsigned int start,
>> static int _xc_livepatch_action(xc_interface *xch,
>> char *name,
>> unsigned int action,
>> - uint32_t timeout)
>> + uint32_t timeout,
>> + uint64_t flags)
>> {
>> int rc;
>> DECLARE_SYSCTL;
>> @@ -880,6 +881,7 @@ static int _xc_livepatch_action(xc_interface *xch,
>> sysctl.u.livepatch.pad = 0;
>> sysctl.u.livepatch.u.action.cmd = action;
>> sysctl.u.livepatch.u.action.timeout = timeout;
>> + sysctl.u.livepatch.u.action.flags = flags;
>> sysctl.u.livepatch.u.action.name = def_name;
>> set_xen_guest_handle(sysctl.u.livepatch.u.action.name.name, name);
>> @@ -891,24 +893,24 @@ static int _xc_livepatch_action(xc_interface *xch,
>> return rc;
>> }
>> -int xc_livepatch_apply(xc_interface *xch, char *name, uint32_t timeout)
>> +int xc_livepatch_apply(xc_interface *xch, char *name, uint32_t timeout,
>> uint64_t flags)
>> {
>> - return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_APPLY, timeout);
>> + return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_APPLY, timeout,
>> flags);
>> }
>> -int xc_livepatch_revert(xc_interface *xch, char *name, uint32_t timeout)
>> +int xc_livepatch_revert(xc_interface *xch, char *name, uint32_t timeout,
>> uint64_t flags)
>> {
>> - return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_REVERT,
>> timeout);
>> + return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_REVERT,
>> timeout, flags);
>> }
>> -int xc_livepatch_unload(xc_interface *xch, char *name, uint32_t timeout)
>> +int xc_livepatch_unload(xc_interface *xch, char *name, uint32_t timeout,
>> uint64_t flags)
>> {
>> - return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_UNLOAD,
>> timeout);
>> + return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_UNLOAD,
>> timeout, flags);
>> }
>> -int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout)
>> +int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout,
>> uint64_t flags)
>> {
>> - return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_REPLACE,
>> timeout);
>> + return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_REPLACE,
>> timeout, flags);
>> }
>> /*
>> diff --git a/tools/misc/xen-livepatch.c b/tools/misc/xen-livepatch.c
>> index 3233472157..a37b2457ff 100644
>> --- a/tools/misc/xen-livepatch.c
>> +++ b/tools/misc/xen-livepatch.c
>> @@ -23,18 +23,23 @@ void show_help(void)
>> {
>> fprintf(stderr,
>> "xen-livepatch: live patching tool\n"
>> - "Usage: xen-livepatch <command> [args]\n"
>> + "Usage: xen-livepatch <command> [args] [command-flags]\n"
>> " <name> An unique name of payload. Up to %d characters.\n"
>> "Commands:\n"
>> " help display this help\n"
>> " upload <name> <file> upload file <file> with <name> name\n"
>> " list list payloads uploaded.\n"
>> - " apply <name> apply <name> patch.\n"
>> + " apply <name> [flags] apply <name> patch.\n"
>> + " Supported flags:\n"
>> + " --nodeps Disable inter-module buildid
>> dependency check.\n"
>> + " Check only against hypervisor
>> buildid.\n"
>> " revert <name> revert name <name> patch.\n"
>> " replace <name> apply <name> patch and revert all
>> others.\n"
>> " unload <name> unload name <name> patch.\n"
>> - " load <file> upload and apply <file>.\n"
>> - " name is the <file> name\n",
>> + " load <file> [flags] upload and apply <file> with name as
>> the <file> name\n"
>> + " Supported flags:\n"
>> + " --nodeps Disable inter-module buildid
>> dependency check.\n"
>> + " Check only against hypervisor
>> buildid.\n",
>> XEN_LIVEPATCH_NAME_SIZE);
>> }
>> @@ -225,12 +230,13 @@ static int upload_func(int argc, char *argv[])
>> return rc;
>> }
>> -/* These MUST match to the 'action_options[]' array slots. */
>> +/* These MUST match to the 'action_options[]' and 'flag_options[]' array
>> slots. */
>> enum {
>> ACTION_APPLY = 0,
>> ACTION_REVERT = 1,
>> ACTION_UNLOAD = 2,
>> ACTION_REPLACE = 3,
>> + ACTION_NUM
>> };
>> struct {
>> @@ -238,7 +244,7 @@ struct {
>> int expected; /* The state to be in after the function. */
>> const char *name;
>> const char *verb;
>> - int (*function)(xc_interface *xch, char *name, uint32_t timeout);
>> + int (*function)(xc_interface *xch, char *name, uint32_t timeout,
>> uint64_t flags);
>> } action_options[] = {
>> { .allow = LIVEPATCH_STATE_CHECKED,
>> .expected = LIVEPATCH_STATE_APPLIED,
>> @@ -266,6 +272,66 @@ struct {
>> },
>> };
>> +/*
>> + * This structure defines supported flag options for actions.
>> + * It defines entries for each action and supports up to 64
>> + * flags per action.
>> + */
>> +struct {
>> + const char *name;
>> + const uint64_t flag;
>> +} flag_options[ACTION_NUM][8 * sizeof(uint64_t)] = {
>> + { /* ACTION_APPLY */
>> + { .name = "--nodeps",
>> + .flag = LIVEPATCH_ACTION_APPLY_NODEPS,
>> + },
>> + },
>> + { /* ACTION_REVERT */
>> + },
>> + { /* ACTION_UNLOAD */
>> + },
>> + { /* ACTION_REPLACE */
>> + }
>> +};
>> +
>> +/*
>> + * Parse user provided action flags.
>> + * This function expects to only receive an array of input parameters being
>> flags.
>> + * Expected action is specified via idx paramater (index of flag_options[]).
>> + */
>> +static int get_flags(int argc, char *argv[], unsigned int idx, uint64_t
>> *flags)
>> +{
>> + int i, j;
>> +
>> + if ( !flags || idx >= ARRAY_SIZE(flag_options) )
>> + return -1;
>> +
>> + *flags = 0;
>> + for ( i = 0; i < argc; i++ )
>> + {
>> + for ( j = 0; j < ARRAY_SIZE(flag_options[idx]); j++ )
>> + {
>> + if ( !flag_options[idx][j].name )
>> + goto error;
>> +
>> + if ( !strcmp(flag_options[idx][j].name, argv[i]) )
>> + {
>> + *flags |= flag_options[idx][j].flag;
>> + break;
>> + }
>> + }
>> +
>> + if ( j == ARRAY_SIZE(flag_options[idx]) )
>> + goto error;
>> + }
>> +
>> + return 0;
>> +error:
>> + fprintf(stderr, "Unsupported flag: %s.\n", argv[i]);
>> + errno = EINVAL;
>> + return errno;
>> +}
>> +
>> /* The hypervisor timeout for the live patching operation is 30 msec,
>> * but it could take some time for the operation to start, so wait twice
>> * that period. */
>> @@ -291,8 +357,9 @@ int action_func(int argc, char *argv[], unsigned int idx)
>> char name[XEN_LIVEPATCH_NAME_SIZE];
>> int rc;
>> xen_livepatch_status_t status;
>> + uint64_t flags;
>> - if ( argc != 1 )
>> + if ( argc < 1 )
>> {
>> show_help();
>> return -1;
>> @@ -301,7 +368,10 @@ int action_func(int argc, char *argv[], unsigned int
>> idx)
>> if ( idx >= ARRAY_SIZE(action_options) )
>> return -1;
>> - if ( get_name(argc, argv, name) )
>> + if ( get_name(argc--, argv++, name) )
>> + return EINVAL;
>> +
>> + if ( get_flags(argc, argv, idx, &flags) )
>> return EINVAL;
>> /* Check initial status. */
>> @@ -332,7 +402,7 @@ int action_func(int argc, char *argv[], unsigned int idx)
>> if ( action_options[idx].allow & status.state )
>> {
>> printf("%s %s... ", action_options[idx].verb, name);
>> - rc = action_options[idx].function(xch, name, HYPERVISOR_TIMEOUT_NS);
>> + rc = action_options[idx].function(xch, name, HYPERVISOR_TIMEOUT_NS,
>> flags);
>> if ( rc )
>> {
>> int saved_errno = errno;
>> @@ -394,17 +464,23 @@ int action_func(int argc, char *argv[], unsigned int
>> idx)
>> static int load_func(int argc, char *argv[])
>> {
>> - int rc;
>> - char *new_argv[2];
>> - char *path, *name, *lastdot;
>> + int i, rc = ENOMEM;
>> + char *upload_argv[2];
>> + char **apply_argv, *path, *name, *lastdot;
>> - if ( argc != 1 )
>> + if ( argc < 1 )
>> {
>> show_help();
>> return -1;
>> }
>> +
>> + /* apply action has <id> [flags] input requirement, which must be
>> constructed */
>> + apply_argv = (char **) malloc(argc * sizeof(*apply_argv));
>> + if ( !apply_argv )
>> + return rc;
>> +
>> /* <file> */
>> - new_argv[1] = argv[0];
>> + upload_argv[1] = argv[0];
>> /* Synthesize the <id> */
>> path = strdup(argv[0]);
>> @@ -413,16 +489,23 @@ static int load_func(int argc, char *argv[])
>> lastdot = strrchr(name, '.');
>> if ( lastdot != NULL )
>> *lastdot = '\0';
>> - new_argv[0] = name;
>> + upload_argv[0] = name;
>> + apply_argv[0] = name;
>> - rc = upload_func(2 /* <id> <file> */, new_argv);
>> + /* Fill in all user provided flags */
>> + for ( i = 0; i < argc - 1; i++ )
>> + apply_argv[i + 1] = argv[i + 1];
>> +
>> + rc = upload_func(2 /* <id> <file> */, upload_argv);
>> if ( rc )
>> - return rc;
>> + goto error;
>> - rc = action_func(1 /* only <id> */, new_argv, ACTION_APPLY);
>> + rc = action_func(argc, apply_argv, ACTION_APPLY);
>> if ( rc )
>> - action_func(1, new_argv, ACTION_UNLOAD);
>> + action_func(1 /* only <id> */, upload_argv, ACTION_UNLOAD);
>> +error:
>> + free(apply_argv);
>> free(path);
>> return rc;
>> }
>> diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
>> index 6a4af6ce57..fb91d5095c 100644
>> --- a/xen/common/livepatch.c
>> +++ b/xen/common/livepatch.c
>> @@ -1575,9 +1575,17 @@ static int livepatch_action(struct
>> xen_sysctl_livepatch_action *action)
>> break;
>> }
>> - rc = build_id_dep(data, !!list_empty(&applied_list));
>> - if ( rc )
>> - break;
>> + /*
>> + * Check if action is issued with nodeps flags to ignore module
>> + * stack dependencies.
>> + */
>> + if ( !(action->flags & LIVEPATCH_ACTION_APPLY_NODEPS) )
>> + {
>> + rc = build_id_dep(data, !!list_empty(&applied_list));
>> + if ( rc )
>> + break;
>> + }
>> +
>> data->rc = -EAGAIN;
>> rc = schedule_work(data, action->cmd, action->timeout);
>> }
>> diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
>> index 91c48dcae0..1b2b165a6d 100644
>> --- a/xen/include/public/sysctl.h
>> +++ b/xen/include/public/sysctl.h
>> @@ -35,7 +35,7 @@
>> #include "domctl.h"
>> #include "physdev.h"
>> -#define XEN_SYSCTL_INTERFACE_VERSION 0x00000012
>> +#define XEN_SYSCTL_INTERFACE_VERSION 0x00000013
>> /*
>> * Read console content from Xen buffer ring.
>> @@ -956,6 +956,15 @@ struct xen_sysctl_livepatch_action {
>> /* hypervisor default. */
>> /* Or upper bound of time (ns)
>> */
>> /* for operation to take. */
>> +
>> +/*
>> + * Overwrite default inter-module buildid dependency chain enforcement.
>> + * Check only if module is built for given hypervisor by comparing buildid.
>> + */
>> +#define LIVEPATCH_ACTION_APPLY_NODEPS (1 << 0)
>> + uint64_t flags; /* IN: action flags. */
>> + /* Provide additional
>> parameters */
>> + /* for an action. */
>> };
>> struct xen_sysctl_livepatch_op {
>
> --
> Julien Grall
Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Ralf Herbrich
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |