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@citrix.com>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
This commit is contained in:
Ian Campbell committed 2012-04-02 17:07:04 +01:00
1 parent 80687dc9ca
commit a7ce17b686
4 files changed
+181 -2

No files matched your search

+25
View File
@@ -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
+1
View File
@@ -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);
+146 -2
View File
@@ -1206,11 +1206,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;
@@ -1265,10 +1285,13 @@ static int handle_domain_death(libxl_ctx *ctx, uint32_t domid,
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:
@@ -1753,7 +1776,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. */
@@ -1790,6 +1815,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.
@@ -3399,6 +3430,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;
@@ -3921,7 +4066,6 @@ static int sched_credit_domain_set(int domid, libxl_sched_credit_domain *scinfo)
{
int rc;
rc = libxl_sched_credit_domain_set(ctx, domid, scinfo);
if (rc)
fprintf(stderr, "libxl_sched_credit_domain_set failed.\n");
+9
View File
@@ -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",
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.