Repository navigation
Fix in the calculation of a volume's physical size #13286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 4.22
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ | |
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
| import java.util.HashSet; | ||
| import java.util.UUID; | ||
| import java.util.concurrent.ConcurrentHashMap; | ||
| import java.util.stream.Collectors; | ||
|
|
@@ -505,6 +506,12 @@ public LibvirtStoragePoolDef getStoragePoolDef(Connect conn, StoragePool pool) t | |
| return parser.parseStoragePoolXML(poolDefXML); | ||
| } | ||
|
|
||
| private String getBackingFileOfVolumeIfExists(StorageVol vol) throws LibvirtException { | ||
| String volDefXML = vol.getXMLDesc(0); | ||
| LibvirtStorageVolumeXMLParser parser = new LibvirtStorageVolumeXMLParser(); | ||
| return parser.getBackingFileNameIfExists(volDefXML); | ||
| } | ||
|
|
||
| public LibvirtStorageVolumeDef getStorageVolumeDef(Connect conn, StorageVol vol) throws LibvirtException { | ||
| String volDefXML = vol.getXMLDesc(0); | ||
| LibvirtStorageVolumeXMLParser parser = new LibvirtStorageVolumeXMLParser(); | ||
|
|
@@ -655,6 +662,28 @@ public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo) { | |
| } | ||
| } | ||
|
|
||
| private Long getBackingFileSizes(StoragePool pool, StorageVol vol) throws LibvirtException { | ||
| long total = 0L; | ||
| Set<String> visited = new HashSet<>(); | ||
| StorageVol current = vol; | ||
|
|
||
| while (current != null) { | ||
| total += current.getInfo().allocation; | ||
| String backingName = getBackingFileOfVolumeIfExists(current); | ||
| if (StringUtils.isBlank(backingName) || !visited.add(backingName)) { | ||
| break; | ||
| } | ||
| try { | ||
| current = getVolume(pool, backingName); | ||
| } catch (CloudRuntimeException e) { | ||
| logger.error("Unable to resolve backing volume {} in pool {}: {}", backingName, pool.getName(), e.getMessage()); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return total; | ||
| } | ||
|
|
||
| @Override | ||
| public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool) { | ||
| LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool; | ||
|
|
@@ -663,8 +692,9 @@ public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool) { | |
| StorageVol vol = getVolume(libvirtPool.getPool(), volumeUuid); | ||
| KVMPhysicalDisk disk; | ||
| LibvirtStorageVolumeDef voldef = getStorageVolumeDef(libvirtPool.getPool().getConnect(), vol); | ||
| Long allSizes = getBackingFileSizes(libvirtPool.getPool(), vol); | ||
| disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool); | ||
| disk.setSize(vol.getInfo().allocation); | ||
| disk.setSize(allSizes); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wont every volume made from the same template now count the whole template too? adding up the volumes on a pool would count it many times
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understood your question. But yes, volumes with linked clone templates will also account for the template size in the volume size. Which is congruent with what would be seen from inside the VM.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. makes sense if its meant to match what the vm sees. that covers it |
||
| disk.setVirtualSize(vol.getInfo().capacity); | ||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens when the backing file isnt found in this pool? looks like each miss refreshes the whole pool, and this runs for every volume on each stats pass
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the backing file is not on the pool. Then the VM is inconsistent and likely corrupt. This should never happen currently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, so the refresh only runs on a broken volume. that covers it