RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 1491217 - blockPeek() return wrong contents of a domain's disk device.
Summary: blockPeek() return wrong contents of a domain's disk device.
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: libvirt
Version: 7.5
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: rc
: ---
Assignee: Peter Krempa
QA Contact: Han Han
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2017-09-13 10:41 UTC by lcheng
Modified: 2018-04-10 10:58 UTC (History)
7 users (show)

Fixed In Version: libvirt-3.8.0-1.el7
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2018-04-10 10:57:19 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHEA-2018:0704 0 None None None 2018-04-10 10:58:32 UTC

Description lcheng 2017-09-13 10:41:41 UTC
Description:
blockPeek() return wrong contents of a domain's disk device.


Version:
libvirt-python-3.7.0-1.el7.x86_64
libvirt-3.7.0-2.el7.x86_64
qemu-kvm-rhev-2.9.0-16.el7_4.6.x86_64


How reproduced:
100%

Steps:
1. Prepare a running domain.

2. Execute following steps.
>>> import os
>>> import libvirt
>>> conn = libvirt.open()
>>> dom = conn.lookupByName("test")
>>> dom.isActive()
1
>>> dom.blockPeek("vda", 0, 16, 0)
'\x80\n\x00D;\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> dom.blockPeek("vda", 0, 16, 0)
'\x80\n\x00H;\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> dom.blockPeek("vda", 0, 16, 0)
'\x80\n\x00L;\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> dom.blockPeek("vda", 0, 16, 0)
'\xb0\n\x00@;\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> dom.blockPeek("vda", 0, 16, 0)
'0A\x00P;\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'



3. Using hexdump command to check the contents of the domain's disk device.
# hexdump /var/lib/libvirt/images/libvirt-test-api -n 16 -s 0
0000000 63eb 1090 d08e 00bc b8b0 0000 d88e c08e
0000010


Actual result:
In step 2, when blockPeek() is called many times, we get different contents every time.

Expected result:
We can get the same contents every time.


Additional info:
We can get the same contents on rhel 7.4.


libvirt-3.2.0-14.el7_4.3.x86_64
libvirt-python-3.2.0-3.el7.x86_64
qemu-kvm-rhev-2.9.0-16.el7_4.5.x86_64

>>> import libvirt
>>> conn = libvirt.open()
>>> dom = conn.lookupByName("test")
>>> dom.blockPeek("vda", 0, 16, 0)
'QFI\xfb\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00'
>>> dom.blockPeek("vda", 0, 16, 0)
'QFI\xfb\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00'
>>> dom.blockPeek("vda", 0, 16, 0)
'QFI\xfb\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00'
>>> quit()

Comment 2 Peter Krempa 2017-09-13 14:32:11 UTC
I probably broke it by commit:

commit 3956af495ecb84dc79f6c1c23d221e868aaf3ab5
Author: Peter Krempa <pkrempa>
Date:   Fri May 12 15:33:33 2017 +0200

    qemu: Use storage driver APIs in qemuDomainBlockPeek
    
    Refactor the access to storage driver usage along with
    qemuDomainStorageFileInit which ensures that we access the file with
    correct DAC uid/gid.


I'll investigate.

Comment 3 Peter Krempa 2017-09-18 14:08:29 UTC
Yes, the commit broke it. Moving to the 'libvirt' component since it's a bug in libvirtd.

Comment 4 Peter Krempa 2017-09-19 15:33:35 UTC
Fixed upstream:

commit f767d53dbe484f33d71c173b3fa890515a91103b
Author: Peter Krempa <pkrempa>
Date:   Mon Sep 18 16:03:58 2017 +0200

    qemu: blockPeek: Fix filling of the return buffer
    
    Commit 3956af495e broke the blockPeek API since virStorageFileRead
    allocates a return buffer and fills it with the data, while the API
    fills a user-provided buffer. This did not get caught by the compiler
    since the API prototype uses a 'void *'.
    
    Fix it by transferring the data from the allocated buffer to the user
    provided buffer.

Comment 7 Han Han 2017-11-01 08:52:40 UTC
Verify it on qemu-kvm-rhev-2.10.0-3.el7.x86_64 libvirt-3.8.0-1.el7.x86_64.
As we know, in an VM with OS, the sectors before first partition usuallly are not written. So I will verify this bug by blockpeek from the first 2048 sectors.

Check the disk in VM:
# fdisk -l /dev/vda                                                

Disk /dev/vda: 10.7 GB, 10737418240 bytes, 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b77dd

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048     2099199     1048576   83  Linux
/dev/vda2         2099200    20971519     9436160   8e  Linux LVM

I write a script to check the hash digest of data from the first 2048 sectors by blockpeek for 9 times. Then check if all hash digests are the same. If yes, bug fixed while no means bug unfixed.

The script:
```
#!/usr/bin/env python
import libvirt
import hashlib
import time
# The target device
DISK_TARGET = "vda"
# Data size of blockpeek
PEEK_SIZE = 2048
# Interval between blockpeek operations
SLEEP_TIME = 2
conn = libvirt.open("qemu:///system")
dom = conn.lookupByName("V-raw")
hexdigest_list = []
for i in range(1,9):
    sha1 = hashlib.sha1()
# Calculate the sha1 digest of data from blockpeek
    sha1.update(dom.blockPeek("vda", 0, PEEK_SIZE, 0))
    hexdigest_list.append(sha1.hexdigest())
    time.sleep(SLEEP_TIME)
# Check if all hash digests are the same
print set(hexdigest_list)
```

Result:
set(['8e6067cc31ccc0b52440a16d711695ca9dac08c6'])

All hash digests are 8e6067cc31ccc0b52440a16d711695ca9dac08c6. Bug fixed.

Comment 11 errata-xmlrpc 2018-04-10 10:57:19 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHEA-2018:0704


Note You need to log in before you can comment on or make changes to this bug.