Skip to content

Commit 9ed9ab8

Browse files
Vineeth Pillaibryteise
authored andcommitted
ch_monitor: Move the thread tracking to monitor object.
Now that we have a monitor notification from cloud-hypervisor, it makes sense to move the thread tracking to monitor. Later patches will add support for using the monitor framework from cloud-hypervisor. Signed-off-by: Vineeth Pillai <[email protected]>
1 parent e032f44 commit 9ed9ab8

File tree

4 files changed

+72
-89
lines changed

4 files changed

+72
-89
lines changed

src/ch/ch_monitor.c

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "ch_conf.h"
2929
#include "ch_domain.h"
3030
#include "ch_monitor.h"
31+
#include "ch_process.h"
3132
#include "viralloc.h"
3233
#include "vircommand.h"
3334
#include "virerror.h"
@@ -562,6 +563,61 @@ chMonitorBuildSocketCmd(virDomainObjPtr vm, const char *socket_path)
562563
return cmd;
563564
}
564565

566+
static void virCHMonitorEventLoop(void *data)
567+
{
568+
virCHMonitorPtr mon = (virCHMonitorPtr)data;
569+
virDomainObjPtr vm = mon->vm;
570+
571+
VIR_DEBUG("Monitor event loop thread starting");
572+
573+
virObjectRef(vm);
574+
while (g_atomic_int_get(&mon->event_loop_stop) == 0) {
575+
576+
g_usleep(G_USEC_PER_SEC);
577+
578+
virObjectLock(vm);
579+
if (virDomainObjIsActive(vm) &&
580+
virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) == 0) {
581+
virCHProcessSetupThreads(vm);
582+
virCHDomainObjEndJob(vm);
583+
}
584+
virObjectUnlock(vm);
585+
}
586+
virObjectUnref(vm);
587+
588+
VIR_DEBUG("Monitor event loop thread exiting");
589+
590+
virObjectUnref(mon);
591+
return;
592+
}
593+
594+
static int virCHMonitorStartEventLoop(virCHMonitorPtr mon)
595+
{
596+
g_autofree char *name = NULL;
597+
598+
name = g_strdup_printf("mon-events-%d", mon->pid);
599+
600+
virObjectRef(mon);
601+
if (virThreadCreateFull(&mon->event_loop_thread,
602+
false,
603+
virCHMonitorEventLoop,
604+
name,
605+
false,
606+
mon) < 0) {
607+
virObjectUnref(mon);
608+
return -1;
609+
610+
}
611+
612+
g_atomic_int_set(&mon->event_loop_stop, 0);
613+
return 0;
614+
}
615+
616+
static void virCHMonitorStopEventLoop(virCHMonitorPtr mon)
617+
{
618+
g_atomic_int_set(&mon->event_loop_stop, 1);
619+
}
620+
565621
virCHMonitorPtr
566622
virCHMonitorOpen(virDomainObjPtr vm, virCHDriverPtr driver)
567623
{
@@ -698,6 +754,10 @@ virCHMonitorNew(virDomainObjPtr vm, virCHDriverPtr driver)
698754
if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0)
699755
goto cleanup;
700756

757+
if (virCHMonitorStartEventLoop(mon) < 0) {
758+
goto cleanup;
759+
}
760+
701761
/* now has its own reference */
702762
virObjectRef(mon);
703763
mon->vm = virObjectRef(vm);
@@ -744,6 +804,8 @@ void virCHMonitorClose(virCHMonitorPtr mon)
744804
close(mon->monitor_fd);
745805
}
746806

807+
virCHMonitorStopEventLoop(mon);
808+
747809
virObjectUnref(mon);
748810
if (mon->vm)
749811
virObjectUnref(mon->vm);
@@ -1109,10 +1171,14 @@ virCHMonitorRefreshThreadInfo(virCHMonitorPtr mon)
11091171
{
11101172
virCHMonitorThreadInfoPtr info = NULL;
11111173
g_autofree pid_t *tids = NULL;
1112-
virDomainObjPtr vm = mon->vm;
1174+
virDomainObjPtr vm;
11131175
size_t ntids = 0;
11141176
size_t i;
11151177

1178+
if (!mon)
1179+
return -1;
1180+
1181+
vm = mon->vm;
11161182
if (virProcessGetPids(vm->pid, &ntids, &tids) < 0) {
11171183
virCHMonitorThreadInfoFree(mon);
11181184
return -1;

src/ch/ch_monitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ struct _virCHMonitor {
9696
char *socketpath;
9797

9898
int monitor_fd;
99+
virThread event_loop_thread;
100+
int event_loop_stop;
99101

100102
pid_t pid;
101103

src/ch/ch_process.c

Lines changed: 1 addition & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ virCHProcessSetupVcpus(virDomainObjPtr vm)
508508
return 0;
509509
}
510510

511-
static int virCHProcessSetupThreads(virDomainObjPtr vm)
511+
int virCHProcessSetupThreads(virDomainObjPtr vm)
512512
{
513513
virCHDomainObjPrivatePtr priv = vm->privateData;
514514
int ret;
@@ -533,87 +533,6 @@ static int virCHProcessSetupThreads(virDomainObjPtr vm)
533533
return ret;
534534
}
535535

536-
/*
537-
* Procfs Thread watcher
538-
* This thread is started when a Domain boots up and
539-
* exists as long as the domain is active. The duty
540-
* of the thread is to watch for any tid changes for
541-
* the VM and then update the cgroups accordingly.
542-
* Threads can change in the case of following events:
543-
* - VM reboot
544-
* - Device activation
545-
*
546-
* TODO: Parsing procfs frequently is ugly and not scalable
547-
* Better option would be to have cloud-hypervisor
548-
* return the thread information via API query or
549-
* probably to have a monitor interface like what
550-
* qemu has.
551-
*/
552-
553-
/*
554-
* Hard coding the polling interval for the watcher thread
555-
* to be 1 second.
556-
*/
557-
#define THREAD_WATCHER_POLL_INTERVAL G_USEC_PER_SEC
558-
559-
static void chProcessWatchThreads(void *data)
560-
{
561-
virDomainObjPtr vm = (virDomainObjPtr)data;
562-
virCHDomainObjPrivatePtr priv;
563-
564-
VIR_DEBUG("VM Thread watcher starting");
565-
566-
virObjectLock(vm);
567-
priv = vm->privateData;
568-
while (g_atomic_int_get(&priv->vmThreadWatcherStop) == 0 &&
569-
virDomainObjIsActive(vm)) {
570-
571-
if (virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) < 0) {
572-
VIR_WARN("VRP: Failed to Lock vm state");
573-
} else {
574-
virCHProcessSetupThreads(vm);
575-
virCHDomainObjEndJob(vm);
576-
}
577-
578-
virObjectUnlock(vm);
579-
g_usleep(G_USEC_PER_SEC);
580-
virObjectLock(vm);
581-
}
582-
VIR_DEBUG("VM Thread watcher exiting");
583-
584-
virDomainObjEndAPI(&vm);
585-
return;
586-
}
587-
588-
static int virCHProcessStartWatchThreads(virDomainObjPtr vm)
589-
{
590-
virCHDomainObjPrivatePtr priv = vm->privateData;
591-
g_autofree char *name = NULL;
592-
593-
name = g_strdup_printf("threadwatcher-%d", vm->pid);
594-
595-
virObjectRef(vm);
596-
if (virThreadCreateFull(&priv->vmThreadWatcher,
597-
false,
598-
chProcessWatchThreads,
599-
name,
600-
false,
601-
vm) < 0) {
602-
virObjectUnref(vm);
603-
return -1;
604-
605-
}
606-
607-
g_atomic_int_set(&priv->vmThreadWatcherStop, 0);
608-
return 0;
609-
}
610-
611-
static void virCHProcessStopWatchThreads(virDomainObjPtr vm)
612-
{
613-
virCHDomainObjPrivatePtr priv = vm->privateData;
614-
g_atomic_int_set(&priv->vmThreadWatcherStop, 1);
615-
}
616-
617536
/**
618537
* chProcessNetworkPrepareDevices
619538
*/
@@ -776,10 +695,6 @@ int virCHProcessStart(virCHDriverPtr driver,
776695
if (chSetupGlobalCpuCgroup(vm) < 0)
777696
goto cleanup;
778697

779-
VIR_DEBUG("Starting the thread watcher thread");
780-
if (virCHProcessStartWatchThreads(vm) < 0)
781-
goto cleanup;
782-
783698
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
784699

785700
if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0)
@@ -1036,8 +951,6 @@ int virCHProcessStop(virCHDriverPtr driver,
1036951
VIR_DEBUG("Stopping VM name=%s pid=%d reason=%d",
1037952
vm->def->name, (int)vm->pid, (int)reason);
1038953

1039-
virCHProcessStopWatchThreads(vm);
1040-
1041954
if (priv->monitor) {
1042955
virCHMonitorClose(priv->monitor);
1043956
priv->monitor = NULL;

src/ch/ch_process.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ int virCHProcessStop(virCHDriverPtr driver,
2929
virDomainObjPtr vm,
3030
virDomainShutoffReason reason);
3131

32+
int virCHProcessSetupThreads(virDomainObjPtr vm);
33+
3234
int virCHProcessSetupVcpu(virDomainObjPtr vm,
3335
unsigned int vcpuid);
3436

0 commit comments

Comments
 (0)