From 8d74e190054f8a2254f9da5a0eb2e17c66df94db Mon Sep 17 00:00:00 2001 From: John Snow Date: Fri, 16 Sep 2016 22:06:28 +0200 Subject: blockdev: ignore cache options for empty CDROM drives RH-Author: John Snow Message-id: <1474063588-6370-2-git-send-email-jsnow@redhat.com> Patchwork-id: 72377 O-Subject: [RHEV-7.3 qemu-kvm-rhev PATCH 1/1] blockdev: ignore cache options for empty CDROM drives Bugzilla: 1342999 RH-Acked-by: Max Reitz RH-Acked-by: Kevin Wolf RH-Acked-by: Stefan Hajnoczi In qemu-kvm-rhev-2.3.0, QEMU will accept cache options for empty CDROM devices, but silently ignore them as they will be overwritten when the next CDROM is inserted. Libvirt and VMM are capable of generating XML configurations which attempt to specify these cache options to QEMU, though they don't have any effect. Upstream, a refactoring of cache option mechanisms means that we have started rejecting invalid configurations where cache options are supplied without any target to actually apply them to. This means that there are combinations of QEMU and libvirt that will fail to start a VM if a user selects a cache option. This patch is a downstream-only workaround until libvirt can stop supplying cache settings for empty CDROMs and/or until libvirt can take advantage of the new QMP tray/medium manipulation mechanisms that will allow proper cache specification for removable media. Signed-off-by: John Snow Signed-off-by: Miroslav Rezanina (cherry picked from commit 89b162019bfd202bbbd00563d03a030c2f7c1395) (cherry picked from commit 454f60447bfea904d561ef282fc0446229484c02) (cherry picked from commit 50e4b1d94ce41a9c83034d372caea6ed20d6fcfb) (cherry picked from commit 54994db40273e0b4bec5f703459fdb71a453a373) (cherry picked from commit 0f4f6f39126ba96a4b288bb13bcd0f13eb46fa35) --- blockdev.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/blockdev.c b/blockdev.c index e941b99..cf10108 100644 --- a/blockdev.c +++ b/blockdev.c @@ -460,6 +460,32 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags, } } +/** + * libvirt expects to be able to pass cache options for CDROM drives without + * inserted media. Historically, QEMU eventually ignores these cache options as + * they are lost when media is inserted. Recently, QEMU started rejecting these + * configurations. Libvirt however still generates such configurations. + * + * To prevent QEMU from being unable to start, pretend there are no options + * present if the only options present are cache options for the BDS. + */ +static bool __redhat_com_has_bs_opts(QDict *bs_opts) +{ + size_t n, s; + s = qdict_size(bs_opts); + + if (s == 0) { + return false; + } else if (s > 2) { + return true; + } + + n = qdict_haskey(bs_opts, BDRV_OPT_CACHE_DIRECT); + n += qdict_haskey(bs_opts, BDRV_OPT_CACHE_NO_FLUSH); + + return s != n; +} + /* Takes the ownership of bs_opts */ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, Error **errp) @@ -567,7 +593,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false); /* init */ - if ((!file || !*file) && !qdict_size(bs_opts)) { + if ((!file || !*file) && !__redhat_com_has_bs_opts(bs_opts)) { BlockBackendRootState *blk_rs; blk = blk_new(0, BLK_PERM_ALL); -- 1.8.3.1