diff --git a/qemu.changes b/qemu.changes index 3b931b5..f627e79 100644 --- a/qemu.changes +++ b/qemu.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Dec 21 04:18:07 UTC 2021 - Lin Ma + +- [JIRA] (SLE-20965) Make QEMU guests more failsafe when resizing + SCSI passthrough disks + * Patches added: + scsi-generic-replace-logical-block-count.patch + ------------------------------------------------------------------- Thu Dec 16 21:54:06 UTC 2021 - Li Zhang diff --git a/qemu.spec b/qemu.spec index 8945182..d8897b6 100644 --- a/qemu.spec +++ b/qemu.spec @@ -180,6 +180,7 @@ Patch00044: Revert-qemu-img-Require-F-with-b-backing.patch Patch00045: qemu-binfmt-conf.sh-should-use-F-as-shor.patch Patch00046: modules-quick-fix-a-fundamental-error-in.patch Patch00047: qemu-binfmt-conf.sh-allow-overriding-SUS.patch +Patch00048: scsi-generic-replace-logical-block-count.patch # Patches applied in roms/seabios/: Patch01000: seabios-use-python2-explicitly-as-needed.patch Patch01001: seabios-switch-to-python3-as-needed.patch @@ -1127,6 +1128,7 @@ This package records qemu testsuite results and represents successful testing. %patch00045 -p1 %patch00046 -p1 %patch00047 -p1 +%patch00048 -p1 %patch01000 -p1 %patch01001 -p1 %patch01002 -p1 diff --git a/scsi-generic-replace-logical-block-count.patch b/scsi-generic-replace-logical-block-count.patch new file mode 100644 index 0000000..9326b7a --- /dev/null +++ b/scsi-generic-replace-logical-block-count.patch @@ -0,0 +1,103 @@ +From: Lin Ma +Date: Sat, 20 Nov 2021 18:05:57 +0800 +Subject: scsi-generic: replace logical block count of response of READ + CAPACITY +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Git-commit: 0000000000000000000000000000000000000000 +References: [SUSE-JIRA] (SLE-20965) + +While using SCSI passthrough, Following scenario makes qemu doesn't +realized the capacity change of remote scsi target: +1. online resize the scsi target. +2. issue 'rescan-scsi-bus.sh -s ...' in host. +3. issue 'rescan-scsi-bus.sh -s ...' in vm. + +In above scenario I used to experienced errors while accessing the +additional disk space in vm. I think the reasonable operations should +be: +1. online resize the scsi target. +2. issue 'rescan-scsi-bus.sh -s ...' in host. +3. issue 'block_resize' via qmp to notify qemu. +4. issue 'rescan-scsi-bus.sh -s ...' in vm. + +The errors disappear once I notify qemu by block_resize via qmp. + +So this patch replaces the number of logical blocks of READ CAPACITY +response from scsi target by qemu's bs->total_sectors. If the user in +vm wants to access the additional disk space, The administrator of +host must notify qemu once resizeing the scsi target. + +Bonus is that domblkinfo of libvirt can reflect the consistent capacity +information between host and vm in case of missing block_resize in qemu. +E.g: +... + + + + + + +
+ +... + +Before: +1. online resize the scsi target. +2. host:~ # rescan-scsi-bus.sh -s /dev/sdc +3. guest:~ # rescan-scsi-bus.sh -s /dev/sda +4 host:~ # virsh domblkinfo --domain $DOMAIN --human --device sda +Capacity: 4.000 GiB +Allocation: 0.000 B +Physical: 8.000 GiB + +5. guest:~ # lsblk /dev/sda +NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT +sda 8:0 0 8G 0 disk +└─sda1 8:1 0 2G 0 part + +After: +1. online resize the scsi target. +2. host:~ # rescan-scsi-bus.sh -s /dev/sdc +3. guest:~ # rescan-scsi-bus.sh -s /dev/sda +4 host:~ # virsh domblkinfo --domain $DOMAIN --human --device sda +Capacity: 4.000 GiB +Allocation: 0.000 B +Physical: 8.000 GiB + +5. guest:~ # lsblk /dev/sda +NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT +sda 8:0 0 4G 0 disk +└─sda1 8:1 0 2G 0 part + +Signed-off-by: Lin Ma +--- + hw/scsi/scsi-generic.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c +index 0306ccc7b1e4827a67aaed926f93..343b51c2c0ab5dc7fb792aeb6458 100644 +--- a/hw/scsi/scsi-generic.c ++++ b/hw/scsi/scsi-generic.c +@@ -315,11 +315,17 @@ static void scsi_read_complete(void * opaque, int ret) + if (r->req.cmd.buf[0] == READ_CAPACITY_10 && + (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) { + s->blocksize = ldl_be_p(&r->buf[4]); +- s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL; ++ BlockBackend *blk = s->conf.blk; ++ BlockDriverState *bs = blk_bs(blk); ++ s->max_lba = bs->total_sectors - 1; ++ stl_be_p(&r->buf[0], s->max_lba); + } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 && + (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { + s->blocksize = ldl_be_p(&r->buf[8]); +- s->max_lba = ldq_be_p(&r->buf[0]); ++ BlockBackend *blk = s->conf.blk; ++ BlockDriverState *bs = blk_bs(blk); ++ s->max_lba = bs->total_sectors - 1; ++ stq_be_p(&r->buf[0], s->max_lba); + } + blk_set_guest_block_size(s->conf.blk, s->blocksize); +