Skip to content

Commit

Permalink
add virt-host-validate-ch for cloud-hypervisor
Browse files Browse the repository at this point in the history
  • Loading branch information
Wei-Chen Chen committed Sep 14, 2020
1 parent 3bc490e commit 060d7bd
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 0 deletions.
5 changes: 5 additions & 0 deletions tools/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ if conf.has('WITH_HOST_VALIDATE')
'virt-host-validate-bhyve.c',
]
endif
if conf.has('WITH_CH')
virt_host_validate_sources += [
'virt-host-validate-ch.c',
]
endif

executable(
'virt-host-validate',
Expand Down
129 changes: 129 additions & 0 deletions tools/virt-host-validate-ch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#include <config.h>

#include "virt-host-validate-ch.h"
#include "virt-host-validate-common.h"
#include "virarch.h"
#include "virbitmap.h"

int validateMinimumChVersion(char* ver_string)
{
// expected ver_string example: "cloud-hypversor v0.8.1-<hash>"
int min_major_version = 0;
int min_minor_version = 9;
char *ptr = strtok(ver_string, " ");
char *last_tok = NULL;
while(ptr != NULL)
{
last_tok = ptr;
ptr = strtok(NULL, " ");
}
if (last_tok == NULL)
return -1;

// eliminate 'v'
last_tok++;
ptr = strtok(last_tok, ".");
if (ptr == NULL)
return -1;
int majorVer = atoi(ptr);
ptr = strtok(NULL, ".");
if (ptr == NULL)
return -1;
int minorVer = atoi(ptr);

if (majorVer > min_major_version)
{
return 0;
}
else if (majorVer == min_major_version)
{
if (minorVer >= min_minor_version)
return 0;
else
return -1;
}
else
{
return -1;
}
}

int virHostValidateCh(void)
{
int ret = 0;
virBitmapPtr flags;
bool hasHwVirt = false;
bool hasVirtFlag = false;
virArch arch = virArchFromHost();
const char *kvmhint = _("Check that CPU and firmware supports virtualization "
"and kvm module is loaded");

if (!(flags = virHostValidateGetCPUFlags()))
return -1;

switch ((int)arch) {
case VIR_ARCH_I686:
case VIR_ARCH_X86_64:
hasVirtFlag = true;
kvmhint = _("Check that the 'kvm-intel' or 'kvm-amd' modules are "
"loaded & the BIOS has enabled virtualization");
if (virBitmapIsBitSet(flags, VIR_HOST_VALIDATE_CPU_FLAG_SVM) ||
virBitmapIsBitSet(flags, VIR_HOST_VALIDATE_CPU_FLAG_VMX))
hasHwVirt = true;
break;
case VIR_ARCH_S390:
case VIR_ARCH_S390X:
hasVirtFlag = true;
if (virBitmapIsBitSet(flags, VIR_HOST_VALIDATE_CPU_FLAG_SIE))
hasHwVirt = true;
break;
case VIR_ARCH_PPC64:
case VIR_ARCH_PPC64LE:
hasVirtFlag = true;
hasHwVirt = true;
break;
default:
hasHwVirt = false;
}

if (hasVirtFlag) {
virHostMsgCheck("CH", "%s", _("for hardware virtualization"));
if (hasHwVirt) {
virHostMsgPass();
} else {
virHostMsgFail(VIR_HOST_VALIDATE_FAIL,
_("Only emulated CPUs are available, performance will be significantly limited"));
ret = -1;
}
}

if (hasHwVirt || !hasVirtFlag) {
if (virHostValidateDeviceExists("CH", "/dev/kvm",
VIR_HOST_VALIDATE_FAIL,
kvmhint) <0)
ret = -1;
else if (virHostValidateDeviceAccessible("CH", "/dev/kvm",
VIR_HOST_VALIDATE_FAIL,
_("Check /dev/kvm is world writable or you are in "
"a group that is allowed to access it")) < 0)
ret = -1;
}

char verResult[256];
virHostMsgCheck("CH", "Cloud-Hypvervisor >= 0.9.0");
if (virHostValidateCmdOutput("cloud-hypervisor --version", verResult, 256,
VIR_HOST_VALIDATE_FAIL, "Failed to get command output of 'cloud-hypervisor --version'") < 0)
ret = -1;
if (validateMinimumChVersion(verResult) < 0)
{
virHostMsgFail(VIR_HOST_VALIDATE_FAIL,
_("Failed to meet minimum version of cloud-hypervisor (minimum:0.9.0)"));
ret = -1;
}
else
{
virHostMsgPass();
}

return ret;
}
4 changes: 4 additions & 0 deletions tools/virt-host-validate-ch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

int validateMinimumChVersion(char* ver_string);
int virHostValidateCh(void);
28 changes: 28 additions & 0 deletions tools/virt-host-validate-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,31 @@ int virHostValidateSecureGuests(const char *hvname,

return 0;
}

int virHostValidateCmdOutput(const char* cmd_name,
char* cmd_output,
int max_output_size,
virHostValidateLevel level,
const char *hint)
{
int ret = -1;
FILE *restrict fp;
if(!cmd_output)
return ret;

fp = popen(cmd_name, "r");
if (fp == NULL) {
pclose(fp);
virHostMsgFail(level, "%s", hint);
return -1;
}
while (fgets(cmd_output, max_output_size, fp) != NULL) {
if (strlen(cmd_output) > 0) {
ret = 0;
break;
}
}
pclose(fp);
return ret;
}

6 changes: 6 additions & 0 deletions tools/virt-host-validate-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,9 @@ int virHostValidateSecureGuests(const char *hvname,
virHostValidateLevel level);

bool virHostKernelModuleIsLoaded(const char *module);

int virHostValidateCmdOutput(const char* cmd_name,
char* cmd_output,
int max_output_size,
virHostValidateLevel level,
const char *hint);
12 changes: 12 additions & 0 deletions tools/virt-host-validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
#if WITH_BHYVE
# include "virt-host-validate-bhyve.h"
#endif
#if WITH_CH
# include "virt-host-validate-ch.h"
#endif

static void
show_help(FILE *out, const char *argv0)
Expand All @@ -52,6 +55,7 @@ show_help(FILE *out, const char *argv0)
" - qemu\n"
" - lxc\n"
" - bhyve\n"
" - cloud-hypervisor\n"
"\n"
" Options:\n"
" -h, --help Display command line help\n"
Expand Down Expand Up @@ -142,6 +146,14 @@ main(int argc, char **argv)
}
#endif

#if WITH_CH
if (!hvname || STREQ(hvname, "ch")) {
usedHvname = true;
if (virHostValidateCh() < 0)
ret = EXIT_FAILURE;
}
#endif

if (hvname && !usedHvname) {
fprintf(stderr, _("%s: unsupported hypervisor name %s\n"),
argv[0], hvname);
Expand Down

0 comments on commit 060d7bd

Please sign in to comment.