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

Re: [Xen-devel] Re-reading domain configs on domain restart



On Thu, Feb 23, 2012 at 3:16 PM, Ian Campbell <Ian.Campbell@xxxxxxxxxx> wrote:
> On Thu, 2012-02-23 at 11:17 +0000, Ian Campbell wrote:
>> As another (hopefully simple) idea how about a "xl dom-set-config" or
>> similar which (only) updates the config stashed in the userinfo to be
>> used on reboot? I would specifically exclude the possibility of this
>> reconfiguring the running domain for simplicity.
>
> I've only lightly tested the following, but it seemed to do what I
> expected (I used it to change memory from 512 to 1024 for a Windows VM
> on reboot).
>
> I think there might be a better name, that better reflects the fact that
> it doesn't actually change the config right now, any ideas?
> "domain-config-override"?
>
> Thoughts on the general concept?

Is the config used for anything other than a reboot?  If so, it might
lead to unexpected behavior, if for example, I want to change config
option X on reboot, but it's read (and acted on) before I get done
with my various changes.  It would be good if the user could be sure
that none of the changes would have any effect until the next reboot.

I think the concept of having a "config-on-reboot" is a good one.  For
convenience, would it make sense to add a parameter to "xl reboot" to
take an argument (-c for example) that will do the config override
before issuing the reboot command?

 -George

>
> Ian.
> 8<-------------------------------------------------------
>
> xl: provide a command to set the saved configuration for a running domain
>
> Pickup this new configuration on reboot.
>
> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
>
> diff -r 8b82b7435b7d -r 063d98ba8309 docs/man/xl.pod.1
> --- a/docs/man/xl.pod.1 Thu Feb 23 12:31:18 2012 +0000
> +++ b/docs/man/xl.pod.1 Thu Feb 23 15:14:29 2012 +0000
> @@ -148,6 +148,31 @@ soon as it is run.
>
>  =back
>
> +=item B<config-update> B<domid> [I<configfile>] [I<OPTIONS>]
> +
> +Update the saved configuration for a running domain. This has no
> +immediate effect but will be applied when the guest is next
> +restarted. This command is useful to ensure that runtime modifications
> +made to the guest will be preserved when the guest is restarted.
> +
> +I<configfile> has to be an absolute path to a file.
> +
> +B<OPTIONS>
> +
> +=over 4
> +
> +=item B<-f=FILE>, B<--defconfig=FILE>
> +
> +Use the given configuration file.
> +
> +=item B<key=value>
> +
> +It is possible to pass I<key=value> pairs on the command line to provide
> +options as if they were written in the configuration file; these override
> +whatever is in the I<configfile>.
> +
> +=back
> +
>  =item B<console> [I<OPTIONS>] I<domain-id>
>
>  Attach to domain I<domain-id>'s console.  If you've set up your domains to
> diff -r 8b82b7435b7d -r 063d98ba8309 tools/libxl/xl.h
> --- a/tools/libxl/xl.h  Thu Feb 23 12:31:18 2012 +0000
> +++ b/tools/libxl/xl.h  Thu Feb 23 15:14:29 2012 +0000
> @@ -50,6 +50,7 @@ int main_reboot(int argc, char **argv);
>  int main_list(int argc, char **argv);
>  int main_list_vm(int argc, char **argv);
>  int main_create(int argc, char **argv);
> +int main_config_update(int argc, char **argv);
>  int main_button_press(int argc, char **argv);
>  int main_vcpupin(int argc, char **argv);
>  int main_vcpuset(int argc, char **argv);
> diff -r 8b82b7435b7d -r 063d98ba8309 tools/libxl/xl_cmdimpl.c
> --- a/tools/libxl/xl_cmdimpl.c  Thu Feb 23 12:31:18 2012 +0000
> +++ b/tools/libxl/xl_cmdimpl.c  Thu Feb 23 15:14:29 2012 +0000
> @@ -1201,11 +1201,31 @@ skip_vfb:
>     xlu_cfg_destroy(config);
>  }
>
> +static void reload_domain_config(libxl_ctx *ctx, uint32_t domid,
> +                                 uint8_t **config_data, int *config_len)
> +{
> +    uint8_t *t_data;
> +    int ret, t_len;
> +
> +    ret = libxl_userdata_retrieve(ctx, domid, "xl", &t_data, &t_len);
> +    if (ret) {
> +        LOG("failed to retrieve guest configuration (rc=%d). "
> +            "reusing old configuration", ret);
> +        return;
> +    }
> +
> +    free(*config_data);
> +    *config_data = t_data;
> +    *config_len = t_len;
> +}
> +
>  /* Returns 1 if domain should be restarted,
>  * 2 if domain should be renamed then restarted, or 0 */
>  static int handle_domain_death(libxl_ctx *ctx, uint32_t domid,
>                                libxl_event *event,
> +                               uint8_t **config_data, int *config_len,
>                                libxl_domain_config *d_config)
> +
>  {
>     int restart = 0;
>     libxl_action_on_shutdown action;
> @@ -1260,10 +1280,13 @@ static int handle_domain_death(libxl_ctx
>         break;
>
>     case LIBXL_ACTION_ON_SHUTDOWN_RESTART_RENAME:
> +        reload_domain_config(ctx, domid, config_data, config_len);
>         restart = 2;
>         break;
>
>     case LIBXL_ACTION_ON_SHUTDOWN_RESTART:
> +        reload_domain_config(ctx, domid, config_data, config_len);
> +
>         restart = 1;
>         /* fall-through */
>     case LIBXL_ACTION_ON_SHUTDOWN_DESTROY:
> @@ -1748,7 +1771,9 @@ start:
>             LOG("Domain %d has shut down, reason code %d 0x%x", domid,
>                 event->u.domain_shutdown.shutdown_reason,
>                 event->u.domain_shutdown.shutdown_reason);
> -            switch (handle_domain_death(ctx, domid, event, &d_config)) {
> +            switch (handle_domain_death(ctx, domid, event,
> +                                        (uint8_t **)&config_data, 
> &config_len,
> +                                        &d_config)) {
>             case 2:
>                 if (!preserve_domain(ctx, domid, event, &d_config)) {
>                     /* If we fail then exit leaving the old domain in place. 
> */
> @@ -1785,6 +1810,12 @@ start:
>                     d_config.c_info.name = strdup(common_domname);
>                 }
>
> +                /* Reparse the configuration in case it has changed */
> +                libxl_domain_config_dispose(&d_config);
> +                memset(&d_config, 0, sizeof(d_config));
> +                parse_config_data(config_file, config_data, config_len,
> +                                  &d_config);
> +
>                 /*
>                  * XXX FIXME: If this sleep is not there then domain
>                  * re-creation fails sometimes.
> @@ -3394,6 +3425,120 @@ int main_create(int argc, char **argv)
>     return 0;
>  }
>
> +int main_config_update(int argc, char **argv)
> +{
> +    const char *filename = NULL;
> +    char *p;
> +    char extra_config[1024];
> +    void *config_data = 0;
> +    int config_len = 0;
> +    libxl_domain_config d_config;
> +    int opt, rc;
> +    int option_index = 0;
> +    int debug = 0;
> +    static struct option long_options[] = {
> +        {"help", 0, 0, 'h'},
> +        {"defconfig", 1, 0, 'f'},
> +        {0, 0, 0, 0}
> +    };
> +
> +    if (argc < 2) {
> +        fprintf(stderr, "xl config-update requires a domain argument\n");
> +        help("config-update");
> +        exit(1);
> +    }
> +
> +    find_domain(argv[1]);
> +    argc--; argv++;
> +
> +    if (argv[1] && argv[1][0] != '-' && !strchr(argv[1], '=')) {
> +        filename = argv[1];
> +        argc--; argv++;
> +    }
> +
> +    while (1) {
> +        opt = getopt_long(argc, argv, "dhqf:", long_options, &option_index);
> +        if (opt == -1)
> +            break;
> +
> +        switch (opt) {
> +        case 'd':
> +            debug = 1;
> +            break;
> +        case 'f':
> +            filename = optarg;
> +            break;
> +        case 'h':
> +            help("create");
> +            return 0;
> +        default:
> +            fprintf(stderr, "option `%c' not supported.\n", optopt);
> +            break;
> +        }
> +    }
> +
> +    extra_config[0] = '\0';
> +    for (p = extra_config; optind < argc; optind++) {
> +        if (strchr(argv[optind], '=') != NULL) {
> +            p += snprintf(p, sizeof(extra_config) - (p - extra_config),
> +                "%s\n", argv[optind]);
> +        } else if (!filename) {
> +            filename = argv[optind];
> +        } else {
> +            help("create");
> +            return 2;
> +        }
> +    }
> +    if (filename) {
> +        free(config_data);  config_data = 0;
> +        rc = libxl_read_file_contents(ctx, filename,
> +                                      &config_data, &config_len);
> +        if (rc) { fprintf(stderr, "Failed to read config file: %s: %s\n",
> +                           filename, strerror(errno)); return ERROR_FAIL; }
> +        if (strlen(extra_config)) {
> +            if (config_len > INT_MAX - (strlen(extra_config) + 2 + 1)) {
> +                fprintf(stderr, "Failed to attach extra configration\n");
> +                exit(1);
> +            }
> +            /* allocate space for the extra config plus two EOLs plus \0 */
> +            config_data = realloc(config_data, config_len
> +                + strlen(extra_config) + 2 + 1);
> +            if (!config_data) {
> +                fprintf(stderr, "Failed to realloc config_data\n");
> +                exit(1);
> +            }
> +            config_len += sprintf(config_data + config_len, "\n%s\n",
> +                extra_config);
> +        }
> +    } else {
> +        fprintf(stderr, "Config file not specified\n");
> +        exit(1);
> +    }
> +
> +    memset(&d_config, 0x00, sizeof(d_config));
> +
> +    parse_config_data(filename, config_data, config_len, &d_config);
> +
> +    if (debug || dryrun_only)
> +        printf_info(default_output_format, -1, &d_config);
> +
> +    if (!dryrun_only) {
> +        fprintf(stderr, "setting dom%d configuration\n", domid);
> +        rc = libxl_userdata_store(ctx, domid, "xl",
> +                                   config_data, config_len);
> +        if (rc) {
> +            fprintf(stderr, "failed to update configuration\n");
> +            exit(1);
> +        }
> +    }
> +
> +    libxl_domain_config_dispose(&d_config);
> +
> +    free(config_data);
> +
> +    return 0;
> +}
> +
>  static void button_press(const char *p, const char *b)
>  {
>     libxl_trigger trigger;
> @@ -3917,7 +4062,6 @@ static int sched_credit_domain_set(
>  {
>     int rc;
>
> -
>     rc = libxl_sched_credit_domain_set(ctx, domid, scinfo);
>     if (rc)
>         fprintf(stderr, "libxl_sched_credit_domain_set failed.\n");
> diff -r 8b82b7435b7d -r 063d98ba8309 tools/libxl/xl_cmdtable.c
> --- a/tools/libxl/xl_cmdtable.c Thu Feb 23 12:31:18 2012 +0000
> +++ b/tools/libxl/xl_cmdtable.c Thu Feb 23 15:14:29 2012 +0000
> @@ -32,6 +32,15 @@ struct cmd_spec cmd_table[] = {
>       "-d                      Enable debug messages.\n"
>       "-e                      Do not wait in the background for the death of 
> the domain."
>     },
> +    { "config-update",
> +      &main_config_update, 1,
> +      "Update a running domain's saved configuration, used when rebuilding "
> +      "the domain after reboot",
> +      "<Domain> <ConfigFile> [options] [vars]",
> +      "-h                      Print this help.\n"
> +      "-f FILE, --defconfig=FILE\n                     Use the given 
> configuration file.\n"
> +      "-d                      Enable debug messages.\n"
> +    },
>     { "list",
>       &main_list, 0,
>       "List information about all/some domains",
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.