# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1320244864 -3600
# Node ID ab5406a5b1d01e3828f0dcd833f99b70e4fbad72
# Parent a51d4fab351d2d1a38b82cbd7ad925f76fce9e9a
xenpaging: initial libxl support
Add initial support to libxl for starting xenpaging.
The patch adds three new config options:
actmem=<int>, the amount of memory in MiB for the guest
xenpaging_file=<string>, pagefile to use (optional)
xenpaging_extra=[ 'string', 'string' ], additional args for xenpaging (optional)
If 'actmem=' is not specified in config file, xenpaging will not start.
If 'xenpaging_file=' is not specified in config file,
/var/lib/xen/xenpaging/<domain_name>.<domaind_id>.paging is used.
Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
diff -r a51d4fab351d -r ab5406a5b1d0 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -261,6 +261,7 @@ int libxl_init_dm_info(libxl_ctx *ctx,
typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv);
int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config,
libxl_console_ready cb, void *priv, uint32_t *domid);
int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config,
libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd);
+int libxl__create_xenpaging(libxl_ctx *ctx, libxl_domain_config *d_config,
uint32_t domid, char *path);
void libxl_domain_config_destroy(libxl_domain_config *d_config);
int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info,
uint32_t domid, int fd);
diff -r a51d4fab351d -r ab5406a5b1d0 tools/libxl/libxl_create.c
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -429,6 +429,122 @@ retry_transaction:
return rc;
}
+static int create_xenpaging(libxl__gc *gc, char *dom_name, uint32_t domid,
+ libxl_domain_build_info *b_info)
+{
+ libxl__spawner_starting *buf_starting;
+ libxl_string_list xpe = b_info->u.hvm.xenpaging_extra;
+ int i, rc;
+ char *logfile;
+ int logfile_w, null;
+ char *path, *dom_path, *value;
+ char **args;
+ char *xp;
+ flexarray_t *xp_args;
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+
+ /* Nothing to do */
+ if (!b_info->tot_memkb)
+ return 0;
+
+ /* Check if paging is already enabled */
+ dom_path = libxl__xs_get_dompath(gc, domid);
+ if (!dom_path ) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+ path = libxl__sprintf(gc, "%s/xenpaging/state", dom_path);
+ if (!path ) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+ value = xs_read(ctx->xsh, XBT_NULL, path, NULL);
+ rc = value && strcmp(value, "running") == 0;
+ free(value);
+ /* Already running, nothing to do */
+ if (rc)
+ return 0;
+
+ /* Check if xenpaging is present */
+ xp = libxl__abs_path(gc, "xenpaging", libxl_libexec_path());
+ if (access(xp, X_OK) < 0) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "%s is not executable", xp);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ /* Initialise settings for child */
+ buf_starting = calloc(sizeof(*buf_starting), 1);
+ if (!buf_starting) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+ buf_starting->domid = domid;
+ buf_starting->dom_path = dom_path;
+ buf_starting->pid_path = "xenpaging/xenpaging-pid";
+ buf_starting->for_spawn = calloc(sizeof(libxl__spawn_starting), 1);
+ if (!buf_starting->for_spawn) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+
+ /* Assemble arguments for xenpaging */
+ xp_args = flexarray_make(8, 1);
+ if (!xp_args) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+ /* Set executable path */
+ flexarray_append(xp_args, xp);
+
+ /* Append pagefile option */
+ flexarray_append(xp_args, "-f");
+ if (b_info->u.hvm.xenpaging_file)
+ flexarray_append(xp_args, b_info->u.hvm.xenpaging_file);
+ else
+ flexarray_append(xp_args, libxl__sprintf(gc, "%s/%s.%u.paging",
+ libxl_xenpaging_dir_path(), dom_name, domid));
+
+ /* Set maximum amount of memory xenpaging should handle */
+ flexarray_append(xp_args, "-m");
+ flexarray_append(xp_args, libxl__sprintf(gc, "%d", b_info->max_memkb));
+
+ /* Append extra args for pager */
+ for (i = 0; xpe && xpe[i]; i++)
+ flexarray_append(xp_args, xpe[i]);
+ /* Append domid for pager */
+ flexarray_append(xp_args, "-d");
+ flexarray_append(xp_args, libxl__sprintf(gc, "%u", domid));
+ flexarray_append(xp_args, NULL);
+ args = (char **) flexarray_contents(xp_args);
+
+ /* Initialise logfile */
+ libxl_create_logfile(ctx, libxl__sprintf(gc, "xenpaging-%s", dom_name),
+ &logfile);
+ logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644);
+ free(logfile);
+ null = open("/dev/null", O_RDONLY);
+
+ /* Spawn the child */
+ rc = libxl__spawn_spawn(gc, buf_starting->for_spawn, "xenpaging",
+ libxl_spawner_record_pid, buf_starting);
+ if (rc < 0)
+ goto out_close;
+ if (!rc) { /* inner child */
+ setsid();
+ /* Finally run xenpaging */
+ libxl__exec(null, logfile_w, logfile_w, xp, args);
+ }
+ rc = libxl__spawn_confirm_offspring_startup(gc, 5, "xenpaging", path,
+ "running", buf_starting);
+out_close:
+ close(null);
+ close(logfile_w);
+ free(args);
+out:
+ return rc;
+}
+
static int do_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
libxl_console_ready cb, void *priv,
uint32_t *domid_out, int restore_fd)
@@ -614,6 +730,16 @@ static int do_domain_create(libxl__gc *g
goto error_out;
}
+ if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM) {
+ ret = create_xenpaging(gc, d_config->dm_info.dom_name, domid,
+ &d_config->b_info);
+ if (ret) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+ "Failed to start xenpaging.\n");
+ goto error_out;
+ }
+ }
+
*domid_out = domid;
return 0;
diff -r a51d4fab351d -r ab5406a5b1d0 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -108,7 +108,7 @@ int libxl__build_post(libxl__gc *gc, uin
if (info->cpuid != NULL)
libxl_cpuid_set(ctx, domid, info->cpuid);
- ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
+ ents = libxl__calloc(gc, 14 + (info->max_vcpus * 2) + 2, sizeof(char *));
ents[0] = "memory/static-max";
ents[1] = libxl__sprintf(gc, "%d", info->max_memkb);
ents[2] = "memory/target";
@@ -121,9 +121,11 @@ int libxl__build_post(libxl__gc *gc, uin
ents[9] = libxl__sprintf(gc, "%"PRIu32, state->store_port);
ents[10] = "store/ring-ref";
ents[11] = libxl__sprintf(gc, "%lu", state->store_mfn);
+ ents[12] = "memory/target-tot_pages";
+ ents[13] = libxl__sprintf(gc, "%d", info->tot_memkb);
for (i = 0; i < info->max_vcpus; i++) {
- ents[12+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i);
- ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 <<
i)))
+ ents[14+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i);
+ ents[14+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 <<
i)))
? "offline" : "online";
}
diff -r a51d4fab351d -r ab5406a5b1d0 tools/libxl/libxl_memory.txt
--- a/tools/libxl/libxl_memory.txt
+++ b/tools/libxl/libxl_memory.txt
@@ -1,28 +1,28 @@
/* === Domain memory breakdown: HVM guests ==================================
- + +----------+ +
- | | shadow | |
- | +----------+ |
- overhead | | extra | |
- | | external | |
- | +----------+ + |
- | | extra | | |
- | | internal | | |
- + +----------+ + | | footprint
- | | video | | | |
- | +----------+ + + | | xen |
- | | | | | | actual | maximum |
- | | | | | | target | |
- | | guest | | | build | | |
- | | | | | start | | |
- static | | | | | | | |
- maximum | +----------+ | + + + +
- | | | |
- | | | |
- | | balloon | | build
- | | | | maximum
- | | | |
- + +----------+ +
+ + +----------+ +
+ | | shadow | |
+ | +----------+ |
+ overhead | | extra | |
+ | | external | |
+ | +----------+ + |
+ | | extra | | |
+ | | internal | | |
+ + +----------+ + | |
footprint
+ | | video | | | |
+ | +----------+ + + + | | xen |
+ | | | | guest OS | | | actual | maximum |
+ | | guest | | real RAM | | | target | |
+ | | | | | | build | | |
+ | |----------+ + | | start + | |
+ static | | paging | | | | |
+ maximum | +----------+ | + + +
+ | | | |
+ | | | |
+ | | balloon | | build
+ | | | | maximum
+ | | | |
+ + +----------+ +
extra internal = LIBXL_MAXMEM_CONSTANT
@@ -34,6 +34,17 @@
libxl_domain_setmaxmem -> xen maximum
libxl_set_memory_target -> actual target
+ build maximum = RAM as seen inside the virtual machine
+ Guest OS has to configure itself for this amount of memory
+ Increase/Decrease via memory hotplug of virtual hardware.
+ xl mem-max
+ build start = RAM usable by the guest OS
+ Guest OS sees balloon driver as memory hog
+ Increase/Decrease via commands to the balloon driver
+ xl mem-set
+ actual target = RAM allocated for the guest
+ Increase/Decrease via commands to paging daemon
+ xl mem-paging_target (?)
=== Domain memory breakdown: PV guests ==================================
diff -r a51d4fab351d -r ab5406a5b1d0 tools/libxl/libxl_types.idl
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -157,6 +157,7 @@ libxl_domain_build_info = Struct("domain
("tsc_mode", integer),
("max_memkb", uint32),
("target_memkb", uint32),
+ ("tot_memkb", uint32),
("video_memkb", uint32),
("shadow_memkb", uint32),
("disable_migrate", bool),
@@ -174,6 +175,8 @@ libxl_domain_build_info = Struct("domain
("vpt_align", bool),
("timer_mode", integer),
("nested_hvm", bool),
+ ("xenpaging_file", string),
+ ("xenpaging_extra", libxl_string_list),
])),
("pv", Struct(None, [("kernel", libxl_file_reference),
("slack_memkb", uint32),
diff -r a51d4fab351d -r ab5406a5b1d0 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -346,6 +346,7 @@ static void printf_info(int domid,
printf("\t\t\t(firmware %s)\n", b_info->u.hvm.firmware);
printf("\t\t\t(video_memkb %d)\n", b_info->video_memkb);
printf("\t\t\t(shadow_memkb %d)\n", b_info->shadow_memkb);
+ printf("\t\t\t(tot_memkb %d)\n", b_info->tot_memkb);
printf("\t\t\t(pae %d)\n", b_info->u.hvm.pae);
printf("\t\t\t(apic %d)\n", b_info->u.hvm.apic);
printf("\t\t\t(acpi %d)\n", b_info->u.hvm.acpi);
@@ -380,6 +381,7 @@ static void printf_info(int domid,
printf("\t\t\t(spicedisable_ticketing %d)\n",
dm_info->spicedisable_ticketing);
printf("\t\t\t(spiceagent_mouse %d)\n", dm_info->spiceagent_mouse);
+ printf("\t\t\t(xenpaging_file %s)\n", b_info->u.hvm.xenpaging_file);
printf("\t\t)\n");
break;
case LIBXL_DOMAIN_TYPE_PV:
@@ -515,6 +517,28 @@ static void parse_disk_config(XLU_Config
parse_disk_config_multistring(config, 1, &spec, disk);
}
+static void parse_xenpaging_extra(const XLU_Config *config, libxl_string_list
*xpe)
+{
+ XLU_ConfigList *args;
+ libxl_string_list l;
+ const char *val;
+ int nr_args = 0, i;
+
+ if (xlu_cfg_get_list(config, "xenpaging_extra", &args, &nr_args, 1))
+ return;
+
+ l = xmalloc(sizeof(char*)*(nr_args + 1));
+ if (!l)
+ return;
+
+ l[nr_args] = NULL;
+ for (i = 0; i < nr_args; i++) {
+ val = xlu_cfg_get_listitem(args, i);
+ l[i] = val ? strdup(val) : NULL;
+ }
+ *xpe = l;
+}
+
static void parse_config_data(const char *configfile_filename_report,
const char *configfile_data,
int configfile_len,
@@ -620,6 +644,9 @@ static void parse_config_data(const char
if (!xlu_cfg_get_long (config, "maxmem", &l))
b_info->max_memkb = l * 1024;
+ if (!xlu_cfg_get_long (config, "actmem", &l))
+ b_info->tot_memkb = l * 1024;
+
if (xlu_cfg_get_string (config, "on_poweroff", &buf))
buf = "destroy";
if (!parse_action_on_shutdown(buf, &d_config->on_poweroff)) {
@@ -695,6 +722,10 @@ static void parse_config_data(const char
b_info->u.hvm.timer_mode = l;
if (!xlu_cfg_get_long (config, "nestedhvm", &l))
b_info->u.hvm.nested_hvm = l;
+
+ xlu_cfg_replace_string (config, "xenpaging_file",
&b_info->u.hvm.xenpaging_file);
+ parse_xenpaging_extra(config, &b_info->u.hvm.xenpaging_extra);
+
break;
case LIBXL_DOMAIN_TYPE_PV:
{
diff -r a51d4fab351d -r ab5406a5b1d0 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -40,6 +40,8 @@
/* Defines number of mfns a guest should use at a time, in KiB */
#define WATCH_TARGETPAGES "memory/target-tot_pages"
+/* Defines path to startup confirmation */
+#define WATCH_STARTUP "xenpaging/state"
static char *watch_target_tot_pages;
static char *dom_path;
static char watch_token[16];
@@ -772,6 +774,20 @@ static int evict_pages(xenpaging_t *pagi
return num;
}
+static void xenpaging_confirm_startup(xenpaging_t *paging)
+{
+ xc_interface *xch = paging->xc_handle;
+ char *path;
+ int len;
+
+ len = asprintf(&path, "%s/%s", dom_path, WATCH_STARTUP);
+ if ( len < 0 )
+ return;
+ DPRINTF("confirming startup in %s\n", path);
+ xs_write(paging->xs_handle, XBT_NULL, path, "running", len);
+ free(path);
+}
+
int main(int argc, char *argv[])
{
struct sigaction act;
@@ -830,6 +846,9 @@ int main(int argc, char *argv[])
/* listen for page-in events to stop pager */
create_page_in_thread(paging);
+ /* Confirm startup to caller */
+ xenpaging_confirm_startup(paging);
+
/* Swap pages in and out */
while ( 1 )
{
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|