* Wed Mar 11 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-14.el8

- kvm-hw-smbios-set-new-default-SMBIOS-fields-for-Windows-.patch [bz#1782529]
- kvm-migration-multifd-clean-pages-after-filling-packet.patch [bz#1738451]
- kvm-migration-Make-sure-that-we-don-t-call-write-in-case.patch [bz#1738451]
- kvm-migration-multifd-fix-nullptr-access-in-terminating-.patch [bz#1738451]
- kvm-migration-multifd-fix-destroyed-mutex-access-in-term.patch [bz#1738451]
- kvm-multifd-Make-sure-that-we-don-t-do-any-IO-after-an-e.patch [bz#1738451]
- kvm-qemu-file-Don-t-do-IO-after-shutdown.patch [bz#1738451]
- kvm-migration-Don-t-send-data-if-we-have-stopped.patch [bz#1738451]
- kvm-migration-Create-migration_is_running.patch [bz#1738451]
- kvm-migration-multifd-fix-nullptr-access-in-multifd_send.patch [bz#1738451]
- kvm-migration-Maybe-VM-is-paused-when-migration-is-cance.patch [bz#1738451]
- kvm-virtiofsd-Remove-fuse_req_getgroups.patch [bz#1797064]
- kvm-virtiofsd-fv_create_listen_socket-error-path-socket-.patch [bz#1797064]
- kvm-virtiofsd-load_capng-missing-unlock.patch [bz#1797064]
- kvm-virtiofsd-do_read-missing-NULL-check.patch [bz#1797064]
- kvm-tools-virtiofsd-fuse_lowlevel-Fix-fuse_out_header-er.patch [bz#1797064]
- kvm-virtiofsd-passthrough_ll-cleanup-getxattr-listxattr.patch [bz#1797064]
- kvm-virtiofsd-Fix-xattr-operations.patch [bz#1797064]
- Resolves: bz#1738451
  (qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel))
- Resolves: bz#1782529
  (Windows Update Enablement with default smbios strings in qemu)
- Resolves: bz#1797064
  (virtiofsd: Fixes)
This commit is contained in:
Danilo C. L. de Paula 2020-03-11 20:25:54 +00:00
parent 2084aa0246
commit cb4ea43665
19 changed files with 1981 additions and 1 deletions

View File

@ -0,0 +1,262 @@
From e6c3fbfc82863180007569cf2a9132c28a47bf1f Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Mon, 20 Jan 2020 16:13:08 +0000
Subject: [PATCH 01/18] hw/smbios: set new default SMBIOS fields for Windows
driver support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Daniel P. Berrange <berrange@redhat.com>
Message-id: <20200120161308.584989-2-berrange@redhat.com>
Patchwork-id: 93422
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 1/1] hw/smbios: set new default SMBIOS fields for Windows driver support
Bugzilla: 1782529
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
For Windows driver support, we have to follow this doc in order to
enable Windows to automatically determine the right drivers to install
for a given guest / host combination:
https://docs.microsoft.com/en-us/windows-hardware/drivers/install/specifying-hardware-ids-for-a-computer
Out of the choices available, it was decided that the Windows drivers
will be written to expect use of the scheme documented as "HardwareID-6"
against Windows 10. This uses SMBIOS System (Type 1) and Base Board
(Type 2) tables and will match on
System Manufacturer = Red Hat
System SKU Number = 8.2.0
Baseboard Manufacturer = Red Hat
Baseboard Product = RHEL-AV
The new SMBIOS fields will be tied to machine type and only reported for
pc-q35-8.2.0 machine and later.
The old SMBIOS fields, previously reported by all machines were:
System Manufacturer: Red Hat
System Product Name: KVM
System Version: RHEL-8.2.0 PC (Q35 + ICH9, 2009)
System Family: Red Hat Enterprise Linux
Baseboard Manufacturer: Red Hat
Baseboard Product Name: KVM
Baseboard Version: RHEL-8.2.0 PC (Q35 + ICH9, 2009)
Chassis Manufacturer: Red Hat
Chassis Product Name: KVM
Chassis Version: RHEL-8.2.0 PC (Q35 + ICH9, 2009)
Processor Manufacturer: Red Hat
Processor Product Name: KVM
Processor Version: RHEL-8.2.0 PC (Q35 + ICH9, 2009)
This information will continue to be reported for all machines, except
where it conflicts with the requirement of the new SMBIOS data. IOW,
the "Baseboard Product Name" will change to "RHEL-AV" for pc-q35-8.2.0
machine types and later.
Management applications MUST NEVER override the 4 new SMBIOS fields that
are used for Windows driver matching, with differing values. Aside from
this, they are free to override any other field, including those from
the old SMBIOS field data.
In particular if a management application wants to report its own
product name and version, it is recommended to use "System product"
and "System version" as identifying fields, as these avoid a clash with
the new SMBIOS fields used for Windows drivers.
Note that until now the Baseboard (type 2) table has only been generated
by QEMU if explicitly asked for on the CLI. This patch makes it always
present for new machine types.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
hw/arm/virt.c | 2 +-
hw/i386/pc_piix.c | 2 ++
hw/i386/pc_q35.c | 8 ++++++++
hw/smbios/smbios.c | 45 +++++++++++++++++++++++++++++++++++++++++---
include/hw/firmware/smbios.h | 5 ++++-
include/hw/i386/pc.h | 3 +++
6 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d30d38c..2dcf6e7 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1423,7 +1423,7 @@ static void virt_build_smbios(VirtMachineState *vms)
smbios_set_defaults("QEMU", product,
vmc->smbios_old_sys_ver ? "1.0" : mc->name, false,
- true, SMBIOS_ENTRY_POINT_30);
+ true, NULL, NULL, SMBIOS_ENTRY_POINT_30);
smbios_get_tables(MACHINE(vms), NULL, 0, &smbios_tables, &smbios_tables_len,
&smbios_anchor, &smbios_anchor_len);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index bd7fdb9..2ac94d5 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -177,6 +177,8 @@ static void pc_init1(MachineState *machine,
smbios_set_defaults("Red Hat", "KVM",
mc->desc, pcmc->smbios_legacy_mode,
pcmc->smbios_uuid_encoded,
+ pcmc->smbios_stream_product,
+ pcmc->smbios_stream_version,
SMBIOS_ENTRY_POINT_21);
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 7531d8e..e975643 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -200,6 +200,8 @@ static void pc_q35_init(MachineState *machine)
smbios_set_defaults("Red Hat", "KVM",
mc->desc, pcmc->smbios_legacy_mode,
pcmc->smbios_uuid_encoded,
+ pcmc->smbios_stream_product,
+ pcmc->smbios_stream_version,
SMBIOS_ENTRY_POINT_21);
}
@@ -565,8 +567,11 @@ static void pc_q35_init_rhel820(MachineState *machine)
static void pc_q35_machine_rhel820_options(MachineClass *m)
{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_q35_machine_rhel_options(m);
m->desc = "RHEL-8.2.0 PC (Q35 + ICH9, 2009)";
+ pcmc->smbios_stream_product = "RHEL-AV";
+ pcmc->smbios_stream_version = "8.2.0";
}
DEFINE_PC_MACHINE(q35_rhel820, "pc-q35-rhel8.2.0", pc_q35_init_rhel820,
@@ -579,9 +584,12 @@ static void pc_q35_init_rhel810(MachineState *machine)
static void pc_q35_machine_rhel810_options(MachineClass *m)
{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_q35_machine_rhel820_options(m);
m->desc = "RHEL-8.1.0 PC (Q35 + ICH9, 2009)";
m->alias = NULL;
+ pcmc->smbios_stream_product = NULL;
+ pcmc->smbios_stream_version = NULL;
compat_props_add(m->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len);
compat_props_add(m->compat_props, pc_rhel_8_1_compat, pc_rhel_8_1_compat_len);
}
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index e6e9355..d65c149 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -57,6 +57,9 @@ static bool smbios_legacy = true;
static bool smbios_uuid_encoded = true;
/* end: legacy structures & constants for <= 2.0 machines */
+/* Set to true for modern Windows 10 HardwareID-6 compat */
+static bool smbios_type2_required;
+
uint8_t *smbios_tables;
size_t smbios_tables_len;
@@ -532,7 +535,7 @@ static void smbios_build_type_1_table(void)
static void smbios_build_type_2_table(void)
{
- SMBIOS_BUILD_TABLE_PRE(2, 0x200, false); /* optional */
+ SMBIOS_BUILD_TABLE_PRE(2, 0x200, smbios_type2_required);
SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer);
SMBIOS_TABLE_SET_STR(2, product_str, type2.product);
@@ -753,7 +756,10 @@ void smbios_set_cpuid(uint32_t version, uint32_t features)
void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version, bool legacy_mode,
- bool uuid_encoded, SmbiosEntryPointType ep_type)
+ bool uuid_encoded,
+ const char *stream_product,
+ const char *stream_version,
+ SmbiosEntryPointType ep_type)
{
smbios_have_defaults = true;
smbios_legacy = legacy_mode;
@@ -774,12 +780,45 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
g_free(smbios_entries);
}
+ /*
+ * If @stream_product & @stream_version are non-NULL, then
+ * we're following rules for new Windows driver support.
+ * The data we have to report is defined in this doc:
+ *
+ * https://docs.microsoft.com/en-us/windows-hardware/drivers/install/specifying-hardware-ids-for-a-computer
+ *
+ * The Windows drivers are written to expect use of the
+ * scheme documented as "HardwareID-6" against Windows 10,
+ * which uses SMBIOS System (Type 1) and Base Board (Type 2)
+ * tables and will match on
+ *
+ * System Manufacturer = Red Hat (@manufacturer)
+ * System SKU Number = 8.2.0 (@stream_version)
+ * Baseboard Manufacturer = Red Hat (@manufacturer)
+ * Baseboard Product = RHEL-AV (@stream_product)
+ *
+ * NB, SKU must be changed with each RHEL-AV release
+ *
+ * Other fields can be freely used by applications using
+ * QEMU. For example apps can use the "System product"
+ * and "System version" to identify themselves.
+ *
+ * We get 'System Manufacturer' and 'Baseboard Manufacturer'
+ */
SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
SMBIOS_SET_DEFAULT(type1.product, product);
SMBIOS_SET_DEFAULT(type1.version, version);
SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux");
+ if (stream_version != NULL) {
+ SMBIOS_SET_DEFAULT(type1.sku, stream_version);
+ }
SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
- SMBIOS_SET_DEFAULT(type2.product, product);
+ if (stream_product != NULL) {
+ SMBIOS_SET_DEFAULT(type2.product, stream_product);
+ smbios_type2_required = true;
+ } else {
+ SMBIOS_SET_DEFAULT(type2.product, product);
+ }
SMBIOS_SET_DEFAULT(type2.version, version);
SMBIOS_SET_DEFAULT(type3.manufacturer, manufacturer);
SMBIOS_SET_DEFAULT(type3.version, version);
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 02a0ced..67e38a1 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -267,7 +267,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp);
void smbios_set_cpuid(uint32_t version, uint32_t features);
void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version, bool legacy_mode,
- bool uuid_encoded, SmbiosEntryPointType ep_type);
+ bool uuid_encoded,
+ const char *stream_product,
+ const char *stream_version,
+ SmbiosEntryPointType ep_type);
uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length);
void smbios_get_tables(MachineState *ms,
const struct smbios_phys_mem_area *mem_array,
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 2e362c8..b9f29ba 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -109,6 +109,9 @@ typedef struct PCMachineClass {
bool smbios_defaults;
bool smbios_legacy_mode;
bool smbios_uuid_encoded;
+ /* New fields needed for Windows HardwareID-6 matching */
+ const char *smbios_stream_product;
+ const char *smbios_stream_version;
/* RAM / address space compat: */
bool gigabyte_align;
--
1.8.3.1

View File

@ -0,0 +1,119 @@
From c9e3d13d70a24bf606ce351886b27bdca25ef4dc Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:41 +0000
Subject: [PATCH 09/18] migration: Create migration_is_running()
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-9-quintela@redhat.com>
Patchwork-id: 94115
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 08/10] migration: Create migration_is_running()
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This function returns true if we are in the middle of a migration.
It is like migration_is_setup_or_active() with CANCELLING and COLO.
Adapt all callers that are needed.
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit 392d87e21325fdb01210176faa07472b4985ccf0)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/migration.c | 29 ++++++++++++++++++++++++-----
migration/migration.h | 1 +
migration/savevm.c | 4 +---
3 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 30c53c6..eb50d77 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -831,6 +831,27 @@ bool migration_is_setup_or_active(int state)
}
}
+bool migration_is_running(int state)
+{
+ switch (state) {
+ case MIGRATION_STATUS_ACTIVE:
+ case MIGRATION_STATUS_POSTCOPY_ACTIVE:
+ case MIGRATION_STATUS_POSTCOPY_PAUSED:
+ case MIGRATION_STATUS_POSTCOPY_RECOVER:
+ case MIGRATION_STATUS_SETUP:
+ case MIGRATION_STATUS_PRE_SWITCHOVER:
+ case MIGRATION_STATUS_DEVICE:
+ case MIGRATION_STATUS_WAIT_UNPLUG:
+ case MIGRATION_STATUS_CANCELLING:
+ case MIGRATION_STATUS_COLO:
+ return true;
+
+ default:
+ return false;
+
+ }
+}
+
static void populate_time_info(MigrationInfo *info, MigrationState *s)
{
info->has_status = true;
@@ -1090,7 +1111,7 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
MigrationCapabilityStatusList *cap;
bool cap_list[MIGRATION_CAPABILITY__MAX];
- if (migration_is_setup_or_active(s->state)) {
+ if (migration_is_running(s->state)) {
error_setg(errp, QERR_MIGRATION_ACTIVE);
return;
}
@@ -1603,7 +1624,7 @@ static void migrate_fd_cancel(MigrationState *s)
do {
old_state = s->state;
- if (!migration_is_setup_or_active(old_state)) {
+ if (!migration_is_running(old_state)) {
break;
}
/* If the migration is paused, kick it out of the pause */
@@ -1900,9 +1921,7 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
return true;
}
- if (migration_is_setup_or_active(s->state) ||
- s->state == MIGRATION_STATUS_CANCELLING ||
- s->state == MIGRATION_STATUS_COLO) {
+ if (migration_is_running(s->state)) {
error_setg(errp, QERR_MIGRATION_ACTIVE);
return false;
}
diff --git a/migration/migration.h b/migration/migration.h
index 0b1b0d4..a2b2336 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -279,6 +279,7 @@ void migrate_fd_error(MigrationState *s, const Error *error);
void migrate_fd_connect(MigrationState *s, Error *error_in);
bool migration_is_setup_or_active(int state);
+bool migration_is_running(int state);
void migrate_init(MigrationState *s);
bool migration_is_blocked(Error **errp);
diff --git a/migration/savevm.c b/migration/savevm.c
index a80bb52..144ecf0 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1506,9 +1506,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
MigrationState *ms = migrate_get_current();
MigrationStatus status;
- if (migration_is_setup_or_active(ms->state) ||
- ms->state == MIGRATION_STATUS_CANCELLING ||
- ms->state == MIGRATION_STATUS_COLO) {
+ if (migration_is_running(ms->state)) {
error_setg(errp, QERR_MIGRATION_ACTIVE);
return -EINVAL;
}
--
1.8.3.1

View File

@ -0,0 +1,42 @@
From ab07e0b41c50a85940d798a9a65a58698fd2edfb Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:40 +0000
Subject: [PATCH 08/18] migration: Don't send data if we have stopped
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-8-quintela@redhat.com>
Patchwork-id: 94114
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 07/10] migration: Don't send data if we have stopped
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
If we do a cancel, we got out without one error, but we can't do the
rest of the output as in a normal situation.
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit b69a0227a803256ad270283872d40ff768f4d56d)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/ram.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/migration/ram.c b/migration/ram.c
index a0257ee..902c56c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3511,7 +3511,8 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
ram_control_after_iterate(f, RAM_CONTROL_ROUND);
out:
- if (ret >= 0) {
+ if (ret >= 0
+ && migration_is_setup_or_active(migrate_get_current()->state)) {
multifd_send_sync_main(rs);
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
qemu_fflush(f);
--
1.8.3.1

View File

@ -0,0 +1,94 @@
From 71b05ab5782aa1e38c016be6264a14f5650d2a87 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:35 +0000
Subject: [PATCH 03/18] migration: Make sure that we don't call write() in case
of error
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-3-quintela@redhat.com>
Patchwork-id: 94113
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 02/10] migration: Make sure that we don't call write() in case of error
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
If we are exiting due to an error/finish/.... Just don't try to even
touch the channel with one IO operation.
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 4d65a6216bfc44891ac298b74a6921d479805131)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/ram.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/migration/ram.c b/migration/ram.c
index 65580e3..8c783b3 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -899,6 +899,12 @@ struct {
uint64_t packet_num;
/* send channels ready */
QemuSemaphore channels_ready;
+ /*
+ * Have we already run terminate threads. There is a race when it
+ * happens that we got one error while we are exiting.
+ * We will use atomic operations. Only valid values are 0 and 1.
+ */
+ int exiting;
} *multifd_send_state;
/*
@@ -927,6 +933,10 @@ static int multifd_send_pages(RAMState *rs)
MultiFDPages_t *pages = multifd_send_state->pages;
uint64_t transferred;
+ if (atomic_read(&multifd_send_state->exiting)) {
+ return -1;
+ }
+
qemu_sem_wait(&multifd_send_state->channels_ready);
for (i = next_channel;; i = (i + 1) % migrate_multifd_channels()) {
p = &multifd_send_state->params[i];
@@ -1008,6 +1018,16 @@ static void multifd_send_terminate_threads(Error *err)
}
}
+ /*
+ * We don't want to exit each threads twice. Depending on where
+ * we get the error, or if there are two independent errors in two
+ * threads at the same time, we can end calling this function
+ * twice.
+ */
+ if (atomic_xchg(&multifd_send_state->exiting, 1)) {
+ return;
+ }
+
for (i = 0; i < migrate_multifd_channels(); i++) {
MultiFDSendParams *p = &multifd_send_state->params[i];
@@ -1117,6 +1137,10 @@ static void *multifd_send_thread(void *opaque)
while (true) {
qemu_sem_wait(&p->sem);
+
+ if (atomic_read(&multifd_send_state->exiting)) {
+ break;
+ }
qemu_mutex_lock(&p->mutex);
if (p->pending_job) {
@@ -1225,6 +1249,7 @@ int multifd_save_setup(void)
multifd_send_state->params = g_new0(MultiFDSendParams, thread_count);
multifd_send_state->pages = multifd_pages_init(page_count);
qemu_sem_init(&multifd_send_state->channels_ready, 0);
+ atomic_set(&multifd_send_state->exiting, 0);
for (i = 0; i < thread_count; i++) {
MultiFDSendParams *p = &multifd_send_state->params[i];
--
1.8.3.1

View File

@ -0,0 +1,70 @@
From 3c4f6f0c2bf5562f2aa26f964848ae53e6ac4790 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:43 +0000
Subject: [PATCH 11/18] migration: Maybe VM is paused when migration is
cancelled
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-11-quintela@redhat.com>
Patchwork-id: 94120
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 10/10] migration: Maybe VM is paused when migration is cancelled
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
From: Zhimin Feng <fengzhimin1@huawei.com>
If the migration is cancelled when it is in the completion phase,
the migration state is set to MIGRATION_STATUS_CANCELLING.
The VM maybe wait for the 'pause_sem' semaphore in migration_maybe_pause
function, so that VM always is paused.
Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: Zhimin Feng <fengzhimin1@huawei.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 8958338b10abcb346b54a8038a491fda2db1c853)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/migration.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index eb50d77..ed18c59 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2786,14 +2786,22 @@ static int migration_maybe_pause(MigrationState *s,
/* This block intentionally left blank */
}
- qemu_mutex_unlock_iothread();
- migrate_set_state(&s->state, *current_active_state,
- MIGRATION_STATUS_PRE_SWITCHOVER);
- qemu_sem_wait(&s->pause_sem);
- migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER,
- new_state);
- *current_active_state = new_state;
- qemu_mutex_lock_iothread();
+ /*
+ * If the migration is cancelled when it is in the completion phase,
+ * the migration state is set to MIGRATION_STATUS_CANCELLING.
+ * So we don't need to wait a semaphore, otherwise we would always
+ * wait for the 'pause_sem' semaphore.
+ */
+ if (s->state != MIGRATION_STATUS_CANCELLING) {
+ qemu_mutex_unlock_iothread();
+ migrate_set_state(&s->state, *current_active_state,
+ MIGRATION_STATUS_PRE_SWITCHOVER);
+ qemu_sem_wait(&s->pause_sem);
+ migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER,
+ new_state);
+ *current_active_state = new_state;
+ qemu_mutex_lock_iothread();
+ }
return s->state == new_state ? 0 : -EINVAL;
}
--
1.8.3.1

View File

@ -0,0 +1,65 @@
From 32ee75b7f4a31d6080e5659e2a0285a046ef1036 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:34 +0000
Subject: [PATCH 02/18] migration/multifd: clean pages after filling packet
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-2-quintela@redhat.com>
Patchwork-id: 94112
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 01/10] migration/multifd: clean pages after filling packet
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
From: Wei Yang <richardw.yang@linux.intel.com>
This is a preparation for the next patch:
not use multifd during postcopy.
Without enabling postcopy, everything looks good. While after enabling
postcopy, migration may fail even not use multifd during postcopy. The
reason is the pages is not properly cleared and *old* target page will
continue to be transferred.
After clean pages, migration succeeds.
Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit eab54aa78ffd9fb7895b20fc2761ee998479489b)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/ram.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/migration/ram.c b/migration/ram.c
index 5078f94..65580e3 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -944,10 +944,10 @@ static int multifd_send_pages(RAMState *rs)
}
qemu_mutex_unlock(&p->mutex);
}
- p->pages->used = 0;
+ assert(!p->pages->used);
+ assert(!p->pages->block);
p->packet_num = multifd_send_state->packet_num++;
- p->pages->block = NULL;
multifd_send_state->pages = p->pages;
p->pages = pages;
transferred = ((uint64_t) pages->used) * TARGET_PAGE_SIZE + p->packet_len;
@@ -1129,6 +1129,8 @@ static void *multifd_send_thread(void *opaque)
p->flags = 0;
p->num_packets++;
p->num_pages += used;
+ p->pages->used = 0;
+ p->pages->block = NULL;
qemu_mutex_unlock(&p->mutex);
trace_multifd_send(p->id, packet_num, used, flags,
--
1.8.3.1

View File

@ -0,0 +1,77 @@
From 2c14a6831954a59256cc8d1980da0ad705a3a3fa Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:37 +0000
Subject: [PATCH 05/18] migration/multifd: fix destroyed mutex access in
terminating multifd threads
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-5-quintela@redhat.com>
Patchwork-id: 94119
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 04/10] migration/multifd: fix destroyed mutex access in terminating multifd threads
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
From: Jiahui Cen <cenjiahui@huawei.com>
One multifd will lock all the other multifds' IOChannel mutex to inform them
to quit by setting p->quit or shutting down p->c. In this senario, if some
multifds had already been terminated and multifd_load_cleanup/multifd_save_cleanup
had destroyed their mutex, it could cause destroyed mutex access when trying
lock their mutex.
Here is the coredump stack:
#0 0x00007f81a2794437 in raise () from /usr/lib64/libc.so.6
#1 0x00007f81a2795b28 in abort () from /usr/lib64/libc.so.6
#2 0x00007f81a278d1b6 in __assert_fail_base () from /usr/lib64/libc.so.6
#3 0x00007f81a278d262 in __assert_fail () from /usr/lib64/libc.so.6
#4 0x000055eb1bfadbd3 in qemu_mutex_lock_impl (mutex=0x55eb1e2d1988, file=<optimized out>, line=<optimized out>) at util/qemu-thread-posix.c:64
#5 0x000055eb1bb4564a in multifd_send_terminate_threads (err=<optimized out>) at migration/ram.c:1015
#6 0x000055eb1bb4bb7f in multifd_send_thread (opaque=0x55eb1e2d19f8) at migration/ram.c:1171
#7 0x000055eb1bfad628 in qemu_thread_start (args=0x55eb1e170450) at util/qemu-thread-posix.c:502
#8 0x00007f81a2b36df5 in start_thread () from /usr/lib64/libpthread.so.0
#9 0x00007f81a286048d in clone () from /usr/lib64/libc.so.6
To fix it up, let's destroy the mutex after all the other multifd threads had
been terminated.
Signed-off-by: Jiahui Cen <cenjiahui@huawei.com>
Signed-off-by: Ying Fang <fangying1@huawei.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 9560a48ecc0c20d87bc458a6db77fba651605819)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/ram.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/migration/ram.c b/migration/ram.c
index 860f781..6c55c5d 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1052,6 +1052,10 @@ void multifd_save_cleanup(void)
if (p->running) {
qemu_thread_join(&p->thread);
}
+ }
+ for (i = 0; i < migrate_multifd_channels(); i++) {
+ MultiFDSendParams *p = &multifd_send_state->params[i];
+
socket_send_channel_destroy(p->c);
p->c = NULL;
qemu_mutex_destroy(&p->mutex);
@@ -1335,6 +1339,10 @@ int multifd_load_cleanup(Error **errp)
qemu_sem_post(&p->sem_sync);
qemu_thread_join(&p->thread);
}
+ }
+ for (i = 0; i < migrate_multifd_channels(); i++) {
+ MultiFDRecvParams *p = &multifd_recv_state->params[i];
+
object_unref(OBJECT(p->c));
p->c = NULL;
qemu_mutex_destroy(&p->mutex);
--
1.8.3.1

View File

@ -0,0 +1,75 @@
From 517a99c5fba163bf684978fe3d9476b619481391 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:42 +0000
Subject: [PATCH 10/18] migration/multifd: fix nullptr access in
multifd_send_terminate_threads
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-10-quintela@redhat.com>
Patchwork-id: 94117
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 09/10] migration/multifd: fix nullptr access in multifd_send_terminate_threads
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
From: Zhimin Feng <fengzhimin1@huawei.com>
If the multifd_send_threads is not created when migration is failed,
multifd_save_cleanup would be called twice. In this senario, the
multifd_send_state is accessed after it has been released, the result
is that the source VM is crashing down.
Here is the coredump stack:
Program received signal SIGSEGV, Segmentation fault.
0x00005629333a78ef in multifd_send_terminate_threads (err=err@entry=0x0) at migration/ram.c:1012
1012 MultiFDSendParams *p = &multifd_send_state->params[i];
#0 0x00005629333a78ef in multifd_send_terminate_threads (err=err@entry=0x0) at migration/ram.c:1012
#1 0x00005629333ab8a9 in multifd_save_cleanup () at migration/ram.c:1028
#2 0x00005629333abaea in multifd_new_send_channel_async (task=0x562935450e70, opaque=<optimized out>) at migration/ram.c:1202
#3 0x000056293373a562 in qio_task_complete (task=task@entry=0x562935450e70) at io/task.c:196
#4 0x000056293373a6e0 in qio_task_thread_result (opaque=0x562935450e70) at io/task.c:111
#5 0x00007f475d4d75a7 in g_idle_dispatch () from /usr/lib64/libglib-2.0.so.0
#6 0x00007f475d4da9a9 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
#7 0x0000562933785b33 in glib_pollfds_poll () at util/main-loop.c:219
#8 os_host_main_loop_wait (timeout=<optimized out>) at util/main-loop.c:242
#9 main_loop_wait (nonblocking=nonblocking@entry=0) at util/main-loop.c:518
#10 0x00005629334c5acf in main_loop () at vl.c:1810
#11 0x000056293334d7bb in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4471
If the multifd_send_threads is not created when migration is failed.
In this senario, we don't call multifd_save_cleanup in multifd_new_send_channel_async.
Signed-off-by: Zhimin Feng <fengzhimin1@huawei.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 9c4d333c092e9c26d38f740ff3616deb42f21681)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/ram.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/migration/ram.c b/migration/ram.c
index 902c56c..3891eff 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1229,7 +1229,15 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
trace_multifd_new_send_channel_async(p->id);
if (qio_task_propagate_error(task, &local_err)) {
migrate_set_error(migrate_get_current(), local_err);
- multifd_save_cleanup();
+ /* Error happen, we need to tell who pay attention to me */
+ qemu_sem_post(&multifd_send_state->channels_ready);
+ qemu_sem_post(&p->sem_sync);
+ /*
+ * Although multifd_send_thread is not created, but main migration
+ * thread neet to judge whether it is running, so we need to mark
+ * its status.
+ */
+ p->quit = true;
} else {
p->c = QIO_CHANNEL(sioc);
qio_channel_set_delay(p->c, false);
--
1.8.3.1

View File

@ -0,0 +1,68 @@
From 7f664fe26ff67f8131faa7a81a388b8a5b51403f Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:36 +0000
Subject: [PATCH 04/18] migration/multifd: fix nullptr access in terminating
multifd threads
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-4-quintela@redhat.com>
Patchwork-id: 94110
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 03/10] migration/multifd: fix nullptr access in terminating multifd threads
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
From: Jiahui Cen <cenjiahui@huawei.com>
One multifd channel will shutdown all the other multifd's IOChannel when it
fails to receive an IOChannel. In this senario, if some multifds had not
received its IOChannel yet, it would try to shutdown its IOChannel which could
cause nullptr access at qio_channel_shutdown.
Here is the coredump stack:
#0 object_get_class (obj=obj@entry=0x0) at qom/object.c:908
#1 0x00005563fdbb8f4a in qio_channel_shutdown (ioc=0x0, how=QIO_CHANNEL_SHUTDOWN_BOTH, errp=0x0) at io/channel.c:355
#2 0x00005563fd7b4c5f in multifd_recv_terminate_threads (err=<optimized out>) at migration/ram.c:1280
#3 0x00005563fd7bc019 in multifd_recv_new_channel (ioc=ioc@entry=0x556400255610, errp=errp@entry=0x7ffec07dce00) at migration/ram.c:1478
#4 0x00005563fda82177 in migration_ioc_process_incoming (ioc=ioc@entry=0x556400255610, errp=errp@entry=0x7ffec07dce30) at migration/migration.c:605
#5 0x00005563fda8567d in migration_channel_process_incoming (ioc=0x556400255610) at migration/channel.c:44
#6 0x00005563fda83ee0 in socket_accept_incoming_migration (listener=0x5563fff6b920, cioc=0x556400255610, opaque=<optimized out>) at migration/socket.c:166
#7 0x00005563fdbc25cd in qio_net_listener_channel_func (ioc=<optimized out>, condition=<optimized out>, opaque=<optimized out>) at io/net-listener.c:54
#8 0x00007f895b6fe9a9 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
#9 0x00005563fdc18136 in glib_pollfds_poll () at util/main-loop.c:218
#10 0x00005563fdc181b5 in os_host_main_loop_wait (timeout=1000000000) at util/main-loop.c:241
#11 0x00005563fdc183a2 in main_loop_wait (nonblocking=nonblocking@entry=0) at util/main-loop.c:517
#12 0x00005563fd8edb37 in main_loop () at vl.c:1791
#13 0x00005563fd74fd45 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4473
To fix it up, let's check p->c before calling qio_channel_shutdown.
Signed-off-by: Jiahui Cen <cenjiahui@huawei.com>
Signed-off-by: Ying Fang <fangying1@huawei.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit f76e32eb05041ab001184ab16afb56524adccd0c)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/ram.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/migration/ram.c b/migration/ram.c
index 8c783b3..860f781 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1307,7 +1307,9 @@ static void multifd_recv_terminate_threads(Error *err)
- normal quit, i.e. everything went fine, just finished
- error quit: We close the channels so the channel threads
finish the qio_channel_read_all_eof() */
- qio_channel_shutdown(p->c, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+ if (p->c) {
+ qio_channel_shutdown(p->c, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+ }
qemu_mutex_unlock(&p->mutex);
}
}
--
1.8.3.1

View File

@ -0,0 +1,74 @@
From 78c7fb5afcb298631df47f6b71cf764f921c15f4 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:38 +0000
Subject: [PATCH 06/18] multifd: Make sure that we don't do any IO after an
error
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-6-quintela@redhat.com>
Patchwork-id: 94118
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 05/10] multifd: Make sure that we don't do any IO after an error
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit 3d4095b222d97393b1c2c6e514951ec7798f1c43)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/ram.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/migration/ram.c b/migration/ram.c
index 6c55c5d..a0257ee 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3440,7 +3440,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
{
RAMState **temp = opaque;
RAMState *rs = *temp;
- int ret;
+ int ret = 0;
int i;
int64_t t0;
int done = 0;
@@ -3511,12 +3511,14 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
ram_control_after_iterate(f, RAM_CONTROL_ROUND);
out:
- multifd_send_sync_main(rs);
- qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
- qemu_fflush(f);
- ram_counters.transferred += 8;
+ if (ret >= 0) {
+ multifd_send_sync_main(rs);
+ qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
+ qemu_fflush(f);
+ ram_counters.transferred += 8;
- ret = qemu_file_get_error(f);
+ ret = qemu_file_get_error(f);
+ }
if (ret < 0) {
return ret;
}
@@ -3568,9 +3570,11 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
ram_control_after_iterate(f, RAM_CONTROL_FINISH);
}
- multifd_send_sync_main(rs);
- qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
- qemu_fflush(f);
+ if (ret >= 0) {
+ multifd_send_sync_main(rs);
+ qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
+ qemu_fflush(f);
+ }
return ret;
}
--
1.8.3.1

View File

@ -0,0 +1,92 @@
From d84814e298e3b05fb5bc61cc8e641a5e104d32d5 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 3 Mar 2020 14:51:39 +0000
Subject: [PATCH 07/18] qemu-file: Don't do IO after shutdown
RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <20200303145143.149290-7-quintela@redhat.com>
Patchwork-id: 94116
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 06/10] qemu-file: Don't do IO after shutdown
Bugzilla: 1738451
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Be sure that we are not doing neither read/write after shutdown of the
QEMUFile.
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit a555b8092abc6f1bbe4b64c516679cbd68fcfbd8)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
migration/qemu-file.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index 26fb25d..bbb2b63 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -53,6 +53,8 @@ struct QEMUFile {
int last_error;
Error *last_error_obj;
+ /* has the file has been shutdown */
+ bool shutdown;
};
/*
@@ -61,10 +63,18 @@ struct QEMUFile {
*/
int qemu_file_shutdown(QEMUFile *f)
{
+ int ret;
+
+ f->shutdown = true;
if (!f->ops->shut_down) {
return -ENOSYS;
}
- return f->ops->shut_down(f->opaque, true, true, NULL);
+ ret = f->ops->shut_down(f->opaque, true, true, NULL);
+
+ if (!f->last_error) {
+ qemu_file_set_error(f, -EIO);
+ }
+ return ret;
}
/*
@@ -214,6 +224,9 @@ void qemu_fflush(QEMUFile *f)
return;
}
+ if (f->shutdown) {
+ return;
+ }
if (f->iovcnt > 0) {
expect = iov_size(f->iov, f->iovcnt);
ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos,
@@ -328,6 +341,10 @@ static ssize_t qemu_fill_buffer(QEMUFile *f)
f->buf_index = 0;
f->buf_size = pending;
+ if (f->shutdown) {
+ return 0;
+ }
+
len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos,
IO_BUF_SIZE - pending, &local_error);
if (len > 0) {
@@ -642,6 +659,9 @@ int64_t qemu_ftell(QEMUFile *f)
int qemu_file_rate_limit(QEMUFile *f)
{
+ if (f->shutdown) {
+ return 1;
+ }
if (qemu_file_get_error(f)) {
return 1;
}
--
1.8.3.1

View File

@ -0,0 +1,55 @@
From e483eea891139ee38138381ba6715b3a2be050cc Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Tue, 3 Mar 2020 18:43:12 +0000
Subject: [PATCH 16/18] tools/virtiofsd/fuse_lowlevel: Fix
fuse_out_header::error value
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20200303184314.155564-6-dgilbert@redhat.com>
Patchwork-id: 94128
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 5/7] tools/virtiofsd/fuse_lowlevel: Fix fuse_out_header::error value
Bugzilla: 1797064
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
RH-Acked-by: Ján Tomko <jtomko@redhat.com>
From: Philippe Mathieu-Daudé <philmd@redhat.com>
Fix warning reported by Clang static code analyzer:
CC tools/virtiofsd/fuse_lowlevel.o
tools/virtiofsd/fuse_lowlevel.c:195:9: warning: Value stored to 'error' is never read
error = -ERANGE;
^ ~~~~~~~
Fixes: 3db2876
Reported-by: Clang Static Analyzer
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit 09c086b2a144324199f99a7d4de78c3276a486c1)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
tools/virtiofsd/fuse_lowlevel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c
index 704c036..2dd36ec 100644
--- a/tools/virtiofsd/fuse_lowlevel.c
+++ b/tools/virtiofsd/fuse_lowlevel.c
@@ -192,7 +192,7 @@ int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
if (error <= -1000 || error > 0) {
fuse_log(FUSE_LOG_ERR, "fuse: bad error value: %i\n", error);
- error = -ERANGE;
+ out.error = -ERANGE;
}
iov[0].iov_base = &out;
--
1.8.3.1

View File

@ -0,0 +1,327 @@
From 8721796f22a8a61d82974088e542377ee6db209e Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Tue, 3 Mar 2020 18:43:14 +0000
Subject: [PATCH 18/18] virtiofsd: Fix xattr operations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20200303184314.155564-8-dgilbert@redhat.com>
Patchwork-id: 94123
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 7/7] virtiofsd: Fix xattr operations
Bugzilla: 1797064
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
RH-Acked-by: Ján Tomko <jtomko@redhat.com>
From: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
Current virtiofsd has problems about xattr operations and
they does not work properly for directory/symlink/special file.
The fundamental cause is that virtiofsd uses openat() + f...xattr()
systemcalls for xattr operation but we should not open symlink/special
file in the daemon. Therefore the function is restricted.
Fix this problem by:
1. during setup of each thread, call unshare(CLONE_FS)
2. in xattr operations (i.e. lo_getxattr), if inode is not a regular
file or directory, use fchdir(proc_loot_fd) + ...xattr() +
fchdir(root.fd) instead of openat() + f...xattr()
(Note: for a regular file/directory openat() + f...xattr()
is still used for performance reason)
With this patch, xfstests generic/062 passes on virtiofs.
This fix is suggested by Miklos Szeredi and Stefan Hajnoczi.
The original discussion can be found here:
https://www.redhat.com/archives/virtio-fs/2019-October/msg00046.html
Signed-off-by: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
Message-Id: <20200227055927.24566-3-misono.tomohiro@jp.fujitsu.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit bdfd66788349acc43cd3f1298718ad491663cfcc)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
tools/virtiofsd/fuse_virtio.c | 13 +++++
tools/virtiofsd/passthrough_ll.c | 105 +++++++++++++++++++++------------------
tools/virtiofsd/seccomp.c | 6 +++
3 files changed, 77 insertions(+), 47 deletions(-)
diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index dd1c605..3b6d16a 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -426,6 +426,8 @@ err:
return ret;
}
+static __thread bool clone_fs_called;
+
/* Process one FVRequest in a thread pool */
static void fv_queue_worker(gpointer data, gpointer user_data)
{
@@ -441,6 +443,17 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
assert(se->bufsize > sizeof(struct fuse_in_header));
+ if (!clone_fs_called) {
+ int ret;
+
+ /* unshare FS for xattr operation */
+ ret = unshare(CLONE_FS);
+ /* should not fail */
+ assert(ret == 0);
+
+ clone_fs_called = true;
+ }
+
/*
* An element contains one request and the space to send our response
* They're spread over multiple descriptors in a scatter/gather set
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index 50c7273..9cba3f1 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -123,7 +123,7 @@ struct lo_inode {
pthread_mutex_t plock_mutex;
GHashTable *posix_locks; /* protected by lo_inode->plock_mutex */
- bool is_symlink;
+ mode_t filetype;
};
struct lo_cred {
@@ -695,7 +695,7 @@ static int utimensat_empty(struct lo_data *lo, struct lo_inode *inode,
struct lo_inode *parent;
char path[PATH_MAX];
- if (inode->is_symlink) {
+ if (S_ISLNK(inode->filetype)) {
res = utimensat(inode->fd, "", tv, AT_EMPTY_PATH);
if (res == -1 && errno == EINVAL) {
/* Sorry, no race free way to set times on symlink. */
@@ -929,7 +929,8 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name,
goto out_err;
}
- inode->is_symlink = S_ISLNK(e->attr.st_mode);
+ /* cache only filetype */
+ inode->filetype = (e->attr.st_mode & S_IFMT);
/*
* One for the caller and one for nlookup (released in
@@ -1139,7 +1140,7 @@ static int linkat_empty_nofollow(struct lo_data *lo, struct lo_inode *inode,
struct lo_inode *parent;
char path[PATH_MAX];
- if (inode->is_symlink) {
+ if (S_ISLNK(inode->filetype)) {
res = linkat(inode->fd, "", dfd, name, AT_EMPTY_PATH);
if (res == -1 && (errno == ENOENT || errno == EINVAL)) {
/* Sorry, no race free way to hard-link a symlink. */
@@ -2193,12 +2194,6 @@ static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
fuse_log(FUSE_LOG_DEBUG, "lo_getxattr(ino=%" PRIu64 ", name=%s size=%zd)\n",
ino, name, size);
- if (inode->is_symlink) {
- /* Sorry, no race free way to getxattr on symlink. */
- saverr = EPERM;
- goto out;
- }
-
if (size) {
value = malloc(size);
if (!value) {
@@ -2207,12 +2202,25 @@ static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
}
sprintf(procname, "%i", inode->fd);
- fd = openat(lo->proc_self_fd, procname, O_RDONLY);
- if (fd < 0) {
- goto out_err;
+ /*
+ * It is not safe to open() non-regular/non-dir files in file server
+ * unless O_PATH is used, so use that method for regular files/dir
+ * only (as it seems giving less performance overhead).
+ * Otherwise, call fchdir() to avoid open().
+ */
+ if (S_ISREG(inode->filetype) || S_ISDIR(inode->filetype)) {
+ fd = openat(lo->proc_self_fd, procname, O_RDONLY);
+ if (fd < 0) {
+ goto out_err;
+ }
+ ret = fgetxattr(fd, name, value, size);
+ } else {
+ /* fchdir should not fail here */
+ assert(fchdir(lo->proc_self_fd) == 0);
+ ret = getxattr(procname, name, value, size);
+ assert(fchdir(lo->root.fd) == 0);
}
- ret = fgetxattr(fd, name, value, size);
if (ret == -1) {
goto out_err;
}
@@ -2266,12 +2274,6 @@ static void lo_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
fuse_log(FUSE_LOG_DEBUG, "lo_listxattr(ino=%" PRIu64 ", size=%zd)\n", ino,
size);
- if (inode->is_symlink) {
- /* Sorry, no race free way to listxattr on symlink. */
- saverr = EPERM;
- goto out;
- }
-
if (size) {
value = malloc(size);
if (!value) {
@@ -2280,12 +2282,19 @@ static void lo_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
}
sprintf(procname, "%i", inode->fd);
- fd = openat(lo->proc_self_fd, procname, O_RDONLY);
- if (fd < 0) {
- goto out_err;
+ if (S_ISREG(inode->filetype) || S_ISDIR(inode->filetype)) {
+ fd = openat(lo->proc_self_fd, procname, O_RDONLY);
+ if (fd < 0) {
+ goto out_err;
+ }
+ ret = flistxattr(fd, value, size);
+ } else {
+ /* fchdir should not fail here */
+ assert(fchdir(lo->proc_self_fd) == 0);
+ ret = listxattr(procname, value, size);
+ assert(fchdir(lo->root.fd) == 0);
}
- ret = flistxattr(fd, value, size);
if (ret == -1) {
goto out_err;
}
@@ -2339,20 +2348,21 @@ static void lo_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
fuse_log(FUSE_LOG_DEBUG, "lo_setxattr(ino=%" PRIu64
", name=%s value=%s size=%zd)\n", ino, name, value, size);
- if (inode->is_symlink) {
- /* Sorry, no race free way to setxattr on symlink. */
- saverr = EPERM;
- goto out;
- }
-
sprintf(procname, "%i", inode->fd);
- fd = openat(lo->proc_self_fd, procname, O_RDWR);
- if (fd < 0) {
- saverr = errno;
- goto out;
+ if (S_ISREG(inode->filetype) || S_ISDIR(inode->filetype)) {
+ fd = openat(lo->proc_self_fd, procname, O_RDONLY);
+ if (fd < 0) {
+ saverr = errno;
+ goto out;
+ }
+ ret = fsetxattr(fd, name, value, size, flags);
+ } else {
+ /* fchdir should not fail here */
+ assert(fchdir(lo->proc_self_fd) == 0);
+ ret = setxattr(procname, name, value, size, flags);
+ assert(fchdir(lo->root.fd) == 0);
}
- ret = fsetxattr(fd, name, value, size, flags);
saverr = ret == -1 ? errno : 0;
out:
@@ -2387,20 +2397,21 @@ static void lo_removexattr(fuse_req_t req, fuse_ino_t ino, const char *name)
fuse_log(FUSE_LOG_DEBUG, "lo_removexattr(ino=%" PRIu64 ", name=%s)\n", ino,
name);
- if (inode->is_symlink) {
- /* Sorry, no race free way to setxattr on symlink. */
- saverr = EPERM;
- goto out;
- }
-
sprintf(procname, "%i", inode->fd);
- fd = openat(lo->proc_self_fd, procname, O_RDWR);
- if (fd < 0) {
- saverr = errno;
- goto out;
+ if (S_ISREG(inode->filetype) || S_ISDIR(inode->filetype)) {
+ fd = openat(lo->proc_self_fd, procname, O_RDONLY);
+ if (fd < 0) {
+ saverr = errno;
+ goto out;
+ }
+ ret = fremovexattr(fd, name);
+ } else {
+ /* fchdir should not fail here */
+ assert(fchdir(lo->proc_self_fd) == 0);
+ ret = removexattr(procname, name);
+ assert(fchdir(lo->root.fd) == 0);
}
- ret = fremovexattr(fd, name);
saverr = ret == -1 ? errno : 0;
out:
@@ -2800,7 +2811,7 @@ static void setup_root(struct lo_data *lo, struct lo_inode *root)
exit(1);
}
- root->is_symlink = false;
+ root->filetype = S_IFDIR;
root->fd = fd;
root->key.ino = stat.st_ino;
root->key.dev = stat.st_dev;
diff --git a/tools/virtiofsd/seccomp.c b/tools/virtiofsd/seccomp.c
index 2d9d4a7..bd9e7b0 100644
--- a/tools/virtiofsd/seccomp.c
+++ b/tools/virtiofsd/seccomp.c
@@ -41,6 +41,7 @@ static const int syscall_whitelist[] = {
SCMP_SYS(exit),
SCMP_SYS(exit_group),
SCMP_SYS(fallocate),
+ SCMP_SYS(fchdir),
SCMP_SYS(fchmodat),
SCMP_SYS(fchownat),
SCMP_SYS(fcntl),
@@ -62,7 +63,9 @@ static const int syscall_whitelist[] = {
SCMP_SYS(getpid),
SCMP_SYS(gettid),
SCMP_SYS(gettimeofday),
+ SCMP_SYS(getxattr),
SCMP_SYS(linkat),
+ SCMP_SYS(listxattr),
SCMP_SYS(lseek),
SCMP_SYS(madvise),
SCMP_SYS(mkdirat),
@@ -85,6 +88,7 @@ static const int syscall_whitelist[] = {
SCMP_SYS(recvmsg),
SCMP_SYS(renameat),
SCMP_SYS(renameat2),
+ SCMP_SYS(removexattr),
SCMP_SYS(rt_sigaction),
SCMP_SYS(rt_sigprocmask),
SCMP_SYS(rt_sigreturn),
@@ -98,10 +102,12 @@ static const int syscall_whitelist[] = {
SCMP_SYS(setresuid32),
#endif
SCMP_SYS(set_robust_list),
+ SCMP_SYS(setxattr),
SCMP_SYS(symlinkat),
SCMP_SYS(time), /* Rarely needed, except on static builds */
SCMP_SYS(tgkill),
SCMP_SYS(unlinkat),
+ SCMP_SYS(unshare),
SCMP_SYS(utimensat),
SCMP_SYS(write),
SCMP_SYS(writev),
--
1.8.3.1

View File

@ -0,0 +1,193 @@
From 7a1860c83ff042f3e796c449e780ee0528107213 Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Tue, 3 Mar 2020 18:43:08 +0000
Subject: [PATCH 12/18] virtiofsd: Remove fuse_req_getgroups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20200303184314.155564-2-dgilbert@redhat.com>
Patchwork-id: 94122
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 1/7] virtiofsd: Remove fuse_req_getgroups
Bugzilla: 1797064
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
RH-Acked-by: Ján Tomko <jtomko@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Remove fuse_req_getgroups that's unused in virtiofsd; it came in
from libfuse but we don't actually use it. It was called from
fuse_getgroups which we previously removed (but had left it's header
in).
Coverity had complained about null termination in it, but removing
it is the easiest answer.
Fixes: Coverity CID: 1413117 (String not null terminated)
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 988717b46b6424907618cb845ace9d69062703af)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
tools/virtiofsd/fuse.h | 20 -----------
tools/virtiofsd/fuse_lowlevel.c | 77 -----------------------------------------
tools/virtiofsd/fuse_lowlevel.h | 21 -----------
3 files changed, 118 deletions(-)
diff --git a/tools/virtiofsd/fuse.h b/tools/virtiofsd/fuse.h
index 7a4c713..aba13fe 100644
--- a/tools/virtiofsd/fuse.h
+++ b/tools/virtiofsd/fuse.h
@@ -1007,26 +1007,6 @@ void fuse_exit(struct fuse *f);
struct fuse_context *fuse_get_context(void);
/**
- * Get the current supplementary group IDs for the current request
- *
- * Similar to the getgroups(2) system call, except the return value is
- * always the total number of group IDs, even if it is larger than the
- * specified size.
- *
- * The current fuse kernel module in linux (as of 2.6.30) doesn't pass
- * the group list to userspace, hence this function needs to parse
- * "/proc/$TID/task/$TID/status" to get the group IDs.
- *
- * This feature may not be supported on all operating systems. In
- * such a case this function will return -ENOSYS.
- *
- * @param size size of given array
- * @param list array of group IDs to be filled in
- * @return the total number of supplementary group IDs or -errno on failure
- */
-int fuse_getgroups(int size, gid_t list[]);
-
-/**
* Check if the current request has already been interrupted
*
* @return 1 if the request has been interrupted, 0 otherwise
diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c
index de2e2e0..01c418a 100644
--- a/tools/virtiofsd/fuse_lowlevel.c
+++ b/tools/virtiofsd/fuse_lowlevel.c
@@ -2667,83 +2667,6 @@ int fuse_lowlevel_is_virtio(struct fuse_session *se)
return !!se->virtio_dev;
}
-#ifdef linux
-int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
-{
- char *buf;
- size_t bufsize = 1024;
- char path[128];
- int ret;
- int fd;
- unsigned long pid = req->ctx.pid;
- char *s;
-
- sprintf(path, "/proc/%lu/task/%lu/status", pid, pid);
-
-retry:
- buf = malloc(bufsize);
- if (buf == NULL) {
- return -ENOMEM;
- }
-
- ret = -EIO;
- fd = open(path, O_RDONLY);
- if (fd == -1) {
- goto out_free;
- }
-
- ret = read(fd, buf, bufsize);
- close(fd);
- if (ret < 0) {
- ret = -EIO;
- goto out_free;
- }
-
- if ((size_t)ret == bufsize) {
- free(buf);
- bufsize *= 4;
- goto retry;
- }
-
- ret = -EIO;
- s = strstr(buf, "\nGroups:");
- if (s == NULL) {
- goto out_free;
- }
-
- s += 8;
- ret = 0;
- while (1) {
- char *end;
- unsigned long val = strtoul(s, &end, 0);
- if (end == s) {
- break;
- }
-
- s = end;
- if (ret < size) {
- list[ret] = val;
- }
- ret++;
- }
-
-out_free:
- free(buf);
- return ret;
-}
-#else /* linux */
-/*
- * This is currently not implemented on other than Linux...
- */
-int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
-{
- (void)req;
- (void)size;
- (void)list;
- return -ENOSYS;
-}
-#endif
-
void fuse_session_exit(struct fuse_session *se)
{
se->exited = 1;
diff --git a/tools/virtiofsd/fuse_lowlevel.h b/tools/virtiofsd/fuse_lowlevel.h
index 138041e..8f6d705 100644
--- a/tools/virtiofsd/fuse_lowlevel.h
+++ b/tools/virtiofsd/fuse_lowlevel.h
@@ -1705,27 +1705,6 @@ void *fuse_req_userdata(fuse_req_t req);
const struct fuse_ctx *fuse_req_ctx(fuse_req_t req);
/**
- * Get the current supplementary group IDs for the specified request
- *
- * Similar to the getgroups(2) system call, except the return value is
- * always the total number of group IDs, even if it is larger than the
- * specified size.
- *
- * The current fuse kernel module in linux (as of 2.6.30) doesn't pass
- * the group list to userspace, hence this function needs to parse
- * "/proc/$TID/task/$TID/status" to get the group IDs.
- *
- * This feature may not be supported on all operating systems. In
- * such a case this function will return -ENOSYS.
- *
- * @param req request handle
- * @param size size of given array
- * @param list array of group IDs to be filled in
- * @return the total number of supplementary group IDs or -errno on failure
- */
-int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]);
-
-/**
* Callback function for an interrupt
*
* @param req interrupted request
--
1.8.3.1

View File

@ -0,0 +1,49 @@
From 901c005299b0316bbca7bc190de56f6c7a2a9880 Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Tue, 3 Mar 2020 18:43:11 +0000
Subject: [PATCH 15/18] virtiofsd: do_read missing NULL check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20200303184314.155564-5-dgilbert@redhat.com>
Patchwork-id: 94127
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 4/7] virtiofsd: do_read missing NULL check
Bugzilla: 1797064
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
RH-Acked-by: Ján Tomko <jtomko@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Missing a NULL check if the argument fetch fails.
Fixes: Coverity CID 1413119
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 99ce9a7e60fd12b213b985343ff8fcc172de59fd)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
tools/virtiofsd/fuse_lowlevel.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c
index 01c418a..704c036 100644
--- a/tools/virtiofsd/fuse_lowlevel.c
+++ b/tools/virtiofsd/fuse_lowlevel.c
@@ -1116,6 +1116,10 @@ static void do_read(fuse_req_t req, fuse_ino_t nodeid,
struct fuse_file_info fi;
arg = fuse_mbuf_iter_advance(iter, sizeof(*arg));
+ if (!arg) {
+ fuse_reply_err(req, EINVAL);
+ return;
+ }
memset(&fi, 0, sizeof(fi));
fi.fh = arg->fh;
--
1.8.3.1

View File

@ -0,0 +1,56 @@
From 3b6461ee08654b2cbb6d4e0cc15c02f89a6610d5 Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Tue, 3 Mar 2020 18:43:09 +0000
Subject: [PATCH 13/18] virtiofsd: fv_create_listen_socket error path socket
leak
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20200303184314.155564-3-dgilbert@redhat.com>
Patchwork-id: 94124
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 2/7] virtiofsd: fv_create_listen_socket error path socket leak
Bugzilla: 1797064
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
RH-Acked-by: Ján Tomko <jtomko@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
If we fail when bringing up the socket we can leak the listen_fd;
in practice the daemon will exit so it's not really a problem.
Fixes: Coverity CID 1413121
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 6fa249027f97e3080f3d9c0fab3f94f8f80828fe)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
tools/virtiofsd/fuse_virtio.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 80a6e92..dd1c605 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -916,6 +916,7 @@ static int fv_create_listen_socket(struct fuse_session *se)
old_umask = umask(0077);
if (bind(listen_sock, (struct sockaddr *)&un, addr_len) == -1) {
fuse_log(FUSE_LOG_ERR, "vhost socket bind: %m\n");
+ close(listen_sock);
umask(old_umask);
return -1;
}
@@ -923,6 +924,7 @@ static int fv_create_listen_socket(struct fuse_session *se)
if (listen(listen_sock, 1) == -1) {
fuse_log(FUSE_LOG_ERR, "vhost socket listen: %m\n");
+ close(listen_sock);
return -1;
}
--
1.8.3.1

View File

@ -0,0 +1,46 @@
From ece7649025fbdbde48ff0b954e8ec2e42c4a8b3d Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Tue, 3 Mar 2020 18:43:10 +0000
Subject: [PATCH 14/18] virtiofsd: load_capng missing unlock
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20200303184314.155564-4-dgilbert@redhat.com>
Patchwork-id: 94126
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 3/7] virtiofsd: load_capng missing unlock
Bugzilla: 1797064
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
RH-Acked-by: Ján Tomko <jtomko@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Missing unlock in error path.
Fixes: Covertiy CID 1413123
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 686391112fd42c615bcc4233472887a66a9b5a4a)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
tools/virtiofsd/passthrough_ll.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index e6f2399..c635fc8 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -232,6 +232,7 @@ static int load_capng(void)
*/
cap.saved = capng_save_state();
if (!cap.saved) {
+ pthread_mutex_unlock(&cap.mutex);
fuse_log(FUSE_LOG_ERR, "capng_save_state (thread)\n");
return -EINVAL;
}
--
1.8.3.1

View File

@ -0,0 +1,154 @@
From f93ea308351cbe2630d7ecf637c3b69894d84a11 Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Date: Tue, 3 Mar 2020 18:43:13 +0000
Subject: [PATCH 17/18] virtiofsd: passthrough_ll: cleanup getxattr/listxattr
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: <20200303184314.155564-7-dgilbert@redhat.com>
Patchwork-id: 94125
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 6/7] virtiofsd: passthrough_ll: cleanup getxattr/listxattr
Bugzilla: 1797064
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
RH-Acked-by: Ján Tomko <jtomko@redhat.com>
From: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
This is a cleanup patch to simplify the following xattr fix and
there is no functional changes.
- Move memory allocation to head of the function
- Unify fgetxattr/flistxattr call for both size == 0 and
size != 0 case
- Remove redundant lo_inode_put call in error path
(Note: second call is ignored now since @inode is already NULL)
Signed-off-by: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
Message-Id: <20200227055927.24566-2-misono.tomohiro@jp.fujitsu.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit 16e15a73089102c3d8846792d514e769300fcc3c)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
tools/virtiofsd/passthrough_ll.c | 54 ++++++++++++++++------------------------
1 file changed, 22 insertions(+), 32 deletions(-)
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index c635fc8..50c7273 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -2199,34 +2199,30 @@ static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
goto out;
}
+ if (size) {
+ value = malloc(size);
+ if (!value) {
+ goto out_err;
+ }
+ }
+
sprintf(procname, "%i", inode->fd);
fd = openat(lo->proc_self_fd, procname, O_RDONLY);
if (fd < 0) {
goto out_err;
}
+ ret = fgetxattr(fd, name, value, size);
+ if (ret == -1) {
+ goto out_err;
+ }
if (size) {
- value = malloc(size);
- if (!value) {
- goto out_err;
- }
-
- ret = fgetxattr(fd, name, value, size);
- if (ret == -1) {
- goto out_err;
- }
saverr = 0;
if (ret == 0) {
goto out;
}
-
fuse_reply_buf(req, value, ret);
} else {
- ret = fgetxattr(fd, name, NULL, 0);
- if (ret == -1) {
- goto out_err;
- }
-
fuse_reply_xattr(req, ret);
}
out_free:
@@ -2242,7 +2238,6 @@ out_free:
out_err:
saverr = errno;
out:
- lo_inode_put(lo, &inode);
fuse_reply_err(req, saverr);
goto out_free;
}
@@ -2277,34 +2272,30 @@ static void lo_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
goto out;
}
+ if (size) {
+ value = malloc(size);
+ if (!value) {
+ goto out_err;
+ }
+ }
+
sprintf(procname, "%i", inode->fd);
fd = openat(lo->proc_self_fd, procname, O_RDONLY);
if (fd < 0) {
goto out_err;
}
+ ret = flistxattr(fd, value, size);
+ if (ret == -1) {
+ goto out_err;
+ }
if (size) {
- value = malloc(size);
- if (!value) {
- goto out_err;
- }
-
- ret = flistxattr(fd, value, size);
- if (ret == -1) {
- goto out_err;
- }
saverr = 0;
if (ret == 0) {
goto out;
}
-
fuse_reply_buf(req, value, ret);
} else {
- ret = flistxattr(fd, NULL, 0);
- if (ret == -1) {
- goto out_err;
- }
-
fuse_reply_xattr(req, ret);
}
out_free:
@@ -2320,7 +2311,6 @@ out_free:
out_err:
saverr = errno;
out:
- lo_inode_put(lo, &inode);
fuse_reply_err(req, saverr);
goto out_free;
}
--
1.8.3.1

View File

@ -67,7 +67,7 @@ Obsoletes: %1-rhev
Summary: QEMU is a machine emulator and virtualizer
Name: qemu-kvm
Version: 4.2.0
Release: 13%{?dist}
Release: 14%{?dist}
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
Epoch: 15
License: GPLv2 and GPLv2+ and CC-BY
@ -528,6 +528,42 @@ Patch195: kvm-qcow2-Fix-qcow2_alloc_cluster_abort-for-external-dat.patch
Patch196: kvm-mirror-Store-MirrorOp.co-for-debuggability.patch
# For bz#1794692 - Mirror block job stops making progress
Patch197: kvm-mirror-Don-t-let-an-operation-wait-for-itself.patch
# For bz#1782529 - Windows Update Enablement with default smbios strings in qemu
Patch198: kvm-hw-smbios-set-new-default-SMBIOS-fields-for-Windows-.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch199: kvm-migration-multifd-clean-pages-after-filling-packet.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch200: kvm-migration-Make-sure-that-we-don-t-call-write-in-case.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch201: kvm-migration-multifd-fix-nullptr-access-in-terminating-.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch202: kvm-migration-multifd-fix-destroyed-mutex-access-in-term.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch203: kvm-multifd-Make-sure-that-we-don-t-do-any-IO-after-an-e.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch204: kvm-qemu-file-Don-t-do-IO-after-shutdown.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch205: kvm-migration-Don-t-send-data-if-we-have-stopped.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch206: kvm-migration-Create-migration_is_running.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch207: kvm-migration-multifd-fix-nullptr-access-in-multifd_send.patch
# For bz#1738451 - qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel)
Patch208: kvm-migration-Maybe-VM-is-paused-when-migration-is-cance.patch
# For bz#1797064 - virtiofsd: Fixes
Patch209: kvm-virtiofsd-Remove-fuse_req_getgroups.patch
# For bz#1797064 - virtiofsd: Fixes
Patch210: kvm-virtiofsd-fv_create_listen_socket-error-path-socket-.patch
# For bz#1797064 - virtiofsd: Fixes
Patch211: kvm-virtiofsd-load_capng-missing-unlock.patch
# For bz#1797064 - virtiofsd: Fixes
Patch212: kvm-virtiofsd-do_read-missing-NULL-check.patch
# For bz#1797064 - virtiofsd: Fixes
Patch213: kvm-tools-virtiofsd-fuse_lowlevel-Fix-fuse_out_header-er.patch
# For bz#1797064 - virtiofsd: Fixes
Patch214: kvm-virtiofsd-passthrough_ll-cleanup-getxattr-listxattr.patch
# For bz#1797064 - virtiofsd: Fixes
Patch215: kvm-virtiofsd-Fix-xattr-operations.patch
BuildRequires: wget
BuildRequires: rpm-build
@ -1461,6 +1497,32 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
%changelog
* Wed Mar 11 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-14.el8
- kvm-hw-smbios-set-new-default-SMBIOS-fields-for-Windows-.patch [bz#1782529]
- kvm-migration-multifd-clean-pages-after-filling-packet.patch [bz#1738451]
- kvm-migration-Make-sure-that-we-don-t-call-write-in-case.patch [bz#1738451]
- kvm-migration-multifd-fix-nullptr-access-in-terminating-.patch [bz#1738451]
- kvm-migration-multifd-fix-destroyed-mutex-access-in-term.patch [bz#1738451]
- kvm-multifd-Make-sure-that-we-don-t-do-any-IO-after-an-e.patch [bz#1738451]
- kvm-qemu-file-Don-t-do-IO-after-shutdown.patch [bz#1738451]
- kvm-migration-Don-t-send-data-if-we-have-stopped.patch [bz#1738451]
- kvm-migration-Create-migration_is_running.patch [bz#1738451]
- kvm-migration-multifd-fix-nullptr-access-in-multifd_send.patch [bz#1738451]
- kvm-migration-Maybe-VM-is-paused-when-migration-is-cance.patch [bz#1738451]
- kvm-virtiofsd-Remove-fuse_req_getgroups.patch [bz#1797064]
- kvm-virtiofsd-fv_create_listen_socket-error-path-socket-.patch [bz#1797064]
- kvm-virtiofsd-load_capng-missing-unlock.patch [bz#1797064]
- kvm-virtiofsd-do_read-missing-NULL-check.patch [bz#1797064]
- kvm-tools-virtiofsd-fuse_lowlevel-Fix-fuse_out_header-er.patch [bz#1797064]
- kvm-virtiofsd-passthrough_ll-cleanup-getxattr-listxattr.patch [bz#1797064]
- kvm-virtiofsd-Fix-xattr-operations.patch [bz#1797064]
- Resolves: bz#1738451
(qemu on src host core dump after set multifd-channels and do migration twice (first migration execute migrate_cancel))
- Resolves: bz#1782529
(Windows Update Enablement with default smbios strings in qemu)
- Resolves: bz#1797064
(virtiofsd: Fixes)
* Sat Feb 29 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-13.el8
- kvm-target-i386-kvm-initialize-feature-MSRs-very-early.patch [bz#1791648]
- kvm-target-i386-add-a-ucode-rev-property.patch [bz#1791648]