Files
xen/xl-save-pc.patch
Charles Arnold 6335fb31bb - Update to Xen 4.21.0 FCS release
* The minimum toolchain requirements have increased for some architectures:
    - For x86, GCC 5.1 and Binutils 2.25, or Clang/LLVM 11
    - For ARM32 and ARM64, GCC 5.1 and Binutils 2.25
    - For RISC-V, GCC 12.2 and Binutils 2.39
  * Debian Trixie added to CI.  Debian Bullseye retired from CI for RISC-V due
    to the baseline change.
  * Linux based device model stubdomains are now fully supported.
  * New dependency on library json-c 0.15 or later, the toolstack will prefer it
    to `YAJL` when available.
  * Introduce libxenmanage as a stable library, replacing xenstored's
    dependency on unstable libraries.
  * Introduce new PDX compression algorithm to cope with Intel Sierra Forest and
    Granite Rapids having sparse memory maps.
  * Support of qemu-traditional has been removed.
  * The in-tree oxenstored is deprecated and will be removed in a future
    version of Xen.  It is moving into the Xapi project
    https://github.com/xapi-project/oxenstored so it can be maintained in line
    with the other Ocaml projects in the Xen ecosystem.
  * On x86:
    - Restrict the cache flushing done as a result of guest physical memory map
      manipulations and memory type changes.
    - Allow controlling the MTRR cache attribute of the Xen platform PCI device
      BAR for HVM guests, to improve performance of guests using it to map the
      grant table or foreign memory.
    - Allow configuring the number of altp2m tables per domain via vm.cfg.
    - Option to attempt to fixup p2m page-faults on PVH dom0.
    - Resizable BARs is supported for PVH dom0.
    - Support PCI passthrough for HVM domUs when dom0 is PVH (note SR-IOV
      capability usage is not yet supported on PVH dom0).

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=903
2025-11-19 18:50:34 +00:00

167 lines
5.7 KiB
Diff

References: bug#1176189
Usage of xl save -p|-c will suspend the domU.
As a result the monitoring xl process with get a LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN/LIBXL_SHUTDOWN_REASON_SUSPEND event.
This will cause it to exit because it does not know the -p/-c flags were used to keep the domU active.
As a result the final shutdown will not destroy the domU.
Write a flag to xenstore to let the monitoring process know about the usage of -p/-c.
Remove the flag once the suspend is done.
Recognize the flag in the monitoring process.
Keep going if the flag is seen.
Watch again for @releaseDomain events.
Keep going if the event type and shutdown reason remains the same.
---
tools/xl/Makefile | 3 ++-
tools/xl/xl.h | 1 +
tools/xl/xl_saverestore.c | 15 ++++++++++++
tools/xl/xl_vmcontrol.c | 48 +++++++++++++++++++++++++++++++++++++++
4 files changed, 66 insertions(+), 1 deletion(-)
--- a/tools/xl/Makefile
+++ b/tools/xl/Makefile
@@ -26,6 +26,7 @@ XL_OBJS += xl_vmcontrol.o xl_saverestore
XL_OBJS += xl_vdispl.o xl_vsnd.o xl_vkb.o
$(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog)
+$(XL_OBJS): CFLAGS += $(CFLAGS_libxenstore)
$(XL_OBJS): CFLAGS += $(CFLAGS_XL)
$(XL_OBJS): CFLAGS += -include $(XEN_ROOT)/tools/config.h # libxl_json.h needs it.
--- a/tools/xl/xl.h
+++ b/tools/xl/xl.h
@@ -306,6 +306,7 @@ typedef enum {
DOMAIN_RESTART_SUSPENDED, /* Domain suspended - keep looping */
} domain_restart_type;
+#define XL_SAVE_PAUSE_CHECKPOINT "suse-xl-save-pc"
extern void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh);
extern void apply_global_affinity_masks(libxl_domain_type type,
libxl_bitmap *vcpu_affinity_array,
--- a/tools/xl/xl_saverestore.c
+++ b/tools/xl/xl_saverestore.c
@@ -21,6 +21,7 @@
#include <time.h>
#include <unistd.h>
+#include <xenstore.h>
#include <libxl.h>
#include <libxl_utils.h>
#include <libxlutil.h>
@@ -127,6 +128,8 @@ static int save_domain(uint32_t domid, i
const char *filename, int checkpoint,
int leavepaused, const char *override_config_file)
{
+ struct xs_handle *xsh = NULL;
+ char path[80];
int fd;
uint8_t *config_data;
int config_len;
@@ -143,12 +146,24 @@ static int save_domain(uint32_t domid, i
fprintf(stderr, "Failed to open temp file %s for writing\n", filename);
exit(EXIT_FAILURE);
}
+ if (leavepaused || checkpoint)
+ {
+ snprintf(path, sizeof(path), "/libxl/%u/" XL_SAVE_PAUSE_CHECKPOINT, domid);
+ xsh = xs_open(0);
+ if (xsh)
+ xs_write(xsh, XBT_NULL, path, leavepaused ? "p" : "c", 1);
+ }
save_domain_core_writeconfig(fd, filename, config_data, config_len);
int rc = libxl_domain_suspend(ctx, domid, fd, 0, NULL);
close(fd);
+ if (xsh) {
+ xs_rm(xsh, XBT_NULL, path);
+ xs_close(xsh);
+ }
+
if (rc < 0) {
fprintf(stderr, "Failed to save domain, resuming domain\n");
libxl_domain_resume(ctx, domid, 1, 0);
--- a/tools/xl/xl_vmcontrol.c
+++ b/tools/xl/xl_vmcontrol.c
@@ -22,6 +22,7 @@
#include <time.h>
#include <unistd.h>
+#include <xenstore.h>
#include <libxl.h>
#include <libxl_utils.h>
#include <libxlutil.h>
@@ -706,6 +707,10 @@ int create_domain(struct domain_create *
int migrate_fd = dom_info->migrate_fd;
bool config_in_json;
+ libxl_event_type type = 0;
+ uint8_t shutdown_reason = 0;
+ bool is_in_suspend = false;
+
int i;
int need_daemon = daemonize;
int ret, rc;
@@ -1073,6 +1078,24 @@ start:
ret = domain_wait_event(domid, &event);
if (ret) goto out;
+ if (is_in_suspend) {
+ if ( type == event->type && event->u.domain_shutdown.shutdown_reason == shutdown_reason) {
+ struct timespec req = { .tv_nsec = 123456789, };
+ libxl_evdisable_domain_death(ctx, deathw);
+ deathw = NULL;
+ ret = libxl_evenable_domain_death(ctx, domid, 0, &deathw);
+ if (ret) goto out;
+ libxl_event_free(ctx, event);
+ LOG("Domain %u still suspended", domid);
+ nanosleep(&req, NULL);
+ continue;
+ }
+ is_in_suspend = false;
+ LOG("Domain %u left suspend state", domid);
+ }
+ type = event->type;
+ shutdown_reason = event->u.domain_shutdown.shutdown_reason;
+
switch (event->type) {
case LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN:
@@ -1134,10 +1157,34 @@ start:
goto start;
case DOMAIN_RESTART_NONE:
+ {
+ struct xs_handle *xsh = xs_open(0);
+
+ if (xsh) {
+ char path[80];
+ unsigned int len = 0;
+ char *val;
+
+ snprintf(path, sizeof(path), "/libxl/%u/" XL_SAVE_PAUSE_CHECKPOINT, domid);
+ val = xs_read(xsh, XBT_NULL, path, &len);
+ xs_close(xsh);
+ LOG("Got %p '%s' from %s, len %u", val, val ?:"", path, len);
+ free(val);
+ if (val)
+ {
+ is_in_suspend = true;
+ libxl_evdisable_domain_death(ctx, deathw);
+ deathw = NULL;
+ ret = libxl_evenable_domain_death(ctx, domid, 0, &deathw);
+ if (ret) goto out;
+ break;
+ }
+ }
LOG("Done. Exiting now");
libxl_event_free(ctx, event);
ret = 0;
goto out;
+ }
case DOMAIN_RESTART_SUSPENDED:
LOG("Continue waiting for domain %u", domid);