一文看懂ovirt中supervdsmd.service架构流程

(文章来自作者维护的社区微信公众号【虚拟化云计算】)
目前有两个微信群《kvm虚拟化》和《openstack》,扫描二维码点击“云-交流”,进群交流提问
在ovirt的节点上supervdsmd.service是有root用户权限的,可以操作系统底层的资源,其他的服务需要与之通讯来完成对资源的操作。其主要完成两个工作:动态扩展 _SuperVdsm和启动BaseManager(multiprocessing.managers)服务端,然后就是监听其他服务发送过的API请求并执行。
 
一.动态扩展 _SuperVdsm
 
supervdsm_server.py
if _glusterEnabled:
    for name, func in listPublicFunctions(GLUSTER_MGMT_ENABLED):
        setattr(_SuperVdsm, name, bind(logDecorator(func)))
把gluster目录下的模块的函数到取出来,在函数名字之前加了字符串gluster,然后赋给_SuperVdsm
 
for _, module_name, _ in pkgutil.iter_modules([supervdsm_api.
                                               __path__[0]]):
    module = importlib.import_module('%s.%s' %
                                     (supervdsm_api.__name__,
                                      module_name))
    api_funcs = [f for _, f in module.__dict__.iteritems()
                 if callable(f) and getattr(f, 'exposed_api', False)]
    for func in api_funcs:
        setattr(_SuperVdsm, func.__name__, bind(logDecorator(func)))
把supervdsm_api目录下的模块中被@expose的函数到取出来,直接赋给_SuperVdsm。这样就为给supervdsmd.service添加新的API提供了很简单的方法:只要在 supervdsm_api文件夹下新建一个pthon文件就可以自动导出新的API了。
 
setattr之前的_SuperVdsm:
初始的_SuperVdsm中函数很少,都在class _SuperVdsm中定义,例如mount、multipath_status、removeDeviceMapping等。
 
setattr之后的_SuperVdsm:
动态扩展之后的_SuperVdsm中函数包含了所有要导出的API函数,包括三部分API:
1.原来_SuperVdsm的API,例如mount、multipath_status、getdeviSCSIinfo等;
2.gluster文件夹下导出的API,例如gluster/cli.py中的snapshotInfo等;
3.supervdsm_api文件夹下导出的API,例如supervdsm_api/hwinfo.py中的getHardwareInfo等。
 
二.启动BaseManager(multiprocessing.managers)服务端
启动一个 BaseManager的serve_forever线程 程,它监听 /var/run/vdsm/svdsm.sock ,它的callable设置为 _SuperVdsm供BaseManager的客户端来调用其中的API。(供调用的API在前面已经全部赋给了_SuperVdsm
manager = _SuperVdsmManager(address=address, authkey='')
manager.register('instance', callable=_SuperVdsm)
 
server = manager.get_server()
servThread = concurrent.thread(server.serve_forever)
servThread.start()
其中_SuperVdsmManager的定义:
class _SuperVdsmManager(BaseManager):
    pass
 
到此supervdsmd.service的任务就完成了,剩下的就是等着client来调用_SuperVdsm中的API了。
 
 
三.client(例如 vdsmd.service) 如何与supervdsmd.service通信
在common/supervdsm.py中实现了BaseManager(multiprocessing.managers)的clinet: SuperVdsmProxy:
class SuperVdsmProxy(object):
    def _connect(self):
        self._manager = _SuperVdsmManager(address=ADDRESS, authkey='')
        self._manager.register('instance')
        self._manager.register('open')
        try:
            function.retry(
                self._manager.connect, Exception, timeout=60, tries=3)
 
在vdsmd.service中使用SuperVdsmProxy来调用supervdsmd.service的API的方法:
from vdsm.common import supervdsm
supervdsm.getProxy().xxxxxxAPI()
 
也可以自己写一个python文件来调用supervdsmd.service的API
例如:
from vdsm.common import supervdsm
print supervdsm.getProxy().getHardwareInfo()
 
 
BaseManager例子
我们把vdsm中关于BaseManager(multiprocessing.managers)的服务端和客户端代码单独摘出来,组成一个可运行的domo程序:
服务端:
from multiprocessing.managers import BaseManager
 
class _SuperVdsmManager(BaseManager):
    pass
 
class _SuperVdsm(object):
    def test_api(*args, **kwargs):
        return "this is server"
 
def start_server():
    manager = _SuperVdsmManager(address='/tmp/test.sock', authkey='')
    manager.register('instance', callable=_SuperVdsm)
 
    server = manager.get_server()
    server.serve_forever()
 
start_server()
 
客户端:
class ProxyCaller(object):
 
    def __init__(self, supervdsmProxy, funcName):
        self._funcName = funcName
        self._supervdsmProxy = supervdsmProxy
 
    def __call__(self, *args, **kwargs):
        callMethod = lambda: \
            getattr(self._supervdsmProxy._svdsm, self._funcName)(*args,
                                                                 **kwargs)
        return callMethod()
 
class SuperVdsmProxy(object):
    def __init__(self):
        self._manager = None
        self._svdsm = None
        self._connect()
 
    def open(self, *args, **kwargs):
        return self._manager.open(*args, **kwargs)
 
    def _connect(self):
        self._manager = _SuperVdsmManager(address='/tmp/test.sock', authkey='')
        self._manager.register('instance')
        self._manager.register('open')
        self._manager.connect()
 
        self._svdsm = self._manager.instance()
 
    def __getattr__(self, name):
        return ProxyCaller(self, name)
 
def start_client():
    instance = SuperVdsmProxy()
    print instance.test_api()
 
start_client()
 
 

附录:
setattr之前的_SuperVdsm:
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_runAs', 'fuser', 'getPathsStatus', 'getScsiSerial', 'getdeviSCSIinfo', 'hbaRescan', 'log', 'mount', 'multipath_status', 'readSessionInfo', 'removeDeviceMapping', 'resizeMap', 'umount', 'validateAccess']
setattr之后的_SuperVdsm:
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_runAs', 'add_ovs_vhostuser_port', 'add_sourceroute', 'appropriateHwrngDevice', 'appropriateIommuGroup', 'appropriateMultipathDevice', 'appropriateSCSIDevice', 'appropriateUSBDevice', 'change_numvfs', 'fuser', 'getFileName', 'getHardwareInfo', 'getPathsStatus', 'getScsiSerial', 'get_ibpb', 'get_ibrs', 'get_lldp_info', 'get_pti', 'getdeviSCSIinfo', 'glusterExecuteGsecCreate', 'glusterExecuteMountBrokerOpt', 'glusterExecuteMountBrokerUserAdd', 'glusterHostUUIDGet', 'glusterPeerDetach', 'glusterPeerProbe', 'glusterPeerStatus', 'glusterSnapshotActivate', 'glusterSnapshotConfig', 'glusterSnapshotCreate', 'glusterSnapshotDeactivate', 'glusterSnapshotDelete', 'glusterSnapshotInfo', 'glusterSnapshotRestore', 'glusterVolumeAddBrick', 'glusterVolumeCreate', 'glusterVolumeDelete', 'glusterVolumeGeoRepConfig', 'glusterVolumeGeoRepSessionCreate', 'glusterVolumeGeoRepSessionDelete', 'glusterVolumeGeoRepSessionPause', 'glusterVolumeGeoRepSessionResume', 'glusterVolumeGeoRepSessionStart', 'glusterVolumeGeoRepSessionStop', 'glusterVolumeGeoRepStatus', 'glusterVolumeHealInfo', 'glusterVolumeInfo', 'glusterVolumeProfileInfo', 'glusterVolumeProfileStart', 'glusterVolumeProfileStop', 'glusterVolumeRebalanceStart', 'glusterVolumeRebalanceStatus', 'glusterVolumeRebalanceStop', 'glusterVolumeRemoveBrickCommit', 'glusterVolumeRemoveBrickForce', 'glusterVolumeRemoveBrickStart', 'glusterVolumeRemoveBrickStatus', 'glusterVolumeRemoveBrickStop', 'glusterVolumeReplaceBrickCommitForce', 'glusterVolumeReset', 'glusterVolumeResetBrickCommitForce', 'glusterVolumeResetBrickStart', 'glusterVolumeSet', 'glusterVolumeSetHelpXml', 'glusterVolumeStart', 'glusterVolumeStatus', 'glusterVolumeStop', 'glusterVolumeTasks', 'gluster_parseVolumeRebalanceRemoveBrickStatus', 'hbaRescan', 'hugepages_alloc', 'injectFilesToFs', 'ksmTune', 'log', 'mdev_create', 'mdev_delete', 'mkFloppyFs', 'mkIsoFs', 'mount', 'multipath_status', 'network_caps', 'ovs_bridge', 'ping', 'prepareVmChannel', 'readSessionInfo', 'removeDeviceMapping', 'removeFs', 'remove_ovs_port', 'remove_sourceroute', 'resizeMap', 'restoreNetworks', 'rmAppropriateHwrngDevice', 'rmAppropriateIommuGroup', 'rmAppropriateMultipathRules', 'rmAppropriateSCSIDevice', 'rmAppropriateUSBDevice', 'setPortMirroring', 'setSafeNetworkConfig', 'set_rp_filter_loose', 'set_rp_filter_strict', 'setupNetworks', 'systemctl_stop', 'systemd_run', 'udevTriggerMultipath', 'umount', 'unsetPortMirroring', 'validateAccess']
 
============================================================
关注微信公众号【虚拟化云计算】,阅读更多虚拟化云计算知识,纯技术干货更新不停。
 
 
 
 

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值