[libvirt] [PATCH 0/5] qemu: Disk emptiness and disk migration fixes

Recent change to use virDomainDiskEmptySource broke internal snapshots since the check was not robust enough. While looking at it I found more brokenness. Peter Krempa (5): conf: Keep 'readonly' property when resetting disk source qemu: snapshot: Skip empty drives with internal snapshots qemu: migration: Skip cache=none check for disks which are storage-migrated qemu: migration: Use virStorageSourceIsEmpty in qemuMigrateDisk qemu: migration: Reject migration of an empty disk src/conf/domain_conf.c | 3 +++ src/qemu/qemu_driver.c | 3 ++- src/qemu/qemu_migration.c | 64 ++++++++++++++++++++++++++++------------------- 3 files changed, 43 insertions(+), 27 deletions(-) -- 2.12.2

The property is necessary also for the disk using the source (e.g. cdrom) which needs to be kept readonly. --- src/conf/domain_conf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 80baa090a..d660c06e0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1723,9 +1723,12 @@ void virDomainDiskEmptySource(virDomainDiskDefPtr def) { virStorageSourcePtr src = def->src; + bool readonly = src->readonly; virStorageSourceClear(src); src->type = VIR_STORAGE_TYPE_FILE; + /* readonly property is necessary for CDROMs and thus can't be cleared */ + src->readonly = readonly; } -- 2.12.2

On 04/07/2017 11:50 AM, Peter Krempa wrote:
The property is necessary also for the disk using the source (e.g. cdrom) which needs to be kept readonly. --- src/conf/domain_conf.c | 3 +++ 1 file changed, 3 insertions(+)
Wouldn't restoring readonly only be necessary "if (def->device == VIR_DOMAIN_DISK_DEVICE_CDROM)" since that's the primary reason it was set by libvirt? Of course it's only ever set at XML parse time, so would inserting a source path necessarily reset it for non CDROM's. Also know it's possible to check git history and all, could the commit message be adjusted to provide a few more shreds of information... Such as adding in "commit id '462c4b66' was a bit too aggressive and missed restoring the readonly flag for the storage source that is set by ParseXML for CDROM's" Of course this all makes me wonder if something else was too aggressively cleared/reset, but at least this much is perfectly understandable. ACK for what's here w/ a bit more details for the commit message... John As an aside, the API could have been called DiskSetEmptySource or DiskSetSourceEmpty... DiskEmptySource almost looks like a boolean function. Oh well different issue ;-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 80baa090a..d660c06e0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1723,9 +1723,12 @@ void virDomainDiskEmptySource(virDomainDiskDefPtr def) { virStorageSourcePtr src = def->src; + bool readonly = src->readonly;
virStorageSourceClear(src); src->type = VIR_STORAGE_TYPE_FILE; + /* readonly property is necessary for CDROMs and thus can't be cleared */ + src->readonly = readonly; }

The code that validates whether an internal snapshot is possible would reject an empty but not-readonly drive. Since floppies can have this property, add a check for emptiness. --- src/qemu/qemu_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 388af4f6f..e39de625d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13825,7 +13825,8 @@ qemuDomainSnapshotPrepare(virConnectPtr conn, case VIR_DOMAIN_SNAPSHOT_LOCATION_NONE: /* Remember seeing a disk that has snapshot disabled */ - if (!dom_disk->src->readonly) + if (!virStorageSourceIsEmpty(dom_disk->src) && + !dom_disk->src->readonly) forbid_internal = true; break; -- 2.12.2

On 04/07/2017 11:50 AM, Peter Krempa wrote:
The code that validates whether an internal snapshot is possible would reject an empty but not-readonly drive. Since floppies can have this property, add a check for emptiness. --- src/qemu/qemu_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Took a little while to think about this one - but essentially because LOCATION_NONE is being set when src->readonly (during XML parse) or when virStorageSourceIsEmpty during virDomainSnapshotAlignDisks, that means essentially that using LOCATION_NONE is "proper" for those disks and thus if we find LOCATION_NONE that means we didn't set it that way and thus the forbid_internal needs to be set. ACK - John

Since the disks are copied by qemu, there's no need to enforce cache=none. Thankfully the code that added qemuMigrateDisk did not break existing configs, since if you don't select any disk to migrate explicitly the code behaves sanely. The logic for determining whether a disk should be migrated is open-coded since using qemuMigrateDisk twice would be semantically incorrect. --- src/qemu/qemu_migration.c | 57 ++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d8222fe3b..5bd45137c 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1126,9 +1126,14 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, static bool qemuMigrationIsSafe(virDomainDefPtr def, size_t nmigrate_disks, - const char **migrate_disks) + const char **migrate_disks, + unsigned int flags) + { + bool storagemigration = flags & (VIR_MIGRATE_NON_SHARED_DISK | + VIR_MIGRATE_NON_SHARED_INC); size_t i; + int rc; for (i = 0; i < def->ndisks; i++) { virDomainDiskDefPtr disk = def->disks[i]; @@ -1136,29 +1141,35 @@ qemuMigrationIsSafe(virDomainDefPtr def, /* Our code elsewhere guarantees shared disks are either readonly (in * which case cache mode doesn't matter) or used with cache=none */ - if (qemuMigrateDisk(disk, nmigrate_disks, migrate_disks) && - disk->cachemode != VIR_DOMAIN_DISK_CACHE_DISABLE) { - int rc; + if (virStorageSourceIsEmpty(disk->src) || + disk->src->readonly || + disk->src->shared || + disk->cachemode == VIR_DOMAIN_DISK_CACHE_DISABLE) + continue; - if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_FILE) { - if ((rc = virFileIsSharedFS(src)) < 0) - return false; - else if (rc == 0) - continue; - if ((rc = virStorageFileIsClusterFS(src)) < 0) - return false; - else if (rc == 1) - continue; - } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK && - disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) { - continue; - } + /* disks which are migrated by qemu are safe too */ + if (storagemigration && + qemuMigrateDisk(disk, nmigrate_disks, migrate_disks)) + continue; - virReportError(VIR_ERR_MIGRATE_UNSAFE, "%s", - _("Migration may lead to data corruption if disks" - " use cache != none")); - return false; + if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_FILE) { + if ((rc = virFileIsSharedFS(src)) < 0) + return false; + else if (rc == 0) + continue; + if ((rc = virStorageFileIsClusterFS(src)) < 0) + return false; + else if (rc == 1) + continue; + } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK && + disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) { + continue; } + + virReportError(VIR_ERR_MIGRATE_UNSAFE, "%s", + _("Migration may lead to data corruption if disks" + " use cache != none")); + return false; } return true; @@ -1915,7 +1926,7 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver, goto cleanup; if (!(flags & VIR_MIGRATE_UNSAFE) && - !qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks)) + !qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks, flags)) goto cleanup; if (flags & VIR_MIGRATE_POSTCOPY && @@ -4773,7 +4784,7 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver, goto endjob; if (!(flags & VIR_MIGRATE_UNSAFE) && - !qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks)) + !qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks, flags)) goto endjob; qemuMigrationStoreDomainState(vm); -- 2.12.2

On 04/07/2017 11:50 AM, Peter Krempa wrote:
Since the disks are copied by qemu, there's no need to enforce cache=none. Thankfully the code that added qemuMigrateDisk did not break existing configs, since if you don't select any disk to migrate explicitly the code behaves sanely.
The logic for determining whether a disk should be migrated is open-coded since using qemuMigrateDisk twice would be semantically incorrect. --- src/qemu/qemu_migration.c | 57 ++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-)
Thanks for altering the multiple non-negative checks logic to the easier to read positive log... Still it feels like there's "two" things going on here w/ that storagemigration bool though.
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d8222fe3b..5bd45137c 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1126,9 +1126,14 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, static bool qemuMigrationIsSafe(virDomainDefPtr def, size_t nmigrate_disks, - const char **migrate_disks) + const char **migrate_disks, + unsigned int flags) + { + bool storagemigration = flags & (VIR_MIGRATE_NON_SHARED_DISK | + VIR_MIGRATE_NON_SHARED_INC); size_t i; + int rc;
for (i = 0; i < def->ndisks; i++) { virDomainDiskDefPtr disk = def->disks[i]; @@ -1136,29 +1141,35 @@ qemuMigrationIsSafe(virDomainDefPtr def,
/* Our code elsewhere guarantees shared disks are either readonly (in * which case cache mode doesn't matter) or used with cache=none */ - if (qemuMigrateDisk(disk, nmigrate_disks, migrate_disks) && - disk->cachemode != VIR_DOMAIN_DISK_CACHE_DISABLE) { - int rc; + if (virStorageSourceIsEmpty(disk->src) || + disk->src->readonly || + disk->src->shared || + disk->cachemode == VIR_DOMAIN_DISK_CACHE_DISABLE)
So this check is being done first to avoid the chance that a disk that was defined in the domain, but wasn't in some supplied migrate_disks doesn't erroneously cause a failure because qemuMigrateDisk would never do that last check which after patch 4 does the Empty, Read, Shared check.
+ continue;
- if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_FILE) { - if ((rc = virFileIsSharedFS(src)) < 0) - return false; - else if (rc == 0) - continue; - if ((rc = virStorageFileIsClusterFS(src)) < 0) - return false; - else if (rc == 1) - continue; - } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK && - disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) { - continue; - } + /* disks which are migrated by qemu are safe too */ + if (storagemigration &&
This is the part that seems to be 'extra' and not related to the commit message. IIUC the flags in question aren't necessarily supplied - so if they weren't supplied the subsequent check won't be made? Is that what is desired? Perhaps I'm missing something subtle or that's a "given" with those flags.
+ qemuMigrateDisk(disk, nmigrate_disks, migrate_disks)) + continue;
Also previously, if the qemuMigrateDisk was true (and cache != DISABLE), then the SharedFS/ClusterFS and RBD checks would be made. With this change as long as both MigrateDisk and those flags are true, the code would just go to the next disk and not check those flags. Again perhaps something subtle I'm missing. John
- virReportError(VIR_ERR_MIGRATE_UNSAFE, "%s", - _("Migration may lead to data corruption if disks" - " use cache != none")); - return false; + if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_FILE) { + if ((rc = virFileIsSharedFS(src)) < 0) + return false; + else if (rc == 0) + continue; + if ((rc = virStorageFileIsClusterFS(src)) < 0) + return false; + else if (rc == 1) + continue; + } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK && + disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) { + continue; } + + virReportError(VIR_ERR_MIGRATE_UNSAFE, "%s", + _("Migration may lead to data corruption if disks" + " use cache != none")); + return false; }
return true; @@ -1915,7 +1926,7 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver, goto cleanup;
if (!(flags & VIR_MIGRATE_UNSAFE) && - !qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks)) + !qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks, flags)) goto cleanup;
if (flags & VIR_MIGRATE_POSTCOPY && @@ -4773,7 +4784,7 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver, goto endjob;
if (!(flags & VIR_MIGRATE_UNSAFE) && - !qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks)) + !qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks, flags)) goto endjob;
qemuMigrationStoreDomainState(vm);

On Wed, Apr 12, 2017 at 19:43:20 -0400, John Ferlan wrote:
On 04/07/2017 11:50 AM, Peter Krempa wrote:
Since the disks are copied by qemu, there's no need to enforce cache=none. Thankfully the code that added qemuMigrateDisk did not break existing configs, since if you don't select any disk to migrate explicitly the code behaves sanely.
The logic for determining whether a disk should be migrated is open-coded since using qemuMigrateDisk twice would be semantically incorrect. --- src/qemu/qemu_migration.c | 57 ++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-)
Thanks for altering the multiple non-negative checks logic to the easier to read positive log...
Still it feels like there's "two" things going on here w/ that storagemigration bool though.
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d8222fe3b..5bd45137c 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1126,9 +1126,14 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, static bool qemuMigrationIsSafe(virDomainDefPtr def, size_t nmigrate_disks, - const char **migrate_disks) + const char **migrate_disks, + unsigned int flags) + { + bool storagemigration = flags & (VIR_MIGRATE_NON_SHARED_DISK | + VIR_MIGRATE_NON_SHARED_INC); size_t i; + int rc;
for (i = 0; i < def->ndisks; i++) { virDomainDiskDefPtr disk = def->disks[i]; @@ -1136,29 +1141,35 @@ qemuMigrationIsSafe(virDomainDefPtr def,
/* Our code elsewhere guarantees shared disks are either readonly (in * which case cache mode doesn't matter) or used with cache=none */ - if (qemuMigrateDisk(disk, nmigrate_disks, migrate_disks) && - disk->cachemode != VIR_DOMAIN_DISK_CACHE_DISABLE) { - int rc; + if (virStorageSourceIsEmpty(disk->src) || + disk->src->readonly || + disk->src->shared || + disk->cachemode == VIR_DOMAIN_DISK_CACHE_DISABLE)
So this check is being done first to avoid the chance that a disk that was defined in the domain, but wasn't in some supplied migrate_disks doesn't erroneously cause a failure because qemuMigrateDisk would never do that last check which after patch 4 does the Empty, Read, Shared check.
Well. No. This is what this function is supposed to check first. I've extracted it from qemuMigrateDisk which would basically have the same semantics if 'migrate_disks' is NULL/empty. It is semantically wrong to call that function at this place. The function returns whether a disk will be migrated when doing migration with non-shared storage. While the logic is the same, it is not correct to abuse it here.
+ continue;
- if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_FILE) { - if ((rc = virFileIsSharedFS(src)) < 0) - return false; - else if (rc == 0) - continue; - if ((rc = virStorageFileIsClusterFS(src)) < 0) - return false; - else if (rc == 1) - continue; - } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK && - disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) { - continue; - } + /* disks which are migrated by qemu are safe too */ + if (storagemigration &&
This is the part that seems to be 'extra' and not related to the commit message. IIUC the flags in question aren't necessarily supplied - so if
No. This is exactly what the first sentence of the commit message promises to fix.
they weren't supplied the subsequent check won't be made? Is that what is desired? Perhaps I'm missing something subtle or that's a "given" with those flags.
The flags contain the two bits which are checked if the user requires storage migration. In case where we migrate storage, we do not need to check that caching for the disks is disabled. This is due to the fact that the disks are migrated by qemu and thus there are no caching-coherency issues, since qemu copies all the data. This means that disks undergoing storage migration don't need to be checked for disabled caching.
+ qemuMigrateDisk(disk, nmigrate_disks, migrate_disks)) + continue;
Also previously, if the qemuMigrateDisk was true (and cache != DISABLE), then the SharedFS/ClusterFS and RBD checks would be made. With this change as long as both MigrateDisk and those flags are true, the code would just go to the next disk and not check those flags. Again perhaps something subtle I'm missing.
Yes, that's exactly what I wanted to achieve. The above addition of the same logich that qemuMigrateDisk does to determine if a disk should be migrated is precisely for the fact, that using qemuMigrateDisk at that point is semantically incorrect. So the logic is as follows: If the disk is empty, readonly, shared, or has disabled caching, it's safe to migrate. This is also for cases where shared storage is used and thus no storage migration takes place. If storage migration is used, then all disks which are migrated using the storage migration are safe to undergo migration, since the caching issue does not apply to them. All other disks need to be checked

On 04/13/2017 06:28 AM, Peter Krempa wrote:
On Wed, Apr 12, 2017 at 19:43:20 -0400, John Ferlan wrote:
On 04/07/2017 11:50 AM, Peter Krempa wrote:
Since the disks are copied by qemu, there's no need to enforce cache=none. Thankfully the code that added qemuMigrateDisk did not break existing configs, since if you don't select any disk to migrate explicitly the code behaves sanely.
The logic for determining whether a disk should be migrated is open-coded since using qemuMigrateDisk twice would be semantically incorrect. --- src/qemu/qemu_migration.c | 57 ++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-)
Thanks for altering the multiple non-negative checks logic to the easier to read positive log...
Still it feels like there's "two" things going on here w/ that storagemigration bool though.
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d8222fe3b..5bd45137c 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1126,9 +1126,14 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, static bool qemuMigrationIsSafe(virDomainDefPtr def, size_t nmigrate_disks, - const char **migrate_disks) + const char **migrate_disks, + unsigned int flags) + { + bool storagemigration = flags & (VIR_MIGRATE_NON_SHARED_DISK | + VIR_MIGRATE_NON_SHARED_INC); size_t i; + int rc;
for (i = 0; i < def->ndisks; i++) { virDomainDiskDefPtr disk = def->disks[i]; @@ -1136,29 +1141,35 @@ qemuMigrationIsSafe(virDomainDefPtr def,
/* Our code elsewhere guarantees shared disks are either readonly (in * which case cache mode doesn't matter) or used with cache=none */ - if (qemuMigrateDisk(disk, nmigrate_disks, migrate_disks) && - disk->cachemode != VIR_DOMAIN_DISK_CACHE_DISABLE) { - int rc; + if (virStorageSourceIsEmpty(disk->src) || + disk->src->readonly || + disk->src->shared || + disk->cachemode == VIR_DOMAIN_DISK_CACHE_DISABLE)
So this check is being done first to avoid the chance that a disk that was defined in the domain, but wasn't in some supplied migrate_disks doesn't erroneously cause a failure because qemuMigrateDisk would never do that last check which after patch 4 does the Empty, Read, Shared check.
Well. No. This is what this function is supposed to check first. I've extracted it from qemuMigrateDisk which would basically have the same semantics if 'migrate_disks' is NULL/empty.
It is semantically wrong to call that function at this place. The function returns whether a disk will be migrated when doing migration with non-shared storage. While the logic is the same, it is not correct to abuse it here.
OK... Right I understand this - although my wording wasn't as precise.
+ continue;
- if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_FILE) { - if ((rc = virFileIsSharedFS(src)) < 0) - return false; - else if (rc == 0) - continue; - if ((rc = virStorageFileIsClusterFS(src)) < 0) - return false; - else if (rc == 1) - continue; - } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK && - disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) { - continue; - } + /* disks which are migrated by qemu are safe too */ + if (storagemigration &&
This is the part that seems to be 'extra' and not related to the commit message. IIUC the flags in question aren't necessarily supplied - so if
No. This is exactly what the first sentence of the commit message promises to fix.
they weren't supplied the subsequent check won't be made? Is that what is desired? Perhaps I'm missing something subtle or that's a "given" with those flags.
The flags contain the two bits which are checked if the user requires storage migration.
When you say "storage migration" - I'm assuming NBD, is that assumption true? Or can the non shared, non readonly, non empty, or cache!=none disks be migrated by some other means?
In case where we migrate storage, we do not need to check that caching for the disks is disabled. This is due to the fact that the disks are migrated by qemu and thus there are no caching-coherency issues, since qemu copies all the data.
This means that disks undergoing storage migration don't need to be checked for disabled caching.
What's confusing to me about the message is that qemuMigrateDisk doesn't check caching... The way the code is changed - it doesn't matter about storage migrated since *any* disk with cache=none is deemed OK.
+ qemuMigrateDisk(disk, nmigrate_disks, migrate_disks)) + continue;
Also previously, if the qemuMigrateDisk was true (and cache != DISABLE), then the SharedFS/ClusterFS and RBD checks would be made. With this change as long as both MigrateDisk and those flags are true, the code would just go to the next disk and not check those flags. Again perhaps something subtle I'm missing.
Yes, that's exactly what I wanted to achieve. The above addition of the same logich that qemuMigrateDisk does to determine if a disk should be migrated is precisely for the fact, that using qemuMigrateDisk at that point is semantically incorrect.
So the logic is as follows:
If the disk is empty, readonly, shared, or has disabled caching, it's safe to migrate. This is also for cases where shared storage is used and thus no storage migration takes place.
If storage migration is used, then all disks which are migrated using the storage migration are safe to undergo migration, since the caching issue does not apply to them.
All other disks need to be checked
Perhaps if qemuMigrateDisk were documented it'd be easier to understand (multiple options for storage transfer - via command line that fills in migrate_disks and the nbd server setup). In any case, thanks for the extra details and this does make (more) sense now... So ACK for the patch... John

On Thu, Apr 13, 2017 at 10:00:11 -0400, John Ferlan wrote:
Perhaps if qemuMigrateDisk were documented it'd be easier to understand (multiple options for storage transfer - via command line that fills in migrate_disks and the nbd server setup).
So to enable storage migration, you need to set one of the VIR_MIGRATE_NON_SHARED_* flags. This will migrate any non shared, non readonly, and non empty disk. Since this was not optimal, a new migration parameter was added so that the list of discs which should be migrated can be explicitly set when migration is started. And qemuMigrateDisk is just a helper which tells whether a given disk is supposed to be migrated: either it is specified in the explicitly passed list of disks, or when no list is passed it uses the default rule. Jirka

Use the proper check whether a disk is empty. --- src/qemu/qemu_migration.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 5bd45137c..46f82ab33 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -415,7 +415,7 @@ qemuMigrateDisk(virDomainDiskDef const *disk, /* Default is to migrate only non-shared non-readonly disks * with source */ return !disk->src->shared && !disk->src->readonly && - virDomainDiskGetSource(disk); + !virStorageSourceIsEmpty(disk->src); } -- 2.12.2

On 04/07/2017 11:50 AM, Peter Krempa wrote:
Use the proper check whether a disk is empty. --- src/qemu/qemu_migration.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
ACK John

If you specify disks to migrate it would be possible to select an empty drive for migration. Reject such config. --- src/qemu/qemu_migration.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 46f82ab33..09adb0484 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -515,9 +515,10 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver, if (!qemuMigrateDisk(disk, nmigrate_disks, migrate_disks)) continue; - if (disk->src->readonly) { + if (disk->src->readonly || virStorageSourceIsEmpty(disk->src)) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("Cannot migrate read-only disk %s"), disk->dst); + _("Cannot migrate empty or read-only disk %s"), + disk->dst); goto cleanup; } -- 2.12.2

On 04/07/2017 11:50 AM, Peter Krempa wrote:
If you specify disks to migrate it would be possible to select an empty drive for migration. Reject such config.
because ...
--- src/qemu/qemu_migration.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 46f82ab33..09adb0484 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -515,9 +515,10 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver, if (!qemuMigrateDisk(disk, nmigrate_disks, migrate_disks)) continue;
IOW: For disks that are not in our migrate_disk list and this is only ever called when the flags VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC are set... So to a degree the checks made in patch 3 make a bit more sense once it's understood that there's this code.... Like I said - something subtle in how this all "magically" works... ACK for this though, John
- if (disk->src->readonly) { + if (disk->src->readonly || virStorageSourceIsEmpty(disk->src)) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("Cannot migrate read-only disk %s"), disk->dst); + _("Cannot migrate empty or read-only disk %s"), + disk->dst); goto cleanup; }
participants (3)
-
Jiri Denemark
-
John Ferlan
-
Peter Krempa