libvirtd启动之后,会创建一系列线程,本文就是针对libvirtd进程创建的线程进行分析:
libvirtd:是libvirt的daemon进程
rpc-worker:是libvirtd接收客户端发送的命令处理的线程
pri-rpc-worker
qemu-event:
udev-event:
vm-instance-000:线程,这个线程比较奇怪,每启动一个虚拟机,就会多出一个这样的线程,看名字明显是和VM的名字相关,原因是线程设定的名字只能是15个字符,所以会出现名字相同的情况。但是这个线程的作用是什么呢?
qemuDomainObjStartWorker
|
|--threadName = vm-instace-000{因为限定15个字符,后面的名字就看不到了}
|
|--priv->eventThread = virEventThreadNew(threadName)
|
|--evt = VIR_EVENT_THREAD(g_object_new(VIR_TYPE_EVENT_THREAD, NULL)
|
|--virEventThreadStart
|
|--evt->thread = g_thread_try_new(thname, virEventThreadWorker)
| |
| |--virEventThreadWorker{这个是新的线程,运行glib事件循环}
| |
| |--running = g_idle_source_new(){创建空闲的事件}
| |
| |--g_source_set_callback(running, virEventThreadNotify, data, NULL)
| | |
| | |--virEventThreadNotify
| | |
| | |--data->running = TRUE
| | |
| | |--g_cond_signal(&data->cond){这里让主线程继续向下运行}
| |
| |--g_source_attach(running, data->context)
| |
| |--g_main_loop_run(data->loop){循环阻塞}
| |
| |--virEventThreadDataFree(data){释放资源}
|
|--while (!data->running)->g_cond_wait(&data->cond, &data->lock){这里会阻塞等待glib事件线程创建成功}
走到这里就创建一个GMainLoop循环的线程,里面有一个idle事件,会将这个idle事件添加到context中
上面创建的source没有关联任何fd,只是创建一个线程来运行事件循环机制;后面的其他source可以关联到这个context上,运行相应的事件响应回调函数。
qemuMonitor监控:
qemuConnectMonitor
|
|--qemuMonitorOpen(vm, priv->monConfig, retry, timeout, virEventThreadGetContext(priv->eventThread), &monitorCallbacks, driver)
|
|--fd = qemuMonitorOpenUnix(config->data.nix.path, vm->pid, retry, timeout){监听的fd}
|
|--qemuMonitorOpenInternal(vm, fd, context, cb, opaque)
|
|--mon->fd = fd
|--mon->context = g_main_context_ref(context)
|--mon->cb = cb{设置的回调函数}
|--mon->callbackOpaque = opaque{回调函数的参数}
|--mon->socket = g_socket_new_from_fd(fd, &gerr){得到监听的socket}
|--qemuMonitorRegister(mon)
|
|--g_socket_create_source(mon->socket, cond, NULL){创建监控的事件,cond=G_IO_IN | G_IO_OUT}
|
|--g_source_set_callback(mon->watch,(GSourceFunc)qemuMonitorIO,mon)
|
|--g_source_attach(mon->watch, mon->context)
QMP Monitor:
qemuProcessQMPConnectMonitor
|
|--qemuMonitorOpen{流程同上}
|