diff --git a/Config.mk b/Config.mk index 55aa0446c9..e5976fc009 100644 --- a/Config.mk +++ b/Config.mk @@ -268,9 +268,9 @@ SEABIOS_UPSTREAM_REVISION ?= rel-1.8.0 ETHERBOOT_NICS ?= rtl8139 8086100e -QEMU_TRADITIONAL_REVISION ?= ab42b4408cb4fc4f869d73218e3d2034e6f5e8ac -# Tue Mar 31 16:27:45 2015 +0100 -# xen: limit guest control of PCI command register +QEMU_TRADITIONAL_REVISION ?= 3b45fcf0c163b9cff4d8115f7b75b42918a9b1b5 +# Thu Apr 9 19:49:24 2015 +0100 +# qemu-trad: xenstore: use relative path for device-model node # Specify which qemu-dm to use. This may be `ioemu' to use the old # Mercurial in-tree version, or a local directory, or a git URL. diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 2a735b3d5b..511eef1e04 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1033,7 +1033,9 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid) } if (type == LIBXL_DOMAIN_TYPE_HVM) { - path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid); + uint32_t dm_domid = libxl_get_stubdom_id(ctx, domid); + + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/state"); state = libxl__xs_read(gc, XBT_NULL, path); if (state != NULL && !strcmp(state, "paused")) { libxl__qemu_traditional_cmd(gc, domid, "continue"); diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index 0f50d0475d..0c06dc4bd4 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -1188,7 +1188,9 @@ int libxl__wait_for_device_model_deprecated(libxl__gc *gc, void *check_callback_userdata) { char *path; - path = GCSPRINTF("/local/domain/0/device-model/%d/state", domid); + uint32_t dm_domid = libxl_get_stubdom_id(CTX, domid); + + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/state"); return libxl__xenstore_child_wait_deprecated(gc, domid, LIBXL_DEVICE_MODEL_START_TIMEOUT, "Device Model", path, state, spawning, diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c index f20565ae1b..30c1578c55 100644 --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -1010,6 +1010,8 @@ static void stubdom_pvqemu_cb(libxl__egc *egc, static void spawn_stubdom_pvqemu_destroy_cb(libxl__egc *egc, libxl__destroy_domid_state *dis, int rc); +static void stubdom_xswait_cb(libxl__egc *egc, libxl__xswait_state *xswait, + int rc, const char *p); char *libxl__stub_dm_name(libxl__gc *gc, const char *guest_name) { @@ -1140,9 +1142,10 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss) retry_transaction: t = xs_transaction_start(ctx->xsh); xs_mkdir(ctx->xsh, t, - libxl__sprintf(gc, "/local/domain/0/device-model/%d", guest_domid)); + libxl__device_model_xs_path(gc, dm_domid, guest_domid, "")); xs_set_permissions(ctx->xsh, t, - libxl__sprintf(gc, "/local/domain/0/device-model/%d", guest_domid), + libxl__device_model_xs_path(gc, dm_domid, + guest_domid, ""), perm, ARRAY_SIZE(perm)); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) @@ -1288,6 +1291,8 @@ static void stubdom_pvqemu_cb(libxl__egc *egc, STATE_AO_GC(sdss->dm.spawn.ao); uint32_t dm_domid = sdss->pvqemu.guest_domid; + libxl__xswait_init(&sdss->xswait); + if (rc) { LOGE(ERROR, "error connecting nics devices"); goto out; @@ -1296,10 +1301,45 @@ static void stubdom_pvqemu_cb(libxl__egc *egc, rc = libxl_domain_unpause(CTX, dm_domid); if (rc) goto out; + sdss->xswait.ao = ao; + sdss->xswait.what = GCSPRINTF("Stubdom %u for %u startup", + dm_domid, sdss->dm.guest_domid); + sdss->xswait.path = + libxl__device_model_xs_path(gc, dm_domid, sdss->dm.guest_domid, + "/state"); + sdss->xswait.timeout_ms = LIBXL_STUBDOM_START_TIMEOUT * 1000; + sdss->xswait.callback = stubdom_xswait_cb; + rc = libxl__xswait_start(gc, &sdss->xswait); + if (rc) goto out; + + return; + out: + stubdom_xswait_cb(egc, &sdss->xswait, rc, NULL); +} + +static void stubdom_xswait_cb(libxl__egc *egc, libxl__xswait_state *xswait, + int rc, const char *p) +{ + EGC_GC; + libxl__stub_dm_spawn_state *sdss = CONTAINER_OF(xswait, *sdss, xswait); + uint32_t dm_domid = sdss->pvqemu.guest_domid; + + if (rc) { + if (rc == ERROR_TIMEDOUT) + LOG(ERROR, "%s: startup timed out", xswait->what); + goto out; + } + + if (!p) return; + + if (strcmp(p, "running")) + return; + out: + libxl__xswait_stop(gc, xswait); if (rc) { if (dm_domid) { - sdss->dis.ao = ao; + sdss->dis.ao = sdss->dm.spawn.ao; sdss->dis.domid = dm_domid; sdss->dis.callback = spawn_stubdom_pvqemu_destroy_cb; libxl__destroy_domid(egc, &sdss->dis); diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index a88db69d4c..9711fb647d 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -1010,7 +1010,8 @@ int libxl__qemu_traditional_cmd(libxl__gc *gc, uint32_t domid, const char *cmd) { char *path = NULL; - path = GCSPRINTF("/local/domain/0/device-model/%d/command", domid); + uint32_t dm_domid = libxl_get_stubdom_id(CTX, domid); + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/command"); return libxl__xs_write(gc, XBT_NULL, path, "%s", cmd); } @@ -1024,11 +1025,13 @@ struct libxl__physmap_info { #define TOOLSTACK_SAVE_VERSION 1 -static inline char *restore_helper(libxl__gc *gc, uint32_t domid, - uint64_t phys_offset, char *node) +static inline char *restore_helper(libxl__gc *gc, uint32_t dm_domid, + uint32_t domid, + uint64_t phys_offset, char *node) { - return GCSPRINTF("/local/domain/0/device-model/%d/physmap/%"PRIx64"/%s", - domid, phys_offset, node); + return libxl__device_model_xs_path(gc, dm_domid, domid, + "/physmap/%"PRIx64"/%s", + phys_offset, node); } int libxl__toolstack_restore(uint32_t domid, const uint8_t *buf, @@ -1042,6 +1045,7 @@ int libxl__toolstack_restore(uint32_t domid, const uint8_t *buf, uint32_t count = 0, version = 0; struct libxl__physmap_info* pi; char *xs_path; + uint32_t dm_domid; LOG(DEBUG,"domain=%"PRIu32" toolstack data size=%"PRIu32, domid, size); @@ -1067,20 +1071,23 @@ int libxl__toolstack_restore(uint32_t domid, const uint8_t *buf, return -1; } + dm_domid = libxl_get_stubdom_id(CTX, domid); for (i = 0; i < count; i++) { pi = (struct libxl__physmap_info*) ptr; ptr += sizeof(struct libxl__physmap_info) + pi->namelen; - xs_path = restore_helper(gc, domid, pi->phys_offset, "start_addr"); + xs_path = restore_helper(gc, dm_domid, domid, + pi->phys_offset, "start_addr"); ret = libxl__xs_write(gc, 0, xs_path, "%"PRIx64, pi->start_addr); if (ret) return -1; - xs_path = restore_helper(gc, domid, pi->phys_offset, "size"); + xs_path = restore_helper(gc, dm_domid, domid, pi->phys_offset, "size"); ret = libxl__xs_write(gc, 0, xs_path, "%"PRIx64, pi->size); if (ret) return -1; if (pi->namelen > 0) { - xs_path = restore_helper(gc, domid, pi->phys_offset, "name"); + xs_path = restore_helper(gc, dm_domid, domid, + pi->phys_offset, "name"); ret = libxl__xs_write(gc, 0, xs_path, "%s", pi->name); if (ret) return -1; @@ -1133,10 +1140,11 @@ static void domain_suspend_switch_qemu_xen_traditional_logdirty const char *got; if (!lds->cmd_path) { - lds->cmd_path = GCSPRINTF( - "/local/domain/0/device-model/%u/logdirty/cmd", domid); - lds->ret_path = GCSPRINTF( - "/local/domain/0/device-model/%u/logdirty/ret", domid); + uint32_t dm_domid = libxl_get_stubdom_id(CTX, domid); + lds->cmd_path = libxl__device_model_xs_path(gc, dm_domid, domid, + "/logdirty/cmd"); + lds->ret_path = libxl__device_model_xs_path(gc, dm_domid, domid, + "/logdirty/ret"); } lds->cmd = enable ? "enable" : "disable"; @@ -1655,11 +1663,13 @@ static void domain_suspend_common_done(libxl__egc *egc, dss->callback_common_done(egc, dss, ok); } -static inline char *physmap_path(libxl__gc *gc, uint32_t domid, - char *phys_offset, char *node) +static inline char *physmap_path(libxl__gc *gc, uint32_t dm_domid, + uint32_t domid, + char *phys_offset, char *node) { - return GCSPRINTF("/local/domain/0/device-model/%d/physmap/%s/%s", - domid, phys_offset, node); + return libxl__device_model_xs_path(gc, dm_domid, domid, + "/physmap/%s/%s", + phys_offset, node); } int libxl__toolstack_save(uint32_t domid, uint8_t **buf, @@ -1674,9 +1684,13 @@ int libxl__toolstack_save(uint32_t domid, uint8_t **buf, uint8_t *ptr = NULL; char **entries = NULL; struct libxl__physmap_info *pi; + uint32_t dm_domid; - entries = libxl__xs_directory(gc, 0, GCSPRINTF( - "/local/domain/0/device-model/%d/physmap", domid), &num); + dm_domid = libxl_get_stubdom_id(CTX, domid); + + entries = libxl__xs_directory(gc, 0, + libxl__device_model_xs_path(gc, dm_domid, domid, "/physmap"), + &num); count = num; *len = sizeof(version) + sizeof(count); @@ -1699,21 +1713,21 @@ int libxl__toolstack_save(uint32_t domid, uint8_t **buf, return -1; } - xs_path = physmap_path(gc, domid, phys_offset, "start_addr"); + xs_path = physmap_path(gc, dm_domid, domid, phys_offset, "start_addr"); start_addr = libxl__xs_read(gc, 0, xs_path); if (start_addr == NULL) { LOG(ERROR, "%s is NULL", xs_path); return -1; } - xs_path = physmap_path(gc, domid, phys_offset, "size"); + xs_path = physmap_path(gc, dm_domid, domid, phys_offset, "size"); size = libxl__xs_read(gc, 0, xs_path); if (size == NULL) { LOG(ERROR, "%s is NULL", xs_path); return -1; } - xs_path = physmap_path(gc, domid, phys_offset, "name"); + xs_path = physmap_path(gc, dm_domid, domid, phys_offset, "name"); name = libxl__xs_read(gc, 0, xs_path); if (name == NULL) namelen = 0; diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 3aba221bd8..9c2230939f 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -86,6 +86,7 @@ #define LIBXL_DESTROY_TIMEOUT 10 #define LIBXL_HOTPLUG_TIMEOUT 10 #define LIBXL_DEVICE_MODEL_START_TIMEOUT 10 +#define LIBXL_STUBDOM_START_TIMEOUT 30 #define LIBXL_QEMU_BODGE_TIMEOUT 2 #define LIBXL_XENCONSOLE_LIMIT 1048576 #define LIBXL_XENCONSOLE_PROTOCOL "vt100" @@ -3075,6 +3076,7 @@ typedef struct { libxl__dm_spawn_state pvqemu; libxl__destroy_domid_state dis; libxl__multidev multidev; + libxl__xswait_state xswait; } libxl__stub_dm_spawn_state; _hidden void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state*); diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c index f3ae1329ff..394f61c128 100644 --- a/tools/libxl/libxl_pci.c +++ b/tools/libxl/libxl_pci.c @@ -850,11 +850,12 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid, int rc = 0; char *path; char *state, *vdevfn; + uint32_t dm_domid; - path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid); + dm_domid = libxl_get_stubdom_id(CTX, domid); + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/state"); state = libxl__xs_read(gc, XBT_NULL, path); - path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter", - domid); + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/parameter"); if (pcidev->vdevfn) { libxl__xs_write(gc, XBT_NULL, path, PCI_BDF_VDEVFN","PCI_OPTIONS, pcidev->domain, pcidev->bus, pcidev->dev, @@ -869,11 +870,9 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid, libxl__qemu_traditional_cmd(gc, domid, "pci-ins"); rc = libxl__wait_for_device_model_deprecated(gc, domid, NULL, NULL, pci_ins_check, state); - path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter", - domid); + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/parameter"); vdevfn = libxl__xs_read(gc, XBT_NULL, path); - path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", - domid); + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/state"); if ( rc < 0 ) LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "qemu refused to add device: %s", vdevfn); @@ -1175,10 +1174,13 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libxl_ctx *ctx = libxl__gc_owner(gc); char *state; char *path; + uint32_t dm_domid; - path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid); + dm_domid = libxl_get_stubdom_id(CTX, domid); + + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/state"); state = libxl__xs_read(gc, XBT_NULL, path); - path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid); + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/parameter"); libxl__xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); @@ -1196,7 +1198,7 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, return ERROR_FAIL; } } - path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid); + path = libxl__device_model_xs_path(gc, dm_domid, domid, "/state"); xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state)); return 0;