* Fri Feb 08 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 3.1.0-13.el8

- kvm-io-ensure-UNIX-client-doesn-t-unlink-server-socket.patch [bz#1665896]
- kvm-scsi-disk-Don-t-use-empty-string-as-device-id.patch [bz#1668248]
- kvm-scsi-disk-Add-device_id-property.patch [bz#1668248]
- Resolves: bz#1665896
  (VNC unix listener socket is deleted after first client quits)
- Resolves: bz#1668248
  ("An unknown error has occurred" when using cdrom to install the system with two blockdev disks.(when choose installation destination))
This commit is contained in:
Danilo C. L. de Paula 2019-02-08 12:18:59 +00:00
parent df2f32921c
commit 1cbaf605ab
4 changed files with 477 additions and 1 deletions

View File

@ -0,0 +1,294 @@
From dea7d39cce3b1da16de0bfb47a028f770547098a Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Tue, 29 Jan 2019 13:58:57 +0000
Subject: [PATCH 1/3] io: ensure UNIX client doesn't unlink server socket
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: <20190129135857.10581-2-berrange@redhat.com>
Patchwork-id: 84141
O-Subject: [RHEL-8.0/AV qemu-kvm PATCH 1/1] io: ensure UNIX client doesn't unlink server socket
Bugzilla: 1665896
RH-Acked-by: John Snow <jsnow@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
The qio_channel_socket_close method for was mistakenly unlinking the
UNIX server socket, even if the channel was a client connection. This
was not noticed with chardevs, since they never call close, but with the
VNC server, this caused the VNC server socket to be deleted after the
first client quit.
The qio_channel_socket_close method also needlessly reimplemented the
logic that already exists in socket_listen_cleanup(). Just call that
method directly, for listen sockets only.
This fixes a regression introduced in QEMU 3.0.0 with
commit d66f78e1eaa832f73c771d9df1b606fe75d52a50
Author: Pavel Balaev <mail@void.so>
Date: Mon May 21 19:17:35 2018 +0300
Delete AF_UNIX socket after close
Fixes launchpad #1795100
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 73564c407caedf992a1c688b5fea776a8b56ba2a)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
io/channel-socket.c | 19 ++--------
tests/test-io-channel-socket.c | 86 +++++++++++++++++++++++++++++++++++++-----
2 files changed, 80 insertions(+), 25 deletions(-)
diff --git a/io/channel-socket.c b/io/channel-socket.c
index b50e63a..bc5f80e 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -688,10 +688,13 @@ qio_channel_socket_close(QIOChannel *ioc,
int rc = 0;
if (sioc->fd != -1) {
- SocketAddress *addr = socket_local_address(sioc->fd, errp);
#ifdef WIN32
WSAEventSelect(sioc->fd, NULL, 0);
#endif
+ if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_LISTEN)) {
+ socket_listen_cleanup(sioc->fd, errp);
+ }
+
if (closesocket(sioc->fd) < 0) {
sioc->fd = -1;
error_setg_errno(errp, errno,
@@ -699,20 +702,6 @@ qio_channel_socket_close(QIOChannel *ioc,
return -1;
}
sioc->fd = -1;
-
- if (addr && addr->type == SOCKET_ADDRESS_TYPE_UNIX
- && addr->u.q_unix.path) {
- if (unlink(addr->u.q_unix.path) < 0 && errno != ENOENT) {
- error_setg_errno(errp, errno,
- "Failed to unlink socket %s",
- addr->u.q_unix.path);
- rc = -1;
- }
- }
-
- if (addr) {
- qapi_free_SocketAddress(addr);
- }
}
return rc;
}
diff --git a/tests/test-io-channel-socket.c b/tests/test-io-channel-socket.c
index 0597213..c253ae3 100644
--- a/tests/test-io-channel-socket.c
+++ b/tests/test-io-channel-socket.c
@@ -49,6 +49,7 @@ static void test_io_channel_set_socket_bufs(QIOChannel *src,
static void test_io_channel_setup_sync(SocketAddress *listen_addr,
SocketAddress *connect_addr,
+ QIOChannel **srv,
QIOChannel **src,
QIOChannel **dst)
{
@@ -78,7 +79,7 @@ static void test_io_channel_setup_sync(SocketAddress *listen_addr,
test_io_channel_set_socket_bufs(*src, *dst);
- object_unref(OBJECT(lioc));
+ *srv = QIO_CHANNEL(lioc);
}
@@ -99,6 +100,7 @@ static void test_io_channel_complete(QIOTask *task,
static void test_io_channel_setup_async(SocketAddress *listen_addr,
SocketAddress *connect_addr,
+ QIOChannel **srv,
QIOChannel **src,
QIOChannel **dst)
{
@@ -146,21 +148,34 @@ static void test_io_channel_setup_async(SocketAddress *listen_addr,
qio_channel_set_delay(*src, false);
test_io_channel_set_socket_bufs(*src, *dst);
- object_unref(OBJECT(lioc));
+ *srv = QIO_CHANNEL(lioc);
g_main_loop_unref(data.loop);
}
+static void test_io_channel_socket_path_exists(SocketAddress *addr,
+ bool expectExists)
+{
+ if (addr->type != SOCKET_ADDRESS_TYPE_UNIX) {
+ return;
+ }
+
+ g_assert(g_file_test(addr->u.q_unix.path,
+ G_FILE_TEST_EXISTS) == expectExists);
+}
+
+
static void test_io_channel(bool async,
SocketAddress *listen_addr,
SocketAddress *connect_addr,
bool passFD)
{
- QIOChannel *src, *dst;
+ QIOChannel *src, *dst, *srv;
QIOChannelTest *test;
if (async) {
- test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);
+ test_io_channel_setup_async(listen_addr, connect_addr,
+ &srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@@ -169,14 +184,25 @@ static void test_io_channel(bool async,
g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
test = qio_channel_test_new();
qio_channel_test_run_threads(test, true, src, dst);
qio_channel_test_validate(test);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ /* unref without close, to ensure finalize() cleans up */
+
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ test_io_channel_socket_path_exists(listen_addr, true);
- test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);
+ object_unref(OBJECT(srv));
+ test_io_channel_socket_path_exists(listen_addr, false);
+
+ test_io_channel_setup_async(listen_addr, connect_addr,
+ &srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@@ -189,10 +215,24 @@ static void test_io_channel(bool async,
qio_channel_test_run_threads(test, false, src, dst);
qio_channel_test_validate(test);
+ /* close before unref, to ensure finalize copes with already closed */
+
+ qio_channel_close(src, &error_abort);
+ qio_channel_close(dst, &error_abort);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ qio_channel_close(srv, &error_abort);
+ test_io_channel_socket_path_exists(listen_addr, false);
+
+ object_unref(OBJECT(srv));
+ test_io_channel_socket_path_exists(listen_addr, false);
} else {
- test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
+ test_io_channel_setup_sync(listen_addr, connect_addr,
+ &srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@@ -201,14 +241,25 @@ static void test_io_channel(bool async,
g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
test = qio_channel_test_new();
qio_channel_test_run_threads(test, true, src, dst);
qio_channel_test_validate(test);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ /* unref without close, to ensure finalize() cleans up */
+
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ object_unref(OBJECT(srv));
+ test_io_channel_socket_path_exists(listen_addr, false);
- test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
+ test_io_channel_setup_sync(listen_addr, connect_addr,
+ &srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@@ -221,8 +272,23 @@ static void test_io_channel(bool async,
qio_channel_test_run_threads(test, false, src, dst);
qio_channel_test_validate(test);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ /* close before unref, to ensure finalize copes with already closed */
+
+ qio_channel_close(src, &error_abort);
+ qio_channel_close(dst, &error_abort);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ qio_channel_close(srv, &error_abort);
+ test_io_channel_socket_path_exists(listen_addr, false);
+
+ object_unref(OBJECT(srv));
+ test_io_channel_socket_path_exists(listen_addr, false);
}
}
@@ -316,7 +382,6 @@ static void test_io_channel_unix(bool async)
qapi_free_SocketAddress(listen_addr);
qapi_free_SocketAddress(connect_addr);
- g_assert(g_file_test(TEST_SOCKET, G_FILE_TEST_EXISTS) == FALSE);
}
@@ -335,7 +400,7 @@ static void test_io_channel_unix_fd_pass(void)
{
SocketAddress *listen_addr = g_new0(SocketAddress, 1);
SocketAddress *connect_addr = g_new0(SocketAddress, 1);
- QIOChannel *src, *dst;
+ QIOChannel *src, *dst, *srv;
int testfd;
int fdsend[3];
int *fdrecv = NULL;
@@ -359,7 +424,7 @@ static void test_io_channel_unix_fd_pass(void)
connect_addr->type = SOCKET_ADDRESS_TYPE_UNIX;
connect_addr->u.q_unix.path = g_strdup(TEST_SOCKET);
- test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
+ test_io_channel_setup_sync(listen_addr, connect_addr, &srv, &src, &dst);
memcpy(bufsend, "Hello World", G_N_ELEMENTS(bufsend));
@@ -412,6 +477,7 @@ static void test_io_channel_unix_fd_pass(void)
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ object_unref(OBJECT(srv));
qapi_free_SocketAddress(listen_addr);
qapi_free_SocketAddress(connect_addr);
unlink(TEST_SOCKET);
--
1.8.3.1

View File

@ -0,0 +1,98 @@
From c9f6e5639cc9d7b1d336b55ccacb6673933a3864 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 6 Feb 2019 15:58:29 +0000
Subject: [PATCH 3/3] scsi-disk: Add device_id property
RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <20190206155829.14641-3-kwolf@redhat.com>
Patchwork-id: 84254
O-Subject: [RHEL-7.7/8.0-AV qemu-kvm-rhev PATCH 2/2] scsi-disk: Add device_id property
Bugzilla: 1668248
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
The new device_id property specifies which value to use for the vendor
specific designator in the Device Identification VPD page.
In particular, this is necessary for libvirt to maintain guest ABI
compatibility when no serial number is given and a VM is switched from
-drive (where the BlockBackend name is used) to -blockdev (where the
vendor specific designator is left out by default).
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 7471a649fc3a391dd497297013fb2525ca9821ba)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
hw/scsi/scsi-disk.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 93eef40..e74e1e7 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -104,6 +104,7 @@ typedef struct SCSIDiskState
char *serial;
char *vendor;
char *product;
+ char *device_id;
bool tray_open;
bool tray_locked;
/*
@@ -642,13 +643,8 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
case 0x83: /* Device identification page, mandatory */
{
- const char *str = s->serial ?: blk_name(s->qdev.conf.blk);
- int max_len = s->serial ? 20 : 255 - 8;
- int id_len = strlen(str);
+ int id_len = s->device_id ? MIN(strlen(s->device_id), 255 - 8) : 0;
- if (id_len > max_len) {
- id_len = max_len;
- }
DPRINTF("Inquiry EVPD[Device identification] "
"buffer size %zd\n", req->cmd.xfer);
@@ -657,7 +653,7 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
outbuf[buflen++] = 0; /* not officially assigned */
outbuf[buflen++] = 0; /* reserved */
outbuf[buflen++] = id_len; /* length of data following */
- memcpy(outbuf + buflen, str, id_len);
+ memcpy(outbuf + buflen, s->device_id, id_len);
buflen += id_len;
}
@@ -2363,6 +2359,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
if (!s->vendor) {
s->vendor = g_strdup("QEMU");
}
+ if (!s->device_id) {
+ if (s->serial) {
+ s->device_id = g_strdup_printf("%.20s", s->serial);
+ } else {
+ const char *str = blk_name(s->qdev.conf.blk);
+ if (str && *str) {
+ s->device_id = g_strdup(str);
+ }
+ }
+ }
if (blk_is_sg(s->qdev.conf.blk)) {
error_setg(errp, "unwanted /dev/sg*");
@@ -2904,7 +2910,9 @@ static const TypeInfo scsi_disk_base_info = {
DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \
DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \
- DEFINE_PROP_STRING("product", SCSIDiskState, product)
+ DEFINE_PROP_STRING("product", SCSIDiskState, product), \
+ DEFINE_PROP_STRING("device_id", SCSIDiskState, device_id)
+
static Property scsi_hd_properties[] = {
DEFINE_SCSI_DISK_PROPERTIES(),
--
1.8.3.1

View File

@ -0,0 +1,71 @@
From 18d600a76319abe59dc4b5e371e5807c089f9159 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 6 Feb 2019 15:58:28 +0000
Subject: [PATCH 2/3] scsi-disk: Don't use empty string as device id
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <20190206155829.14641-2-kwolf@redhat.com>
Patchwork-id: 84253
O-Subject: [RHEL-7.7/8.0-AV qemu-kvm-rhev PATCH 1/2] scsi-disk: Don't use empty string as device id
Bugzilla: 1668248
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
scsi-disk includes in the Device Identification VPD page, depending on
configuration amongst others, a vendor specific designator that consists
either of the serial number if given or the BlockBackend name (which is
a host detail that better shouldn't have been leaked to the guest, but
now we have to maintain it for compatibility).
With anonymous BlockBackends, i.e. scsi-disk devices constructed with
drive=<node-name>, and no serial number explicitly specified, this ends
up as an empty string. If this happens to more than one disk, we have
accidentally signalled to the OS that this is a multipath setup, which
is obviously not what was intended.
Instead of using an empty string for the vendor specific designator,
simply leave out that designator, which makes Linux detect such setups
as separate disks again.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
(cherry picked from commit a8f58afcdb86e266e06c9dc41a71605e570244c3)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
hw/scsi/scsi-disk.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 0e9027c..93eef40 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -652,12 +652,14 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
DPRINTF("Inquiry EVPD[Device identification] "
"buffer size %zd\n", req->cmd.xfer);
- outbuf[buflen++] = 0x2; /* ASCII */
- outbuf[buflen++] = 0; /* not officially assigned */
- outbuf[buflen++] = 0; /* reserved */
- outbuf[buflen++] = id_len; /* length of data following */
- memcpy(outbuf + buflen, str, id_len);
- buflen += id_len;
+ if (id_len) {
+ outbuf[buflen++] = 0x2; /* ASCII */
+ outbuf[buflen++] = 0; /* not officially assigned */
+ outbuf[buflen++] = 0; /* reserved */
+ outbuf[buflen++] = id_len; /* length of data following */
+ memcpy(outbuf + buflen, str, id_len);
+ buflen += id_len;
+ }
if (s->qdev.wwn) {
outbuf[buflen++] = 0x1; /* Binary */
--
1.8.3.1

View File

@ -174,6 +174,12 @@ Patch44: kvm-throttle-groups-fix-restart-coroutine-iothread-race.patch
Patch45: kvm-iotests-add-238-for-throttling-tgm-unregister-iothre.patch
# For bz#1668244 - qemu-img: /var/tmp/v2vovl9951f8.qcow2: CURL: Error opening file: The requested URL returned error: 404 Not Found
Patch47: kvm-json-Fix-handling-when-not-interpolating.patch
# For bz#1665896 - VNC unix listener socket is deleted after first client quits
Patch48: kvm-io-ensure-UNIX-client-doesn-t-unlink-server-socket.patch
# For bz#1668248 - "An unknown error has occurred" when using cdrom to install the system with two blockdev disks.(when choose installation destination)
Patch49: kvm-scsi-disk-Don-t-use-empty-string-as-device-id.patch
# For bz#1668248 - "An unknown error has occurred" when using cdrom to install the system with two blockdev disks.(when choose installation destination)
Patch50: kvm-scsi-disk-Add-device_id-property.patch
BuildRequires: zlib-devel
BuildRequires: glib2-devel
@ -1021,8 +1027,15 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
%changelog
* Thu Jan 31 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 3.1.0-12.el8
* Fri Feb 08 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 3.1.0-12.el8
- Removing kvm-Fix-fsfreeze-hook-path-in-the-man-page.patch [bz#1644985]
- kvm-io-ensure-UNIX-client-doesn-t-unlink-server-socket.patch [bz#1665896]
- kvm-scsi-disk-Don-t-use-empty-string-as-device-id.patch [bz#1668248]
- kvm-scsi-disk-Add-device_id-property.patch [bz#1668248]
- Resolves: bz#1665896
(VNC unix listener socket is deleted after first client quits)
- Resolves: bz#1668248
("An unknown error has occurred" when using cdrom to install the system with two blockdev disks.(when choose installation destination))
* Thu Jan 31 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 3.1.0-11.el8
- kvm-Fix-fsfreeze-hook-path-in-the-man-page.patch [bz#1644985]