Skip to content

Commit cc18b84

Browse files
Vineeth Pillaibryteise
authored andcommitted
ch: procfs watcher thread for updating vm's thread information
Implement a thread that parses procfs for any changes to the VM process's threads and on any change, update the thread information maintained by the monitor. Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
1 parent aa338cb commit cc18b84

2 files changed

Lines changed: 93 additions & 1 deletion

File tree

src/ch/ch_domain.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ struct _virCHDomainObjPrivate {
7171

7272
size_t tapfdSize;
7373
int *tapfd;
74+
75+
virThread vmThreadWatcher;
76+
int vmThreadWatcherStop;
7477
};
7578

7679
#define CH_DOMAIN_PRIVATE(vm) \

src/ch/ch_process.c

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,9 @@ static int virCHProcessSetupThreads(virDomainObjPtr vm)
420420
virCHDomainObjPrivatePtr priv = vm->privateData;
421421
int ret;
422422

423-
virCHMonitorRefreshThreadInfo(priv->monitor);
423+
ret = virCHMonitorRefreshThreadInfo(priv->monitor);
424+
if (ret <= 0)
425+
return ret;
424426

425427
VIR_DEBUG("Setting emulator tuning/settings");
426428
ret = virCHProcessSetupEmulatorThreads(vm);
@@ -438,6 +440,87 @@ static int virCHProcessSetupThreads(virDomainObjPtr vm)
438440
return ret;
439441
}
440442

443+
/*
444+
* Procfs Thread watcher
445+
* This thread is started when a Domain boots up and
446+
* exists as long as the domain is active. The duty
447+
* of the thread is to watch for any tid changes for
448+
* the VM and then update the cgroups accordingly.
449+
* Threads can change in the case of following events:
450+
* - VM reboot
451+
* - Device activation
452+
*
453+
* TODO: Parsing procfs frequently is ugly and not scalable
454+
* Better option would be to have cloud-hypervisor
455+
* return the thread information via API query or
456+
* probably to have a monitor interface like what
457+
* qemu has.
458+
*/
459+
460+
/*
461+
* Hard coding the polling interval for the watcher thread
462+
* to be 1 second.
463+
*/
464+
#define THREAD_WATCHER_POLL_INTERVAL G_USEC_PER_SEC
465+
466+
static void chProcessWatchThreads(void *data)
467+
{
468+
virDomainObjPtr vm = (virDomainObjPtr)data;
469+
virCHDomainObjPrivatePtr priv;
470+
471+
VIR_DEBUG("VM Thread watcher starting");
472+
473+
virObjectLock(vm);
474+
priv = vm->privateData;
475+
while (g_atomic_int_get(&priv->vmThreadWatcherStop) == 0 &&
476+
virDomainObjIsActive(vm)) {
477+
478+
if (virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) < 0) {
479+
VIR_WARN("VRP: Failed to Lock vm state");
480+
} else {
481+
virCHProcessSetupThreads(vm);
482+
virCHDomainObjEndJob(vm);
483+
}
484+
485+
virObjectUnlock(vm);
486+
g_usleep(G_USEC_PER_SEC);
487+
virObjectLock(vm);
488+
}
489+
VIR_DEBUG("VM Thread watcher exiting");
490+
491+
virDomainObjEndAPI(&vm);
492+
return;
493+
}
494+
495+
static int virCHProcessStartWatchThreads(virDomainObjPtr vm)
496+
{
497+
virCHDomainObjPrivatePtr priv = vm->privateData;
498+
g_autofree char *name = NULL;
499+
500+
name = g_strdup_printf("threadwatcher-%d", vm->pid);
501+
502+
virObjectRef(vm);
503+
if (virThreadCreateFull(&priv->vmThreadWatcher,
504+
false,
505+
chProcessWatchThreads,
506+
name,
507+
false,
508+
vm) < 0) {
509+
virObjectUnref(vm);
510+
return -1;
511+
512+
}
513+
514+
g_atomic_int_set(&priv->vmThreadWatcherStop, 0);
515+
return 0;
516+
}
517+
518+
static void virCHProcessStopWatchThreads(virDomainObjPtr vm)
519+
{
520+
virCHDomainObjPrivatePtr priv = vm->privateData;
521+
g_atomic_int_set(&priv->vmThreadWatcherStop, 1);
522+
}
523+
441524
/**
442525
* chProcessNetworkPrepareDevices
443526
*/
@@ -593,6 +676,10 @@ int virCHProcessStart(virCHDriverPtr driver,
593676
if (chSetupGlobalCpuCgroup(vm) < 0)
594677
goto cleanup;
595678

679+
VIR_DEBUG("Starting the thread watcher thread");
680+
if (virCHProcessStartWatchThreads(vm) < 0)
681+
goto cleanup;
682+
596683
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
597684

598685
return 0;
@@ -615,6 +702,8 @@ int virCHProcessStop(virCHDriverPtr driver G_GNUC_UNUSED,
615702
VIR_DEBUG("Stopping VM name=%s pid=%d reason=%d",
616703
vm->def->name, (int)vm->pid, (int)reason);
617704

705+
virCHProcessStopWatchThreads(vm);
706+
618707
if (priv->monitor) {
619708
virCHMonitorClose(priv->monitor);
620709
priv->monitor = NULL;

0 commit comments

Comments
 (0)