bhouse-nexthop opened a new issue, #14622:
URL: https://github.com/apache/cloudstack/issues/14622

   ### problem
   
   On KVM, resizing a volume on RBD primary storage fails in the agent if this 
host's libvirt has not yet cached the image in its view of the pool. A freshly 
deployed VM's ROOT volume is the usual case:
   
   ```
   resizeVolume id=<ROOT> size=12
     -> Failed to resize volume operation of volume UUID: [<uuid>] due to -
        org.libvirt.LibvirtException: Storage volume not found: no storage vol 
with matching path '<ceph pool>/<uuid>'
   ```
   
   `resizeVolume` with a size or a disk offering, `changeOfferingForVolume` and 
`scaleVirtualMachine` all fail the same way, since they all end in the same 
`ResizeVolumeCommand`. A size-only grow of a ROOT volume fails too. The resize 
works again once something else on that host has made libvirt refresh the pool 
(or after a `virsh pool-refresh` by hand).
   
   ### Cause
   
   `LibvirtResizeVolumeCommandWrapper` gets the disk with 
`pool.getPhysicalDisk()` and then looks the volume up through libvirt with 
`conn.storageVolLookupByPath(path)` to call `StorageVol.resize()`.
   
   - Before #14188, `getPhysicalDisk()` went through 
`LibvirtStorageAdaptor.getVolume()`, which refreshes the libvirt pool on a 
miss. So by the time the wrapper called `storageVolLookupByPath()`, the volume 
was in libvirt's cache.
   - #14188 made `getPhysicalDisk()` stat RBD images through librbd, on 
purpose, so that a miss no longer refreshes the whole pool. The wrapper's 
`storageVolLookupByPath()` now runs against libvirt's cache cold.
   - CloudStack creates RBD volumes through librbd (the clone from the 
template), not through libvirt, so a new volume is not in libvirt's cache on 
any host until something refreshes the pool there.
   
   The other libvirt volume lookups in the KVM plugin don't depend on 
`getPhysicalDisk()`: `deletePhysicalDisk()` uses `getVolume()`, which still 
refreshes on a miss, and `LibvirtMigrateCommandWrapper.deleteLocalVolume()` 
only handles local files.
   
   The unit tests mock `Connect.storageVolLookupByPath`, so they did not see 
this.
   
   ### versions
   
   The 4.22 branch since #14188, and main. Released versions without #14188 are 
not affected. Found while testing #14602 in a lab: KVM, Ceph RBD primary 
storage, a running Ubuntu VM with its ROOT on RBD.
   
   ### The steps to reproduce the bug
   
   1. Deploy a VM on KVM with its ROOT volume on RBD primary storage.
   2. Before anything refreshes the libvirt pool on its host (no `virsh 
pool-refresh`, no storage stats poll yet), resize its ROOT volume, for example 
`resizeVolume id=<ROOT> size=<larger>`.
   3. The agent fails with "Storage volume not found: no storage vol with 
matching path ...".
   
   ### What to do about it?
   
   In the resize wrapper, when the lookup by path fails with "not found" 
(VIR_ERR_NO_STORAGE_VOL) on an RBD pool, refresh that pool and look the volume 
up once more. That is what `getVolume()` did for this path before #14188, and 
it only costs a refresh when the volume is not cached. Other pool types are 
unchanged.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

  • [I] KVM: resizing an RBD volu... bhouse-nexthop (via GitHub) via commits

Reply via email to