pythonstoragelibvirt

How to get actual disk size from libvirt-python (3 questions!)


I've been working with virt-manager and am now moving into some custom code using python and libvirt.

I have noticed that some of my VMs show "unknown" in regard to the disk "Storage size".

Using virsh gives me what roughly appear to be correct results:

virsh # domblkinfo 10 vda
Capacity:       32212254720
Allocation:     31936634880
Physical:       31935758336

... "Capacity" I assume is the maximum of the defined drive. However in this case, the actual defined size, (using qemu-img) the guest OS sees as 25GB (total) - which is what was requested.

virsh domblkinfo shows 30G (if those numbers are bytes)

The host OS says the current qcow2 file size is 17GB. (which makes sense as it is a COW disk).

However...

Thanks in advance!


Solution

  • in short, you should first extract info about disks path from domain XML, and the pass it to blockInfo() method, so the full script will look like the following:

    import libvirt
    from xml.dom import minidom
    
    conn = libvirt.open('qemu:///system')
    domainIDs = conn.listAllDomains(0)
    
    print("\tNAME\tSTATE\tCPUs\tMEM\tDISK\tUSED")
    for domain in domainIDs:
            raw_xml = domain.XMLDesc(0)
            state, maxmem, mem2, cpus, cput = domain.info()
            name = domain.name()
            mem   = domain.maxMemory()/1024**2
            xml = minidom.parseString(raw_xml)
            diskTypes = xml.getElementsByTagName('disk')
            for diskType in diskTypes:
                    if diskType.getAttribute('device') == 'disk':
                            diskNodes = diskType.childNodes
                            for diskNode in diskNodes:
                                    if diskNode.nodeName == 'source':
                                            for attr in diskNode.attributes.keys():
                                                    if diskNode.attributes[attr].name == 'file':
                                                            blkinf = domain.blockInfo(diskNode.attributes[attr].value)
                    if   state == 1: vmstate = "running"
                    elif state == 5: vmstate = "stopped"
                    disksize = round(blkinf[0]/1024**3)
                    diskused = round(blkinf[1]/1024**3)
            print(name+"\t"+vmstate+"\t"+str(cpus)+"\t"+str(mem)+"G"+"\t"+str(disksize)+"G\t"+str(diskused)+"G")
    
    conn.close()
    

    the result should be like following:

            NAME    STATE   CPUs    MEM     DISK    USED
    cos6-copy       stopped 2       1.0G    64G     2G
    centos6.i386    running 2       1.0G    64G     2G