博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
oVirt (Open Virtual) 之 VDSM 学习笔记 vdsm/vdsm (一)
阅读量:6358 次
发布时间:2019-06-23

本文共 7795 字,大约阅读时间需要 25 分钟。

简介:

VDSM 是 oVirt 项目中的一个重要部分,oVirt 可以参见 oVirt 官网:http://www.ovirt.org/。

VDSM 可以通过 oVirt 官网找到,也可通过 GIT 仓库下载:git clone http://gerrit.ovirt.org/p/vdsm.git。

VDSM 模块开始运行的文件是: vdsm/vdsm。是 Python 语言编写的。

 

Let's go!

1 loggerConfFile = constants.P_VDSM_CONF + 'logger.conf' 2  3 if config.getboolean('devel', 'python_warnings_enable'): 4     warnings.simplefilter("always") 5     if hasattr(logging, 'captureWarnings'): 6         # Python 2.6 does not have captureWarnings 7         logging.captureWarnings(True) 8  9 10 if __name__ == '__main__':11     try:12         main()13     except FatalError as e:14         syslog.syslog("VDSM failed to start: %s" % e)15         # Make it easy to debug via the shell16         raise

 

这是一个通用的写法, 如果某个模块是被通过关键字 import 导入的,那么其 __name__ 属性将是模块名。

如果是以通过 Python 解释器直接执行,那么 __name__ 属性将为:'__main__'。对于此种写法,代码:

if __name__ == '__main__':

部分的代码一般用作测试此模块代码。“ vdsm/vdsm ” 将被 Python 直接解释执行,所以将执行下面的代码。

调用 main() 方法,main() 方法将是我们关注的对象。而 syslog.syslog 是调用了 syslog 模块的 syslog()

方法,记录日志。

小技巧:

查看 Python 代码时,对于这种导入库的使用,可以采用启动 Python 解释器后,通过 “ import <模块名> ”,

再使用“ help(<模块名>) ”的方式查看其帮助手册。

出现异常的时候,使用 raise 来讲程序挂起,便于调试(O__O 哥,从代码注释都能看出来的呢)。

 

Main 开始:

3个断言( assert )语句,用于保证程序运行的基本条件;

根据配置 [vars] 里的 'core_dump_enable' 值来设置程序跑飞(DUMP/CORE)时的事件记录资源设置;

设置组ID,保证运行,然后..., 跑。

1 def main(): 2     __assertVdsmUser() 3     __assertLogPermission() 4     __assertSudoerPermissions() 5  6     if not config.getboolean('vars', 'core_dump_enable'): 7         resource.setrlimit(resource.RLIMIT_CORE, (0, 0)) 8  9     if os.getsid(0) != os.getpid():10         # Modern init systems such as systemd can provide us a clean daemon11         # environment. So we setpgrp only when run by traditional init system12         # that does not prepare the environment.13         os.setpgrp()14     run()

 

断言:

__assertVdsmUser(): 用于保证程序运行的用户和用户组为:vdsm/kvm。

1 def __assertVdsmUser():2     username = getpass.getuser()3     if username != constants.VDSM_USER:4         raise FatalError("Not running as %r, trying to run as %r"5                          % (constants.VDSM_USER, username))6     group = grp.getgrnam(constants.VDSM_GROUP)7     if (constants.VDSM_USER not in group.gr_mem) and \8        (pwd.getpwnam(constants.VDSM_USER).pw_gid != group.gr_gid):9         raise FatalError("Vdsm user is not in KVM group")

 

__assertLogPermission(): 用于保证程序具有对日志文件的写的权限。

1 def __assertLogPermission(): 2     if not os.access(constants.P_VDSM_LOG, os.W_OK): 3         raise FatalError("Cannot access vdsm log dirctory") 4  5     logfile = constants.P_VDSM_LOG + "/vdsm.log" 6     if not os.path.exists(logfile): 7         # if file not exist, and vdsm has an access to log directory- continue 8         return 9 10     if not os.access(logfile, os.W_OK):11         raise FatalError("Cannot access vdsm log file")

 

__assertSudoerPermissions(): 用于保证程序具有调用某些特权命令(如:/sbin/multipath)的权限。

1 def __assertSudoerPermissions(): 2     rc = 1 3     with tempfile.NamedTemporaryFile() as dst: 4         # This cmd choice is arbitrary to validate that sudoes.d/50_vdsm file 5         # is read properly 6         cmd = [constants.EXT_CHOWN, "%s:%s" % 7                (constants.VDSM_USER, constants.QEMU_PROCESS_GROUP), dst.name] 8         rc, _, stderr = utils.execCmd(cmd, sudo=True) 9 10     if rc != 0:11         raise FatalError("Vdsm user could not manage to run sudo operation: "12                          "(stderr: %s). Verify sudoer rules configuration" %13                          (stderr))

从注释中可以注意到到 sudoes.d/50_vdsm 就是其特权命令的规则描述。

红帽( RedHat )系列Linux 为 /etc/sudoes.d/50_vdsm。

 

基本配置:

config.getboolean('type', 'des'): 将读取如下格式的配置文件,并返回“ = ”后面的值。

main() 函数里是设置程序DUMP(如 C 语言工程师讨厌的:段错误)的时候,内核将对其问题

追踪产生一些资源(文件),对程序的资源进行限制。

# 模板 # [type] # des=xxx [vars]core_dump_enable=True # Comments[string]name=YBHelloaddr=ChengDu

  

跑:

检查会话( Session ) ID 是否和进程 ID 相等:

如果相等,等价于此程序是一后台程序运行,使用 init 机制可以保证(注释里都这样说的);

如果不等,将进程自己的 ID ( PID )设置为组 ID。

【使用旧版本的 service vdsmd restart 的方式重启,程序部分日志将写到终端】

因为 VDSM 的需要这样的设置来保证环境(注释翻译)。

1     if os.getsid(0) != os.getpid():2         # Modern init systems such as systemd can provide us a clean daemon3         # environment. So we setpgrp only when run by traditional init system4         # that does not prepare the environment.5         os.setpgrp()6     run()

 

run() 起来:

输入:pidfile 将被写入 vdsm 程序的 PID 的值。

日志配置文件的处理(日志配置文件为: etc/vdsm/logger.conf)

添加一个 TRACE 日志级别(作者说:这很粗鲁但很有用 O__O "…)

导入 VDSM 调试插件

导入 覆盖率测试 模块(参见代码覆盖率测试)

将进程的 PID 写入 pidfile 中(pidfile 作为 run() 函数的参数传入),并记录日志

调用  serve_clients(log) ,正常运行下,serve_clients 不会退出(将继续追踪下去)

如果 serve_clients(log) 返回了,将所有的线程关闭

1 def run(): 2     try: 3         lconfig.fileConfig(loggerConfFile, disable_existing_loggers=False) 4     except RuntimeError as e: 5         raise FatalError("Cannot configure logging: %s" % e) 6  7     logging.addLevelName(5, 'TRACE') 8     logging.TRACE = 5  # impolite but helpful 9 10     # Used to enable code coverage. On production machines11     # "coverage" should not exists and COVERAGE_PROCESS_START should not be12     # set.13     try:14         import coverage15         coverage.process_startup()16     except ImportError:17         pass18 19     log = logging.getLogger('vds')20     try:21         logging.root.handlers.append(logging.StreamHandler())22         log.handlers.append(logging.StreamHandler())23 24         sysname, nodename, release, version, machine = os.uname()25         log.info('(PID: %s) I am the actual vdsm %s %s (%s)',26                  os.getpid(), dsaversion.raw_version_revision, nodename,27                  release)28 29         __set_cpu_affinity()30 31         serve_clients(log)32     except:33         log.error("Exception raised", exc_info=True)34 35     log.info("VDSM main thread ended. Waiting for %d other threads..." %36              (threading.activeCount() - 1))37     for t in threading.enumerate():38         if hasattr(t, 'stop'):39             t.stop()40         log.info(str(t))

 

serve_clients():

添加 SIGTERM、SIGUSR1 的信号处理函数

概要信息统计线程开始运行(包括:CPU 和内存两部分)

开启与 libvirt 的事件循环处理(线程)

根据配置文件的 [irs] 的 irs_enable 的值设置环境

scheduler(调度)实例线程

cif(Client InterFace )实例线程

开启周期执行线程

等待信号到来,如果信号到来,停止各个线程,函数放回,程序将结束

1 def serve_clients(log): 2     cif = None 3     irs = None 4     scheduler = None 5     running = [True] 6  7     def sigtermHandler(signum, frame): 8         log.debug("Received signal %s" % signum) 9         running[0] = False10 11     def sigusr1Handler(signum, frame):12         if irs:13             log.debug("Received signal %s" % signum)14             irs.spmStop(15                 irs.getConnectedStoragePoolsList()['poollist'][0])16 17     sigutils.register()18     signal.signal(signal.SIGTERM, sigtermHandler)19     signal.signal(signal.SIGUSR1, sigusr1Handler)20     zombiereaper.registerSignalHandler()21 22     profile.start()23 24     libvirtconnection.start_event_loop()25 26     try:27         if config.getboolean('irs', 'irs_enable'):28             try:29                 irs = Dispatcher(HSM())30             except:31                 utils.panic("Error initializing IRS")32 33         from clientIF import clientIF  # must import after config is read34         cif = clientIF.getInstance(irs, log)35 36         install_manhole({
'irs': irs, 'cif': cif})37 38 scheduler = schedule.Scheduler(name="vdsm.Scheduler",39 clock=utils.monotonic_time)40 scheduler.start()41 cif.start()42 periodic.start(cif, scheduler)43 try:44 while running[0]:45 sigutils.wait_for_signal()46 47 profile.stop()48 finally:49 periodic.stop()50 cif.prepareForShutdown()51 scheduler.stop()52 finally:53 libvirtconnection.stop_event_loop(wait=False)

 

 

 

  

 

转载于:https://www.cnblogs.com/YBhello/p/4834024.html

你可能感兴趣的文章
用户体验升级后 “谁行谁上”让百度Q4财报更有底气
查看>>
直播相关学习链接
查看>>
使用RPM包工具和源码包编译安装Linux应用程序
查看>>
VoIP——开启免费通话新时代的先锋
查看>>
Linux下rsync的用法
查看>>
apache虚拟主机、日志轮询、日志统计、去版本优化
查看>>
java代码实现开启openoffice服务和关闭sffice.exe进程
查看>>
docker镜像的使用方法
查看>>
提升HTTPS安全评级
查看>>
iOS开发过程中的心得
查看>>
QOS配置命令
查看>>
使用 MPI for Python 并行化遗传算法
查看>>
widget
查看>>
paramiko安装及使用
查看>>
Java私塾:研磨设计模式 之 访问者模式(Visitor)
查看>>
我的友情链接
查看>>
《Python网络数据采集》读书笔记(六)
查看>>
Linux必学的60个命令
查看>>
iptables 学习笔记 (上)
查看>>
Windows Server 2012 R2 Active Directory(活动目录)实验一
查看>>