Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
src/qemu/qemu_driver.c | 22 +++++++++++++---------
src/qemu/qemu_migration.c | 2 +-
src/qemu/qemu_process.c | 20 ++++++++++++++++----
src/qemu/qemu_process.h | 3 +++
src/qemu/qemu_saveimage.c | 29 +++++++++++++++++++++++++----
src/qemu/qemu_saveimage.h | 4 +++-
src/qemu/qemu_snapshot.c | 8 ++++----
7 files changed, 65 insertions(+), 23 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 34f37210d9..53674458bf 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1624,7 +1624,7 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
}
if (qemuProcessStart(conn, driver, vm, NULL, VIR_ASYNC_JOB_START,
- NULL, -1, NULL, NULL,
+ NULL, -1, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
start_flags) < 0) {
virDomainAuditStart(vm, "booted", false);
@@ -5742,6 +5742,7 @@ qemuDomainRestoreInternal(virConnectPtr conn,
g_autofree char *xmlout = NULL;
const char *newxml = dxml;
int fd = -1;
+ int nondirectFd = -1;
int ret = -1;
virQEMUSaveData *data = NULL;
virFileWrapperFd *wrapperFd = NULL;
@@ -5758,7 +5759,7 @@ qemuDomainRestoreInternal(virConnectPtr conn,
fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
(flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
- &wrapperFd, false, false);
+ &wrapperFd, &nondirectFd, false, false);
if (fd < 0)
goto cleanup;
@@ -5812,13 +5813,14 @@ qemuDomainRestoreInternal(virConnectPtr conn,
if (qemuProcessBeginJob(vm, VIR_DOMAIN_JOB_OPERATION_RESTORE, flags) < 0)
goto cleanup;
- ret = qemuSaveImageStartVM(conn, driver, vm, &fd, data, path,
+ ret = qemuSaveImageStartVM(conn, driver, vm, &fd, nondirectFd, data, path,
false, reset_nvram, VIR_ASYNC_JOB_START);
qemuProcessEndJob(vm);
cleanup:
VIR_FORCE_CLOSE(fd);
+ VIR_FORCE_CLOSE(nondirectFd);
if (virFileWrapperFdClose(wrapperFd) < 0)
ret = -1;
virFileWrapperFdFree(wrapperFd);
@@ -5893,7 +5895,7 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path,
virCheckFlags(VIR_DOMAIN_SAVE_IMAGE_XML_SECURE, NULL);
fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
- false, NULL, false, false);
+ false, NULL, NULL, false, false);
if (fd < 0)
goto cleanup;
@@ -5930,7 +5932,7 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path,
state = 0;
fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
- false, NULL, true, false);
+ false, NULL, NULL, true, false);
if (fd < 0)
goto cleanup;
@@ -6011,7 +6013,7 @@ qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom, unsigned int
flags)
}
if ((fd = qemuSaveImageOpen(driver, priv->qemuCaps, path, &def, &data,
- false, NULL, false, false)) < 0)
+ false, NULL, NULL, false, false)) < 0)
goto cleanup;
ret = qemuDomainDefFormatXML(driver, priv->qemuCaps, def, flags);
@@ -6069,13 +6071,14 @@ qemuDomainObjRestore(virConnectPtr conn,
g_autoptr(virDomainDef) def = NULL;
qemuDomainObjPrivate *priv = vm->privateData;
int fd = -1;
+ int nondirectFd = -1;
int ret = -1;
g_autofree char *xmlout = NULL;
virQEMUSaveData *data = NULL;
virFileWrapperFd *wrapperFd = NULL;
fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
- bypass_cache, &wrapperFd, false, true);
+ bypass_cache, &wrapperFd, &nondirectFd, false, true);
if (fd < 0) {
if (fd == -3)
ret = 1;
@@ -6120,12 +6123,13 @@ qemuDomainObjRestore(virConnectPtr conn,
virDomainObjAssignDef(vm, &def, true, NULL);
- ret = qemuSaveImageStartVM(conn, driver, vm, &fd, data, path,
+ ret = qemuSaveImageStartVM(conn, driver, vm, &fd, nondirectFd, data, path,
start_paused, reset_nvram, asyncJob);
cleanup:
virQEMUSaveDataFree(data);
VIR_FORCE_CLOSE(fd);
+ VIR_FORCE_CLOSE(nondirectFd);
if (virFileWrapperFdClose(wrapperFd) < 0)
ret = -1;
virFileWrapperFdFree(wrapperFd);
@@ -6321,7 +6325,7 @@ qemuDomainObjStart(virConnectPtr conn,
}
ret = qemuProcessStart(conn, driver, vm, NULL, asyncJob,
- NULL, -1, NULL, NULL,
+ NULL, -1, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags);
virDomainAuditStart(vm, "booted", ret >= 0);
if (ret >= 0) {
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index a0435a0572..0b1e03394e 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3009,7 +3009,7 @@ qemuMigrationDstPrepare(virDomainObj *vm,
}
return qemuProcessIncomingDefNew(vm, listenAddress,
- migrateFrom, fd, NULL, 0);
+ migrateFrom, fd, -1, NULL, 0);
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f700390a8c..f5b2f9ea2b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4688,6 +4688,7 @@ qemuProcessIncomingDefNew(virDomainObj *vm,
const char *listenAddress,
const char *migrateFrom,
int fd,
+ int nondirectFd,
const char *path,
unsigned int flags)
{
@@ -4707,11 +4708,18 @@ qemuProcessIncomingDefNew(virDomainObj *vm,
unsigned int fdsetId;
off_t offset;
- if ((offset = lseek(fd, 0, SEEK_CUR)) == -1)
- offset = 0;
+ if (nondirectFd == -1)
+ offset = lseek(fd, 0, SEEK_CUR);
+ else
+ offset = lseek(nondirectFd, 0, SEEK_CUR);
+
+ if (offset < 0)
+ goto error;
inc->fdPassMigrate = qemuFDPassNew("migrate", priv);
qemuFDPassAddFD(inc->fdPassMigrate, &fd, "-fd");
+ if (nondirectFd != -1)
+ qemuFDPassAddFD(inc->fdPassMigrate, &nondirectFd,
"-nondirect-fd");
qemuFDPassGetId(inc->fdPassMigrate, &fdsetId);
inc->uri = g_strdup_printf("file:/dev/fdset/%u,offset=%#lx",
fdsetId, offset);
} else {
@@ -8148,6 +8156,7 @@ qemuProcessStart(virConnectPtr conn,
virDomainAsyncJob asyncJob,
const char *migrateFrom,
int migrateFd,
+ int migrateNondirectFd,
const char *migratePath,
virDomainMomentObj *snapshot,
virNetDevVPortProfileOp vmop,
@@ -8185,7 +8194,8 @@ qemuProcessStart(virConnectPtr conn,
if (migrateFrom) {
incoming = qemuProcessIncomingDefNew(vm, NULL, migrateFrom,
- migrateFd, migratePath, flags);
+ migrateFd, migrateNondirectFd,
+ migratePath, flags);
if (!incoming)
goto stop;
}
@@ -8264,6 +8274,7 @@ qemuProcessStart(virConnectPtr conn,
* @driver: qemu driver object
* @vm: domain object
* @fd: FD pointer of memory state file
+ * @nondirectFd: FD for memory state file, opened without O_DIRECT
* @path: path to memory state file
* @snapshot: internal snapshot to load when starting QEMU process or NULL
* @data: data from memory state file or NULL
@@ -8290,6 +8301,7 @@ qemuProcessStartWithMemoryState(virConnectPtr conn,
virQEMUDriver *driver,
virDomainObj *vm,
int *fd,
+ int nondirectFd,
const char *path,
virDomainMomentObj *snapshot,
virQEMUSaveData *data,
@@ -8329,7 +8341,7 @@ qemuProcessStartWithMemoryState(virConnectPtr conn,
priv->disableSlirp = true;
if (qemuProcessStart(conn, driver, vm, cookie ? cookie->cpu : NULL,
- asyncJob, migrateFrom, *fd, path, snapshot,
+ asyncJob, migrateFrom, *fd, nondirectFd, path, snapshot,
VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
start_flags) == 0)
*started = true;
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index a5212ee56e..6e37dac2ca 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -62,6 +62,7 @@ qemuProcessIncomingDef *qemuProcessIncomingDefNew(virDomainObj *vm,
const char *listenAddress,
const char *migrateFrom,
int fd,
+ int nondirectFd,
const char *path,
unsigned int flags);
void qemuProcessIncomingDefFree(qemuProcessIncomingDef *inc);
@@ -89,6 +90,7 @@ int qemuProcessStart(virConnectPtr conn,
virDomainAsyncJob asyncJob,
const char *migrateFrom,
int stdin_fd,
+ int nondirectFd,
const char *stdin_path,
virDomainMomentObj *snapshot,
virNetDevVPortProfileOp vmop,
@@ -98,6 +100,7 @@ int qemuProcessStartWithMemoryState(virConnectPtr conn,
virQEMUDriver *driver,
virDomainObj *vm,
int *fd,
+ int nondirectFd,
const char *path,
virDomainMomentObj *snapshot,
virQEMUSaveData *data,
diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c
index 2b0281895a..8e634862a6 100644
--- a/src/qemu/qemu_saveimage.c
+++ b/src/qemu/qemu_saveimage.c
@@ -610,6 +610,7 @@ qemuSaveImageGetCompressionProgram(const char *imageFormat,
* @ret_data: returns structure filled with data from the image header
* @bypass_cache: bypass cache when opening the file
* @wrapperFd: returns the file wrapper structure
+ * @nondirectFd: returns file descriptor without O_DIRECT set
* @open_write: open the file for writing (for updates)
* @unlink_corrupt: remove the image file if it is corrupted
*
@@ -625,11 +626,14 @@ qemuSaveImageOpen(virQEMUDriver *driver,
virQEMUSaveData **ret_data,
bool bypass_cache,
virFileWrapperFd **wrapperFd,
+ int *nondirectFd,
bool open_write,
bool unlink_corrupt)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
VIR_AUTOCLOSE fd = -1;
+ VIR_AUTOCLOSE nondirect_fd = -1;
+ int read_fd;
int ret = -1;
g_autoptr(virQEMUSaveData) data = NULL;
virQEMUSaveHeader *header;
@@ -646,6 +650,13 @@ qemuSaveImageOpen(virQEMUDriver *driver,
_("bypass cache unsupported by this system"));
return -1;
}
+
+ /* Also open the file without O_DIRECT for reading header and for
+ * qemu to use when reading unaligned state
+ */
+ if ((nondirect_fd = qemuDomainOpenFile(cfg, NULL, path, oflags, NULL)) < 0)
+ return -1;
+
oflags |= directFlag;
}
@@ -655,7 +666,12 @@ qemuSaveImageOpen(virQEMUDriver *driver,
data = g_new0(virQEMUSaveData, 1);
header = &data->header;
- if (saferead(fd, header, sizeof(*header)) != sizeof(*header)) {
+ if (nondirect_fd != -1)
+ read_fd = nondirect_fd;
+ else
+ read_fd = fd;
+
+ if (saferead(read_fd, header, sizeof(*header)) != sizeof(*header)) {
if (unlink_corrupt) {
if (unlink(path) < 0) {
virReportSystemError(errno,
@@ -732,7 +748,7 @@ qemuSaveImageOpen(virQEMUDriver *driver,
data->xml = g_new0(char, xml_len);
- if (saferead(fd, data->xml, xml_len) != xml_len) {
+ if (saferead(read_fd, data->xml, xml_len) != xml_len) {
virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("failed to read domain XML"));
return -1;
@@ -741,7 +757,7 @@ qemuSaveImageOpen(virQEMUDriver *driver,
if (cookie_len > 0) {
data->cookie = g_new0(char, cookie_len);
- if (saferead(fd, data->cookie, cookie_len) != cookie_len) {
+ if (saferead(read_fd, data->cookie, cookie_len) != cookie_len) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("failed to read cookie"));
return -1;
@@ -761,6 +777,10 @@ qemuSaveImageOpen(virQEMUDriver *driver,
*ret_def = g_steal_pointer(&def);
*ret_data = g_steal_pointer(&data);
+ if (nondirectFd) {
+ *nondirectFd = nondirect_fd;
+ nondirect_fd = -1;
+ }
ret = fd;
fd = -1;
@@ -774,6 +794,7 @@ qemuSaveImageStartVM(virConnectPtr conn,
virQEMUDriver *driver,
virDomainObj *vm,
int *fd,
+ int nondirectFd,
virQEMUSaveData *data,
const char *path,
bool start_paused,
@@ -794,7 +815,7 @@ qemuSaveImageStartVM(virConnectPtr conn,
if (header->features & QEMU_SAVE_FEATURE_MAPPED_RAM)
start_flags |= VIR_QEMU_PROCESS_START_MAPPED_RAM;
- if (qemuProcessStartWithMemoryState(conn, driver, vm, fd, path, NULL, data,
+ if (qemuProcessStartWithMemoryState(conn, driver, vm, fd, nondirectFd, path, NULL,
data,
asyncJob, start_flags, "restored",
&started) < 0) {
goto cleanup;
diff --git a/src/qemu/qemu_saveimage.h b/src/qemu/qemu_saveimage.h
index 81d93bf33c..0a8b35158a 100644
--- a/src/qemu/qemu_saveimage.h
+++ b/src/qemu/qemu_saveimage.h
@@ -67,12 +67,13 @@ qemuSaveImageStartVM(virConnectPtr conn,
virQEMUDriver *driver,
virDomainObj *vm,
int *fd,
+ int nondirectFd,
virQEMUSaveData *data,
const char *path,
bool start_paused,
bool reset_nvram,
virDomainAsyncJob asyncJob)
- ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6);
+ ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(6) ATTRIBUTE_NONNULL(7);
int
qemuSaveImageOpen(virQEMUDriver *driver,
@@ -82,6 +83,7 @@ qemuSaveImageOpen(virQEMUDriver *driver,
virQEMUSaveData **ret_data,
bool bypass_cache,
virFileWrapperFd **wrapperFd,
+ int *nondirectFd,
bool open_write,
bool unlink_corrupt)
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 1e9e0e31d7..f137a79a8d 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -2115,7 +2115,7 @@ qemuSnapshotRevertExternalPrepare(virDomainObj *vm,
memdata->path = snapdef->memorysnapshotfile;
memdata->fd = qemuSaveImageOpen(driver, NULL, memdata->path,
&savedef, &memdata->data,
- false, NULL,
+ false, NULL, NULL,
false, false);
if (memdata->fd < 0)
@@ -2359,7 +2359,7 @@ qemuSnapshotRevertActive(virDomainObj *vm,
virDomainObjAssignDef(vm, config, true, NULL);
if (qemuProcessStartWithMemoryState(snapshot->domain->conn, driver, vm,
- &memdata.fd, memdata.path, loadSnap,
+ &memdata.fd, -1, memdata.path, loadSnap,
memdata.data, VIR_ASYNC_JOB_SNAPSHOT,
start_flags, "from-snapshot",
&started) < 0) {
@@ -2513,7 +2513,7 @@ qemuSnapshotRevertInactive(virDomainObj *vm,
start_flags |= paused ? VIR_QEMU_PROCESS_START_PAUSED : 0;
rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL,
- VIR_ASYNC_JOB_SNAPSHOT, NULL, -1, NULL, NULL,
+ VIR_ASYNC_JOB_SNAPSHOT, NULL, -1, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
start_flags);
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
@@ -2991,7 +2991,7 @@ qemuSnapshotDeleteExternalPrepare(virDomainObj *vm,
if (!virDomainObjIsActive(vm)) {
if (qemuProcessStart(NULL, driver, vm, NULL, VIR_ASYNC_JOB_SNAPSHOT,
- NULL, -1, NULL, NULL,
+ NULL, -1, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
VIR_QEMU_PROCESS_START_PAUSED) < 0) {
return -1;
--
2.44.0