关于libvirt的API编程介绍

本文先简要介绍了libvirt以及其API编程要点,然后具体介绍了如何通过调用libvirt的Python API,来实现memory balloon(即virtio balloon)的功能。

关于libvirt,可以将它看成由四个部分组成:
1. libvirtd,它是一个系统服务,运行 man libvirtd 可以看到更多关于libvirtd的介绍。 它主要是作为libvirt虚拟化管理系统的服务端守护进程。它的任务主要包括启动、停止虚机,在主机间迁移虚机,配置和操作网络,为虚机的使用而管理存储等。重启libvirtd不会影响正在运行的虚机。
2. libvirt虚拟化所依赖的动态链接库
   对于CentOS来说,位于 /usr/lib64/libvirt 
3. virsh,一个用户态程序,用于管理虚机。用“man virsh”可以看到非常详尽的信息。
4. libvirt API,有各种语言的实现,但最基本最主要的是C语言的实现。
   通过使用这些API,可以实现virsh的功能。
   关于libvirt API的列表,可以参见: http://libvirt.org/html/index.html

一个坑:
关于libvirt API的各语言实现与C语言的对应关系,是一个比较坑的事情。libvirt官方网站给出了一个简单的例子来说明C语言API和Python版本的API的对应关系,参见这里: http://libvirt.org/python.html 

说它坑,是因为:一、即使进入Python运行环境,import之后,运行help()来查看,看到的也仍是C API的描述;二、官方网站上只有C版本API的文档;三、上述的那个对应关系文章并不很详尽,很多由C到Python的对应规则还需自行领悟。这三点会对初学者使用非C版本的libvirt API造成一定的障碍。

笔者大致总结了一下从C到Python的API的对应规则,可能并不全面,但应该会有一点帮助:

1. C语言API里的一些全局函数,对应于Python版本里的特定类的成员函数,比如:
int virDomainSetMemory(virDomainPtr domain, unsigned long memory);
这是一个C语言的全局函数,它对应于Python中的类virDomain的成员函数setMemory()
2. C语言里面的一些宏,比如 XXX,到了Python中体现为 libvirt.XXX. 
3. C语言里面一些指向结构体的指针,尤其是该指针被用作函数的入参同时也是出参的时候,到了Python中就体现为该函数的返回值是一个dict. 比如,int virDomainMemoryStats(virDomainPtr dom, virDomainMemoryStatPtr stats,  unsigned int nr_stats, unsigned int flags) 这个函数,到了Python中就体现为 virDomain::memoryStats(),该函数没有入参,返回值是一个dict,包含了'actual', 'available'等keys,分别表示实际总内存量、可得内存量等等。

最后回归实践,让我们来写一段代码,用于设置和获取某个指定虚机的‘total memory’,即实现内存气球技术(关于内存气球的细节,请参见 http://blog.csdn.net/nirendao/article/details/54919471)

#!/usr/bin/python

import libvirt
import sys
from pprint import pprint
   

def set_memory(instance_id, size_in_kb):
    conn = libvirt.open(None)
    if conn == None:
        print 'Failed to open connection to the hypervisor'
        sys.exit(1)
    else:
        print 'Get the connection'

    try:
        # dom = conn.lookupByUUIDString('790208f9-6379-4172-bc8e-d2b325496a14')
        dom = conn.lookupByID(instance_id)
        result = dom.setMemory(1024*size_in_kb)        
        if result == 0:
            print 'Succeeded to set Memory!'
        else:
            print 'Failed to set Memory!'
    except Exception as ex:
        print 'Failed to execution: %s' % ex
        sys.exit(1)
        
def get_memory(instance_id):
    conn = libvirt.open(None)
    if conn == None:
        print 'Failed to open connection to the hypervisor'
        sys.exit(1)
    else:
        print 'Get the connection'

    try:
        # dom = conn.lookupByUUIDString('790208f9-6379-4172-bc8e-d2b325496a14')
        dom = conn.lookupByID(instance_id)
        result = dom.memoryStats()
        pprint(result)
    except Exception as ex:
        print 'Failed to execution: %s' % ex
        sys.exit(1)

    
def main():
    set(5, 1200)
    get(5)
    
if __name__ == "__main__":
    main()
    

以上这个程序中,set_memory(instance_id, size_in_kb)函数就是用来设定指定虚机(dom)的实际最大内存,而get_memory(instance_id)函数,就是用来获取指定虚机的实际最大内存。

(完)

你可能感兴趣的:(OpenStack,云计算,云计算与虚拟化)