[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH] block: always update auto_backing_file to full path
From: |
Joe Jin |
Subject: |
Re: [RFC PATCH] block: always update auto_backing_file to full path |
Date: |
Thu, 1 Apr 2021 14:47:05 -0700 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 |
Hi Max,
Thanks very much for your replies.
On 4/1/21 2:57 AM, Max Reitz wrote:
> On 01.04.21 06:22, Joe Jin wrote:
>> Some time after created snapshot, auto_backing_file only has filename,
>> this confused overridden check, update it to full path if it is not.
>>
>> Signed-off-by: Joe Jin <joe.jin@oracle.com>
>> ---
>> block.c | 13 +++++++++++++
>> 1 file changed, 13 insertions(+)
>
> Do you have a test for this?
My issue is my guest image is on NFS, I could created snapshot from ovirt but I
could not delete it, tried to commit it by virsh and it complained qemu
internal error:
# virsh blockcommit snap-test sda --active --verbose --pivot
error: internal error: qemu block name 'json:{"backing": {"driver": "qcow2",
"file": {"driver": "file", "filename":
"/rhev/data-center/mnt/nfs_server:_nfsexport/fee77d23-1291-4bdb-9157-12ff6cd5ee96/images/66bb625e-7458-478d-a238-b012f87062b8/919a4cda-bf11-4bb7-a2e3-d9e4515ed646"}},
"driver": "qcow2", "file": {"driver": "file", "filename":
"/rhev/data-center/mnt/nfs_server:_nfsexport/fee77d23-1291-4bdb-9157-12ff6cd5ee96/images/66bb625e-7458-478d-a238-b012f87062b8/24d28fcd-67e3-49d2-8860-2110f3a5e796"}}'
doesn't match expected
'/rhev/data-center/mnt/nfs_server:_nfsexport/fee77d23-1291-4bdb-9157-12ff6cd5ee96/images/66bb625e-7458-478d-a238-b012f87062b8/24d28fcd-67e3-49d2-8860-2110f3a5e796'
Tracked qemu block and I found when issue happened, bdrv_backing_overridden()
was tried to compare absolute path(bs->backing->bs->filename) with relative
path(bs->auto_backing_file) but they are same filename, then it triggered
generated json filename.
Regarding auto_backing_file, it updated by qcow2_do_open(), and read the
backing file name from image:
/* read the backing file name */
if (header.backing_file_offset != 0) {
len = header.backing_file_size;
if (len > MIN(1023, s->cluster_size - header.backing_file_offset) ||
len >= sizeof(bs->backing_file)) {
error_setg(errp, "Backing file name too long");
ret = -EINVAL;
goto fail;
}
ret = bdrv_pread(bs->file, header.backing_file_offset,
bs->auto_backing_file, len);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not read backing file name");
goto fail;
}
bs->auto_backing_file[len] = '\0';
pstrcpy(bs->backing_file, sizeof(bs->backing_file),
bs->auto_backing_file);
s->image_backing_file = g_strdup(bs->auto_backing_file);
}
Updated auto_backing_file to absolute path, I could successfully delete
snapshot from ovirt, or execute blockcommit by virsh.
>
> The thing is, I’m not sure about this solution, and I think having a test
> would help me understand better.
> bs->auto_backing_file is meant to track what filename a BDS would have if we
> opened bs->backing_file. To this end, we generally set it to whatever
> bs->backing_file is and then refresh it when we actually do open a BDS from
> it.
>
> So it seems strange to blindly modify it somewhere that doesn’t have to do
> with any of these things.
>
> Now, when opening a backing file from bs->backing_file, we first do make it
> an absolute filename via bdrv_get_full_backing_filename(). So it kind of
> seems prudent to replicate that elsewhere, but I’m not sure where exactly. I
> would think the best place would be whenever auto_backing_file is set to be
> equal to backing_file (which is generally in the image format drivers, when
> they read the backing file string from the image metadata), but that might
> break the strcmp() in bdrv_open_backing_file()...
>
> I don’t think bdrv_refresh_filename() is the right place, though, because I’m
> afraid that this might modify filenames we’ve already retrieved from the
> actual backing BDS, or something.
>
> For example, with this patch applied, iotest 024 fails.
Yes after applied my patch, I can reproduced the failure, it caused by
bdrv_make_absolute_filename() returned relative path, not sure if this is
bdrv_make_absolute_filename() bug?
Added path_is_absolute(backing_filename) check before update auto_backing_file,
test passed:
+ backing_filename = bdrv_make_absolute_filename(bs,
bs->auto_backing_file, &local_err);
+ if (!local_err && backing_filename &&
path_is_absolute(backing_filename)) {
+ pstrcpy(bs->auto_backing_file, sizeof(bs->auto_backing_file),
+ backing_filename);
>
>> diff --git a/block.c b/block.c
>> index c5b887cec1..8f9a027dee 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -6969,6 +6969,19 @@ void bdrv_refresh_filename(BlockDriverState *bs)
>> return;
>> }
>> + /* auto_backing_file only has filename, update it to the full path */
>> + if (bs->backing && bs->auto_backing_file[0] != '/') {
>> + char *backing_filename = NULL;
>> + Error *local_err = NULL;
>> +
>> + backing_filename = bdrv_make_absolute_filename(bs,
>> + bs->auto_backing_file, &local_err);
>> + if (!local_err && backing_filename) {
>> + pstrcpy(bs->auto_backing_file, sizeof(bs->auto_backing_file),
>> + backing_filename);
>> + g_free(backing_filename);
>> + }
>> + }
>
> All spaces here are 0xa0 (non-breaking space), which is kind of broken and
> makes it difficult to apply this patch.
Sorry about this, I may use git send-email to send it.
>
> Furthermore, if local_err != NULL, we’d need to free it.
Thanks for reminder, will take care of this.
Thanks,
Joe
>
> Max
>
>> backing_overridden = bdrv_backing_overridden(bs);
>> if (bs->open_flags & BDRV_O_NO_IO) {
>>
>