Skip to content

Commit 4996626

Browse files
committed
ch: Add detection for vm crash
When cloud-hypervisor crashes or is killed without being able to notify it is being shutdown, previously libvirt wouldn't be able to detect this condition. To avoid this, add a check in the event monitor read loop on EINTR to test if the VM pid is still active.
1 parent afb1f90 commit 4996626

File tree

2 files changed

+19
-14
lines changed

2 files changed

+19
-14
lines changed

src/ch/ch_domain.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ struct _virCHDomainObjPrivate {
9292

9393
virThread vmThreadWatcher;
9494
int vmThreadWatcherStop;
95+
96+
char *ch_path;
9597
};
9698

9799
#define CH_DOMAIN_PRIVATE(vm) \

src/ch/ch_monitor.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -586,15 +586,9 @@ virCHMonitorBuildResizeJson(const unsigned int nvcpus,
586586
return ret;
587587
}
588588

589-
/* generate command to launch Cloud-Hypervisor socket
590-
return -1 - error
591-
0 - OK
592-
Caller has to free the cmd
593-
*/
594-
static virCommandPtr
595-
chMonitorBuildSocketCmd(virDomainObjPtr vm, const char *socket_path)
589+
static char *getCHPath(virDomainObjPtr vm)
596590
{
597-
virCommandPtr cmd;
591+
char *ch_path = NULL;
598592

599593
if (vm->def == NULL) {
600594
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -603,12 +597,11 @@ chMonitorBuildSocketCmd(virDomainObjPtr vm, const char *socket_path)
603597
}
604598

605599
if (vm->def->emulator != NULL)
606-
cmd = virCommandNew(vm->def->emulator);
600+
ch_path = g_find_program_in_path(vm->def->emulator);
607601
else
608-
cmd = virCommandNew(CH_CMD);
602+
ch_path = g_find_program_in_path(CH_CMD);
609603

610-
virCommandAddArgList(cmd, "--api-socket", socket_path, NULL);
611-
return cmd;
604+
return ch_path;
612605
}
613606

614607
static const char *virCHMonitorEventStrings[] = {
@@ -931,16 +924,22 @@ static int virCHMonitorReadProcessEvents(virCHMonitorPtr mon,
931924
size_t max_sz = CH_MONITOR_BUFFER_SZ - mon->buf_offset;
932925
char *buf = mon->buffer + mon->buf_offset;
933926
virDomainObjPtr vm = mon->vm;
927+
virCHDomainObjPrivatePtr priv = vm->privateData;
934928
bool incomplete = false;
935929
int events = 0;
936930
size_t sz = 0;
931+
pid_t pid = 0;
937932

938933
memset(buf, 0, max_sz);
939934
do {
940935
ssize_t ret;
941936

942937
ret = read(monitor_fd, buf + sz, max_sz - sz);
943938
if (ret == 0 || (ret < 0 && errno == EINTR)) {
939+
if ((virPidFileReadPathIfAlive(priv->pidfile, &pid, priv->ch_path)) < 0 || (pid < 0)) {
940+
virCHProcessStop(CH_DOMAIN_PRIVATE(vm)->driver, vm, VIR_DOMAIN_SHUTOFF_CRASHED);
941+
return -1;
942+
}
944943
g_usleep(G_USEC_PER_SEC);
945944
continue;
946945
} else if (ret < 0) {
@@ -1181,8 +1180,12 @@ virCHMonitorNew(virDomainObjPtr vm, virCHDriverPtr driver)
11811180
goto cleanup;
11821181

11831182
/* prepare to launch Cloud-Hypervisor socket */
1184-
if (!(cmd = chMonitorBuildSocketCmd(vm, mon->socketpath)))
1185-
goto cleanup;
1183+
if (!(priv->ch_path = getCHPath(vm)))
1184+
goto cleanup;
1185+
1186+
cmd = virCommandNew(priv->ch_path);
1187+
1188+
virCommandAddArgList(cmd, "--api-socket", mon->socketpath, NULL);
11861189

11871190
if (virFileMakePath(cfg->stateDir) < 0) {
11881191
virReportSystemError(errno,

0 commit comments

Comments
 (0)