libvirtd总体代码架构
libvirt相关代码
LanceLiu
2019-12-03
libvirt 总体代码架构 NetServerClient 模块 refcount机制 (1) virObjectLockableNew()函数中调用virObjectNew() 为其ref赋初始值为1 (3) virNetServerAddClient()中virObjectRef(client)会使得client ref值+1 -->3 (2)virNetServerClientInit() virNetServerClientRegisterEvent() ref++ -->2 (4) virNetServerAddClient() 中virNetServerClientInitKeepAlive() ref +1 -->4 virKeepAliveNew() 为ka 注册UnRef client callback virNetServerDispatchNewClient() ref -1 --> 3 virNetServerClientDispatchRead() ref +1 --> 4 dispatch virNetServerHandleJob() ref -1 virNetServerProcessClients() ref - 1 清理ka时会unref client virEventPollCleanupTimeouts() ref -1 virEventPollCleanupHandles () :593 virNetSocketEventFree() ref -1 daemonAddClientStream() ref +1 virStreamEventAddCallback()中会注册ff callback virObjectFreeCallback virFDStreamEvent 调用 virObjectFreeCallback() ref -1 初始化 初始化log系统 log_level : debug info warning error 编程学习 isatty() 影响变量 virLogDefaultPriority 优先从环境变量中获取 进行fork,然后父进程退出 (若有-d 参数) umask() 启动server 不过此步尚未创建相关监听端口 virNetServerNew(min_workers, max_workers, prio_workers, max_clients, max_anonymous_clients, keepalive_count, mdns_name, remoteClientInitHook, NULL, remoteClientFreeFunc, NULL) why fork到grand child virClass机制 创建worker池,用于接收工作队列(min_worker个数) 创建prio worker pool mdns 何用 参数 max_clients 客户端最大数量 max_anonymous_clients 最大无需认证的客户端个数 注册事件相关callback函数 忽略SIGPIPE信号 将上一步创建的server加入 net daemon中 daemonInittialize 主要是加载network interface storage nodedev secret nwfilter qemu lxc等 为server增加remoteProgram lxcProgram qemuProgram 后续dispatchMessage时,会根据msg header的 prog和vers寻找合适的处理program 创建admin Server 添加到Net Daemon中,然后为admin Server注册处理函数数组 adminProcs 注册信号处理机制: SIGINT SIGQUIT SIGTERM SIGHUP 初始化hook机制 audit 机制 创建网络监听接口 unix_sock_dir 用于普通server libvirt-sock-ro 用于读权限service libvirt-admin-sock 用于admin service 初始化daemon Driver 状态 初始化后,enable 服务,如此后续才能处理服务请求 运行daemon 开始监听处理 动态lib库加载 dlopen dlsym libvirt signal处理机制 1. 通过pipe fd的方式,检测pipe读fd的事件信息,当收到 读事件后,统一由fd事件机制调用注册callback进行处理 2. 改变信号处理函数,当收到信号时,信号处理函数将信号写入pipe fd, 最终触发事件处理模块收到读事件 SIGINT SIGQUIT SIGTERM callback为daemonShutdownHandler() SIGHUP daemonReloadHandler() libvirt job worker机制 两组job worker thread pool 由virNetServerNew()完成创建thread pool 1. server thread pool 2.adm server thread pool 处理机制 job worker thread pool的pool->jobFunc callback为virNetServerHandleJob()。 每个pool 有mutex和cond 3. 每个server thread worker pool都分为普通的 worker thread pool和prio worker thread pool 工作线程工作函数virThreadPoolWorker()会等待条件变量cond,收到条件变量cond后, 首先freeWorkers--, 然后从job链表中取下job,调用callback即virNetServerHandleJob进 行处理 virNetServerHandleJob() --> virNetServerProcessMsg(srv, job->client, job->prog, job- >msg) -->virNetServerProgramDispatch()根据msg->type msg->header.proc 索引相应的处理函数,然后进行处理 相关问题 VIR_NET_CALL vs VIR_NET_CALL_WITH_FDS 只有remoteDomainCreateWithFiles()时才使用VIR_NET_CALL_WITH_FDS msg->fds[] 数组中fd何时被赋值? dispatch机制 virNetServerAddService()会为svc注册dispatch new client 函数callback 为virNetServerDispatchNewClient() 当新的client connetion到达后,会触发上述callback得到调用 将client->dspatchFUnc callback 赋值为virNetServerDispatchNewMessage() client端发送新的msg过来,一条msg接收完成后 会触发client->dispatchFunc() 对msg进行dispatch virNetServerDispatchNewMessage() 将msg发送到job worker pool的 任务列表中 daemonConfigLoadFile() 加载配置文件 初始化默认配置项 daemonConfigNew() libvirt 各个driver及init 机制 加载driver项 1. network 2. interface 3. storage 4. nodedev 5. secret 6. nwfilter 7. qemu 8. lxc 通过virDriverLoadModule()的方式动态加载各模块动态链接库 通过dlopen打开动态链接库 通过dlsym() 获取所需调用相应函数的地址 调用相应的register函数 对模块进行注册 qemu:// 这类connection server 是什么,如何连接,什么场景下需要连接 daemonStateInit() 调用由virDriverLoadModule()函数注册的各个driver的状态初始化函数 进行初始化回调函数(如qemuStateInitialize()) 和 stateAutoStart()回调函数