2022-09-02 00:07:34 +02:00
|
|
|
From 914c37ca3f0af956e69179d49e87e8390560c2b3 Mon Sep 17 00:00:00 2001
|
2018-07-16 18:42:10 +02:00
|
|
|
From: Jim Fehlig <jfehlig@suse.com>
|
2022-09-02 00:07:34 +02:00
|
|
|
Date: Tue, 5 Jul 2022 11:36:37 -0600
|
|
|
|
Subject: libxl: add support for BlockResize API
|
2018-07-16 18:42:10 +02:00
|
|
|
|
|
|
|
Add support in the libxl driver for the BlockResize API. Use libxl's
|
|
|
|
libxl_qemu_monitor_command API to issue the block_resize command to qemu.
|
|
|
|
|
|
|
|
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
|
|
|
|
---
|
2022-09-02 00:07:34 +02:00
|
|
|
src/libxl/libxl_api_wrapper.h | 15 ++++++
|
|
|
|
src/libxl/libxl_driver.c | 90 +++++++++++++++++++++++++++++++++++
|
|
|
|
2 files changed, 105 insertions(+)
|
2018-07-16 18:42:10 +02:00
|
|
|
|
2022-09-02 00:07:34 +02:00
|
|
|
Index: libvirt-8.7.0/src/libxl/libxl_api_wrapper.h
|
|
|
|
===================================================================
|
|
|
|
--- libvirt-8.7.0.orig/src/libxl/libxl_api_wrapper.h
|
|
|
|
+++ libvirt-8.7.0/src/libxl/libxl_api_wrapper.h
|
|
|
|
@@ -215,3 +215,18 @@ libxlSetMemoryTargetWrapper(libxl_ctx *c
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+static inline int
|
|
|
|
+libxlQemuMonitorCommandWrapper(libxl_ctx *ctx, uint32_t domid,
|
|
|
|
+ const char *command_line, char **output)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+#if LIBXL_API_VERSION < 0x041300
|
|
|
|
+ ret = libxl_qemu_monitor_command(ctx, domid, command_line, output);
|
|
|
|
+#else
|
|
|
|
+ ret = libxl_qemu_monitor_command(ctx, domid, command_line, output, NULL);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
Index: libvirt-8.7.0/src/libxl/libxl_driver.c
|
2018-07-16 18:42:10 +02:00
|
|
|
===================================================================
|
2022-09-02 00:07:34 +02:00
|
|
|
--- libvirt-8.7.0.orig/src/libxl/libxl_driver.c
|
|
|
|
+++ libvirt-8.7.0/src/libxl/libxl_driver.c
|
2022-07-06 19:18:39 +02:00
|
|
|
@@ -5257,6 +5257,95 @@ libxlDomainMemoryStats(virDomainPtr dom,
|
2018-07-16 18:42:10 +02:00
|
|
|
|
|
|
|
#undef LIBXL_SET_MEMSTAT
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Resize a block device while a guest is running. Resize to a lower size
|
|
|
|
+ * is supported, but should be used with extreme caution. Note that it
|
|
|
|
+ * only supports to resize image files, it can't resize block devices
|
|
|
|
+ * like LVM volumes.
|
|
|
|
+ */
|
|
|
|
+static int
|
|
|
|
+libxlDomainBlockResize(virDomainPtr dom,
|
|
|
|
+ const char *path,
|
|
|
|
+ unsigned long long size,
|
|
|
|
+ unsigned int flags)
|
|
|
|
+{
|
2021-05-18 00:14:02 +02:00
|
|
|
+ libxlDriverPrivate *driver = dom->conn->privateData;
|
|
|
|
+ libxlDriverConfig *cfg;
|
|
|
|
+ virDomainObj *vm;
|
2018-07-16 18:42:10 +02:00
|
|
|
+ int ret = -1;
|
2021-05-18 00:14:02 +02:00
|
|
|
+ virDomainDiskDef *disk = NULL;
|
2021-07-01 19:24:26 +02:00
|
|
|
+ g_autofree char *moncmd = NULL;
|
|
|
|
+ g_autofree char *monreply = NULL;
|
2018-07-16 18:42:10 +02:00
|
|
|
+
|
|
|
|
+ virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES, -1);
|
|
|
|
+
|
|
|
|
+ if (path[0] == '\0') {
|
|
|
|
+ virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
+ "%s", _("empty path"));
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* We prefer operating on bytes. */
|
|
|
|
+ if ((flags & VIR_DOMAIN_BLOCK_RESIZE_BYTES) == 0) {
|
|
|
|
+ if (size > ULLONG_MAX / 1024) {
|
|
|
|
+ virReportError(VIR_ERR_OVERFLOW,
|
|
|
|
+ _("size must be less than %llu"),
|
|
|
|
+ ULLONG_MAX / 1024);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ size *= 1024;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cfg = libxlDriverConfigGet(driver);
|
|
|
|
+ if (!(vm = libxlDomObjFromDomain(dom)))
|
|
|
|
+ goto cleanup;
|
|
|
|
+
|
|
|
|
+ if (virDomainBlockResizeEnsureACL(dom->conn, vm->def) < 0)
|
|
|
|
+ goto cleanup;
|
|
|
|
+
|
2022-04-02 00:35:43 +02:00
|
|
|
+ if (libxlDomainObjBeginJob(driver, vm, VIR_JOB_MODIFY) < 0)
|
2018-07-16 18:42:10 +02:00
|
|
|
+ goto cleanup;
|
|
|
|
+
|
|
|
|
+ if (!virDomainObjIsActive(vm)) {
|
|
|
|
+ virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
+ "%s", _("domain is not running"));
|
|
|
|
+ goto endjob;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!(disk = virDomainDiskByName(vm->def, path, false))) {
|
|
|
|
+ virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
+ _("invalid path: %s"), path);
|
|
|
|
+ goto endjob;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* qcow2 and qed must be sized on 512 byte blocks/sectors,
|
|
|
|
+ * so adjust size if necessary to round up.
|
|
|
|
+ */
|
|
|
|
+ if (disk->src->format == VIR_STORAGE_FILE_QCOW2 ||
|
|
|
|
+ disk->src->format == VIR_STORAGE_FILE_QED)
|
|
|
|
+ size = VIR_ROUND_UP(size, 512);
|
|
|
|
+
|
2019-12-03 05:35:26 +01:00
|
|
|
+ moncmd = g_strdup_printf("block_resize %s %lluB", disk->dst, size);
|
2018-07-16 18:42:10 +02:00
|
|
|
+
|
2021-05-18 00:14:02 +02:00
|
|
|
+ if (libxlQemuMonitorCommandWrapper(cfg->ctx, vm->def->id,
|
|
|
|
+ moncmd, &monreply) != 0) {
|
2018-07-16 18:42:10 +02:00
|
|
|
+ virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
+ _("block_resize command failed for device '%s' on domain '%d'"),
|
|
|
|
+ disk->dst, vm->def->id);
|
|
|
|
+ goto endjob;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = 0;
|
|
|
|
+
|
|
|
|
+ endjob:
|
|
|
|
+ libxlDomainObjEndJob(driver, vm);
|
|
|
|
+
|
|
|
|
+ cleanup:
|
|
|
|
+ virDomainObjEndAPI(&vm);
|
|
|
|
+ virObjectUnref(cfg);
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static int
|
|
|
|
libxlDomainGetJobInfo(virDomainPtr dom,
|
|
|
|
virDomainJobInfoPtr info)
|
2022-07-06 19:18:39 +02:00
|
|
|
@@ -6583,6 +6672,7 @@ static virHypervisorDriver libxlHypervis
|
2021-07-01 19:24:26 +02:00
|
|
|
.domainGetNumaParameters = libxlDomainGetNumaParameters, /* 1.1.1 */
|
2018-07-16 18:42:10 +02:00
|
|
|
.nodeGetFreeMemory = libxlNodeGetFreeMemory, /* 0.9.0 */
|
|
|
|
.nodeGetCellsFreeMemory = libxlNodeGetCellsFreeMemory, /* 1.1.1 */
|
|
|
|
+ .domainBlockResize = libxlDomainBlockResize, /* 4.2.0 */
|
|
|
|
.domainGetJobInfo = libxlDomainGetJobInfo, /* 1.3.1 */
|
|
|
|
.domainGetJobStats = libxlDomainGetJobStats, /* 1.3.1 */
|
|
|
|
.domainMemoryStats = libxlDomainMemoryStats, /* 1.3.0 */
|