From nobody Thu Sep 19 01:08:38 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1717771009933216.52506026361948; Fri, 7 Jun 2024 07:36:49 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id C43CA259F; Fri, 7 Jun 2024 10:36:47 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 108C02473; Fri, 7 Jun 2024 10:26:46 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 37BC623D0; Fri, 7 Jun 2024 10:26:34 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id E6E3A234D for ; Fri, 7 Jun 2024 10:26:25 -0400 (EDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-690-VrhDUAYwPt2Q9ToUjP7p_Q-1; Fri, 07 Jun 2024 10:26:23 -0400 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1E82B800173 for ; Fri, 7 Jun 2024 14:26:22 +0000 (UTC) Received: from toolbox.redhat.com (unknown [10.39.193.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5B7FB492BC6; Fri, 7 Jun 2024 14:26:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1717770384; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7lIPj+x3c4T0g1d575rYR/jJalDaDuov703hOfORQGk=; b=EtLiMocYYLTE6Ww6Ia0AQQ1f8wJdVR7aPCDmJ84TBwohqkYZOxlQrHW63wE2k8VZg9J5pG 11JTsNvoga2+YxLavskiUkLNptVgVcsCiDbLNzBPUZhqz1mT5W6cn0nXYIjHsQUt/JmxmI Ch7nVmDtclX2YJ+JYWuFdEgC5C7ztNs= X-MC-Unique: VrhDUAYwPt2Q9ToUjP7p_Q-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH 5/9] tools: split off common helpers for host validate tool Date: Fri, 7 Jun 2024 15:26:12 +0100 Message-ID: <20240607142616.749339-6-berrange@redhat.com> In-Reply-To: <20240607142616.749339-1-berrange@redhat.com> References: <20240607142616.749339-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.9 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 6XOHDUDBAJT2CENX2PYURAIRPQSB3YWW X-Message-ID-Hash: 6XOHDUDBAJT2CENX2PYURAIRPQSB3YWW X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1717771010401100001 Content-Type: text/plain; charset="utf-8" The common messaging helpers will be reused in the new impl of the virt-pki-validate tool. Signed-off-by: Daniel P. Berrang=C3=A9 --- po/POTFILES | 1 + tools/meson.build | 1 + tools/virt-host-validate-ch.c | 12 +- tools/virt-host-validate-common.c | 308 +++++++++++------------------- tools/virt-host-validate-common.h | 48 +---- tools/virt-host-validate-lxc.c | 18 +- tools/virt-host-validate-qemu.c | 30 +-- tools/virt-host-validate.c | 2 +- tools/virt-validate-common.c | 110 +++++++++++ tools/virt-validate-common.h | 57 ++++++ 10 files changed, 319 insertions(+), 268 deletions(-) create mode 100644 tools/virt-validate-common.c create mode 100644 tools/virt-validate-common.h diff --git a/po/POTFILES b/po/POTFILES index 0f68c652eb..cb73d07904 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -391,6 +391,7 @@ tools/virt-host-validate-qemu.c tools/virt-host-validate.c tools/virt-login-shell-helper.c tools/virt-pki-query-dn.c +tools/virt-validate-common.c tools/vsh-table.c tools/vsh.c tools/vsh.h diff --git a/tools/meson.build b/tools/meson.build index 1bb84be0be..feb6b7c3ad 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -40,6 +40,7 @@ libvirt_shell_lib =3D static_library( =20 if conf.has('WITH_HOST_VALIDATE') virt_host_validate_sources =3D [ + 'virt-validate-common.c', 'virt-host-validate.c', 'virt-host-validate-common.c', ] diff --git a/tools/virt-host-validate-ch.c b/tools/virt-host-validate-ch.c index 3f96423836..e48c8c825f 100644 --- a/tools/virt-host-validate-ch.c +++ b/tools/virt-host-validate-ch.c @@ -57,21 +57,21 @@ int virHostValidateCh(void) } =20 if (hasVirtFlag) { - virHostMsgCheck("CH", "%s", _("Checking for hardware virtualizatio= n")); + virValidateCheck("CH", "%s", _("Checking for hardware virtualizati= on")); if (hasHwVirt) { - virHostMsgPass(); + virValidatePass(); } else { - virHostMsgFail(VIR_HOST_VALIDATE_FAIL, - _("Only emulated CPUs are available, performanc= e will be significantly limited")); + virValidateFail(VIR_VALIDATE_FAIL, + _("Only emulated CPUs are available, performan= ce will be significantly limited")); ret =3D -1; } } =20 if (hasHwVirt || !hasVirtFlag) { - if (virHostValidateDeviceExists("CH", "/dev/kvm", VIR_HOST_VALIDAT= E_FAIL, + if (virHostValidateDeviceExists("CH", "/dev/kvm", VIR_VALIDATE_FAI= L, kvmhint) < 0) ret =3D -1; - else if (virHostValidateDeviceAccessible("CH", "/dev/kvm", VIR_HOS= T_VALIDATE_FAIL, + else if (virHostValidateDeviceAccessible("CH", "/dev/kvm", VIR_VAL= IDATE_FAIL, _("Check /dev/kvm is worl= d writable or you are in a group that is allowed to access it")) < 0) ret =3D -1; } diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-c= ommon.c index 66f08ac2b3..ad06dfb245 100644 --- a/tools/virt-host-validate-common.c +++ b/tools/virt-host-validate-common.c @@ -45,144 +45,58 @@ VIR_ENUM_IMPL(virHostValidateCPUFlag, "158", "sev"); =20 -static bool quiet; - -void virHostMsgSetQuiet(bool quietFlag) -{ - quiet =3D quietFlag; -} - -void virHostMsgCheck(const char *prefix, - const char *format, - ...) -{ - va_list args; - g_autofree char *msg =3D NULL; - - if (quiet) - return; - - va_start(args, format); - msg =3D g_strdup_vprintf(format, args); - va_end(args); - - fprintf(stdout, "%1$6s: %2$-69s: ", prefix, msg); -} - -static bool virHostMsgWantEscape(void) -{ - static bool detectTty =3D true; - static bool wantEscape; - if (detectTty) { - if (isatty(STDOUT_FILENO)) - wantEscape =3D true; - detectTty =3D false; - } - return wantEscape; -} - -void virHostMsgPass(void) -{ - if (quiet) - return; - - if (virHostMsgWantEscape()) - fprintf(stdout, "\033[32m%s\033[0m\n", _("PASS")); - else - fprintf(stdout, "%s\n", _("PASS")); -} - - -static const char * failMessages[] =3D { - N_("FAIL"), - N_("WARN"), - N_("NOTE"), -}; - -G_STATIC_ASSERT(G_N_ELEMENTS(failMessages) =3D=3D VIR_HOST_VALIDATE_LAST); - -static const char *failEscapeCodes[] =3D { - "\033[31m", - "\033[33m", - "\033[34m", -}; - -G_STATIC_ASSERT(G_N_ELEMENTS(failEscapeCodes) =3D=3D VIR_HOST_VALIDATE_LAS= T); - -void virHostMsgFail(virHostValidateLevel level, - const char *format, - ...) -{ - va_list args; - g_autofree char *msg =3D NULL; - - if (quiet) - return; - - va_start(args, format); - msg =3D g_strdup_vprintf(format, args); - va_end(args); - - if (virHostMsgWantEscape()) - fprintf(stdout, "%s%s\033[0m (%s)\n", - failEscapeCodes[level], _(failMessages[level]), msg); - else - fprintf(stdout, "%s (%s)\n", - _(failMessages[level]), msg); -} - =20 int virHostValidateDeviceExists(const char *hvname, const char *dev_name, - virHostValidateLevel level, + virValidateLevel level, const char *hint) { - virHostMsgCheck(hvname, _("Checking if device '%1$s' exists"), dev_nam= e); + virValidateCheck(hvname, _("Checking if device '%1$s' exists"), dev_na= me); =20 if (access(dev_name, F_OK) < 0) { - virHostMsgFail(level, "%s", hint); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "%s", hint); + return VIR_VALIDATE_FAILURE(level); } =20 - virHostMsgPass(); + virValidatePass(); return 0; } =20 =20 int virHostValidateDeviceAccessible(const char *hvname, const char *dev_name, - virHostValidateLevel level, + virValidateLevel level, const char *hint) { - virHostMsgCheck(hvname, _("Checking if device '%1$s' is accessible"), = dev_name); + virValidateCheck(hvname, _("Checking if device '%1$s' is accessible"),= dev_name); =20 if (access(dev_name, R_OK|W_OK) < 0) { - virHostMsgFail(level, "%s", hint); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "%s", hint); + return VIR_VALIDATE_FAILURE(level); } =20 - virHostMsgPass(); + virValidatePass(); return 0; } =20 =20 int virHostValidateNamespace(const char *hvname, const char *ns_name, - virHostValidateLevel level, + virValidateLevel level, const char *hint) { char nspath[100]; =20 - virHostMsgCheck(hvname, _("Checking for namespace '%1$s'"), ns_name); + virValidateCheck(hvname, _("Checking for namespace '%1$s'"), ns_name); =20 g_snprintf(nspath, sizeof(nspath), "/proc/self/ns/%s", ns_name); =20 if (access(nspath, F_OK) < 0) { - virHostMsgFail(level, "%s", hint); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "%s", hint); + return VIR_VALIDATE_FAILURE(level); } =20 - virHostMsgPass(); + virValidatePass(); return 0; } =20 @@ -248,7 +162,7 @@ virBitmap *virHostValidateGetCPUFlags(void) =20 int virHostValidateLinuxKernel(const char *hvname, int version, - virHostValidateLevel level, + virValidateLevel level, const char *hint) { struct utsname uts; @@ -256,26 +170,26 @@ int virHostValidateLinuxKernel(const char *hvname, =20 uname(&uts); =20 - virHostMsgCheck(hvname, _("Checking for Linux >=3D %1$d.%2$d.%3$d"), - ((version >> 16) & 0xff), - ((version >> 8) & 0xff), - (version & 0xff)); + virValidateCheck(hvname, _("Checking for Linux >=3D %1$d.%2$d.%3$d"), + ((version >> 16) & 0xff), + ((version >> 8) & 0xff), + (version & 0xff)); =20 if (STRNEQ(uts.sysname, "Linux")) { - virHostMsgFail(level, "%s", hint); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "%s", hint); + return VIR_VALIDATE_FAILURE(level); } =20 if (virStringParseVersion(&thisversion, uts.release, true) < 0) { - virHostMsgFail(level, "%s", hint); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "%s", hint); + return VIR_VALIDATE_FAILURE(level); } =20 if (thisversion < version) { - virHostMsgFail(level, "%s", hint); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "%s", hint); + return VIR_VALIDATE_FAILURE(level); } else { - virHostMsgPass(); + virValidatePass(); return 0; } } @@ -283,7 +197,7 @@ int virHostValidateLinuxKernel(const char *hvname, #ifdef __linux__ int virHostValidateCGroupControllers(const char *hvname, int controllers, - virHostValidateLevel level) + virValidateLevel level) { g_autoptr(virCgroup) group =3D NULL; int ret =3D 0; @@ -292,7 +206,7 @@ int virHostValidateCGroupControllers(const char *hvname, if (virCgroupNew("/", -1, &group) < 0) { fprintf(stderr, "Unable to initialize cgroups: %s\n", virGetLastErrorMessage()); - return VIR_HOST_VALIDATE_FAILURE(level); + return VIR_VALIDATE_FAILURE(level); } =20 for (i =3D 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { @@ -302,15 +216,15 @@ int virHostValidateCGroupControllers(const char *hvna= me, if (!(controllers & flag)) continue; =20 - virHostMsgCheck(hvname, _("Checking for cgroup '%1$s' controller s= upport"), cg_name); + virValidateCheck(hvname, _("Checking for cgroup '%1$s' controller = support"), cg_name); =20 if (!virCgroupHasController(group, i)) { - ret =3D VIR_HOST_VALIDATE_FAILURE(level); - virHostMsgFail(level, "Enable '%s' in kernel Kconfig file or " - "mount/enable cgroup controller in your system", - cg_name); + ret =3D VIR_VALIDATE_FAILURE(level); + virValidateFail(level, "Enable '%s' in kernel Kconfig file or " + "mount/enable cgroup controller in your system= ", + cg_name); } else { - virHostMsgPass(); + virValidatePass(); } } =20 @@ -319,15 +233,15 @@ int virHostValidateCGroupControllers(const char *hvna= me, #else /* !__linux__ */ int virHostValidateCGroupControllers(const char *hvname G_GNUC_UNUSED, int controllers G_GNUC_UNUSED, - virHostValidateLevel level) + virValidateLevel level) { - virHostMsgFail(level, "%s", "This platform does not support cgroups"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "%s", "This platform does not support cgroups"); + return VIR_VALIDATE_FAILURE(level); } #endif /* !__linux__ */ =20 int virHostValidateIOMMU(const char *hvname, - virHostValidateLevel level) + virValidateLevel level) { g_autoptr(virBitmap) flags =3D NULL; struct stat sb; @@ -337,7 +251,7 @@ int virHostValidateIOMMU(const char *hvname, struct dirent *dent; int rc; =20 - virHostMsgCheck(hvname, "%s", _("Checking for device assignment IOMMU = support")); + virValidateCheck(hvname, "%s", _("Checking for device assignment IOMMU= support")); =20 flags =3D virHostValidateGetCPUFlags(); =20 @@ -348,28 +262,28 @@ int virHostValidateIOMMU(const char *hvname, =20 if (isIntel) { if (access("/sys/firmware/acpi/tables/DMAR", F_OK) =3D=3D 0) { - virHostMsgPass(); + virValidatePass(); bootarg =3D "intel_iommu=3Don"; } else { - virHostMsgFail(level, - "No ACPI DMAR table found, IOMMU either " - "disabled in BIOS or not supported by this " - "hardware platform"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "No ACPI DMAR table found, IOMMU either " + "disabled in BIOS or not supported by this " + "hardware platform"); + return VIR_VALIDATE_FAILURE(level); } } else if (isAMD) { if (access("/sys/firmware/acpi/tables/IVRS", F_OK) =3D=3D 0) { - virHostMsgPass(); + virValidatePass(); bootarg =3D "iommu=3Dpt iommu=3D1"; } else { - virHostMsgFail(level, - "No ACPI IVRS table found, IOMMU either " - "disabled in BIOS or not supported by this " - "hardware platform"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "No ACPI IVRS table found, IOMMU either " + "disabled in BIOS or not supported by this " + "hardware platform"); + return VIR_VALIDATE_FAILURE(level); } } else if (ARCH_IS_PPC64(arch)) { - virHostMsgPass(); + virValidatePass(); } else if (ARCH_IS_S390(arch)) { g_autoptr(DIR) dir =3D NULL; =20 @@ -378,41 +292,41 @@ int virHostValidateIOMMU(const char *hvname, * no PCI devices the directory is still there but is * empty. */ if (!virDirOpen(&dir, "/sys/bus/pci/devices")) { - virHostMsgFail(VIR_HOST_VALIDATE_NOTE, - "Skipped - PCI support disabled"); - return VIR_HOST_VALIDATE_FAILURE(VIR_HOST_VALIDATE_NOTE); + virValidateFail(VIR_VALIDATE_NOTE, + "Skipped - PCI support disabled"); + return VIR_VALIDATE_FAILURE(VIR_VALIDATE_NOTE); } rc =3D virDirRead(dir, &dent, NULL); if (rc <=3D 0) { - virHostMsgFail(VIR_HOST_VALIDATE_NOTE, - "Skipped - No PCI devices are online"); - return VIR_HOST_VALIDATE_FAILURE(VIR_HOST_VALIDATE_NOTE); + virValidateFail(VIR_VALIDATE_NOTE, + "Skipped - No PCI devices are online"); + return VIR_VALIDATE_FAILURE(VIR_VALIDATE_NOTE); } - virHostMsgPass(); + virValidatePass(); } else if (ARCH_IS_ARM(arch)) { if (access("/sys/firmware/acpi/tables/IORT", F_OK) !=3D 0) { - virHostMsgFail(level, - "No ACPI IORT table found, IOMMU not " - "supported by this hardware platform"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "No ACPI IORT table found, IOMMU not " + "supported by this hardware platform"); + return VIR_VALIDATE_FAILURE(level); } else { rc =3D virAcpiHasSMMU(); if (rc < 0) { - virHostMsgFail(level, - "Failed to parse ACPI IORT table"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "Failed to parse ACPI IORT table"); + return VIR_VALIDATE_FAILURE(level); } else if (rc =3D=3D 0) { - virHostMsgFail(level, - "No SMMU found"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "No SMMU found"); + return VIR_VALIDATE_FAILURE(level); } else { - virHostMsgPass(); + virValidatePass(); } } } else { - virHostMsgFail(level, - "Unknown if this platform has IOMMU support"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "Unknown if this platform has IOMMU support"); + return VIR_VALIDATE_FAILURE(level); } =20 =20 @@ -423,17 +337,17 @@ int virHostValidateIOMMU(const char *hvname, if (!S_ISDIR(sb.st_mode)) return 0; =20 - virHostMsgCheck(hvname, "%s", _("Checking if IOMMU is enabled by kerne= l")); + virValidateCheck(hvname, "%s", _("Checking if IOMMU is enabled by kern= el")); if (sb.st_nlink <=3D 2) { if (bootarg) - virHostMsgFail(level, - "IOMMU appears to be disabled in kernel. " - "Add %s to kernel cmdline arguments", bootarg); + virValidateFail(level, + "IOMMU appears to be disabled in kernel. " + "Add %s to kernel cmdline arguments", bootarg); else - virHostMsgFail(level, "IOMMU capability not compiled into kern= el."); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "IOMMU capability not compiled into ker= nel."); + return VIR_VALIDATE_FAILURE(level); } - virHostMsgPass(); + virValidatePass(); return 0; } =20 @@ -466,7 +380,7 @@ bool virHostKernelModuleIsLoaded(const char *module) =20 =20 int virHostValidateSecureGuests(const char *hvname, - virHostValidateLevel level) + virValidateLevel level) { g_autoptr(virBitmap) flags =3D NULL; bool hasFac158 =3D false; @@ -483,13 +397,13 @@ int virHostValidateSecureGuests(const char *hvname, else if (flags && virBitmapIsBitSet(flags, VIR_HOST_VALIDATE_CPU_FLAG_= SEV)) hasAMDSev =3D true; =20 - virHostMsgCheck(hvname, "%s", _("Checking for secure guest support")); + virValidateCheck(hvname, "%s", _("Checking for secure guest support")); if (ARCH_IS_S390(arch)) { if (hasFac158) { if (!virFileIsDir("/sys/firmware/uv")) { - virHostMsgFail(level, "IBM Secure Execution not supported = by " - "the currently used kernel"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "IBM Secure Execution not supported= by " + "the currently used kernel"); + return VIR_VALIDATE_FAILURE(level); } =20 /* we're prefix matching rather than equality matching here, b= ecause @@ -501,47 +415,47 @@ int virHostValidateSecureGuests(const char *hvname, G_N_ELEMENTS(kIBMValues), VIR_KERNEL_CMDLINE_FLAGS_SEARCH= _FIRST | VIR_KERNEL_CMDLINE_FLAGS_CMP_PR= EFIX)) { - virHostMsgPass(); + virValidatePass(); return 1; } else { - virHostMsgFail(level, - "IBM Secure Execution appears to be disable= d " - "in kernel. Add prot_virt=3D1 to kernel cmd= line " - "arguments"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "IBM Secure Execution appears to be disabl= ed " + "in kernel. Add prot_virt=3D1 to kernel cm= dline " + "arguments"); + return VIR_VALIDATE_FAILURE(level); } } else { - virHostMsgFail(level, "Hardware or firmware does not provide " - "support for IBM Secure Execution"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "Hardware or firmware does not provide " + "support for IBM Secure Execution"); + return VIR_VALIDATE_FAILURE(level); } } else if (hasAMDSev) { if (virFileReadValueString(&mod_value, "/sys/module/kvm_amd/parame= ters/sev") < 0) { - virHostMsgFail(level, "AMD Secure Encrypted Virtualization not= " - "supported by the currently used kernel"= ); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, "AMD Secure Encrypted Virtualization no= t " + "supported by the currently used kernel"); + return VIR_VALIDATE_FAILURE(level); } =20 if (mod_value[0] !=3D '1' && mod_value[0] !=3D 'Y' && mod_value[0]= !=3D 'y') { - virHostMsgFail(level, - "AMD Secure Encrypted Virtualization appears to= be " - "disabled in kernel. Add kvm_amd.sev=3D1 " - "to the kernel cmdline arguments"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "AMD Secure Encrypted Virtualization appears t= o be " + "disabled in kernel. Add kvm_amd.sev=3D1 " + "to the kernel cmdline arguments"); + return VIR_VALIDATE_FAILURE(level); } =20 if (virFileExists("/dev/sev")) { - virHostMsgPass(); + virValidatePass(); return 1; } else { - virHostMsgFail(level, - "AMD Secure Encrypted Virtualization appears to= be " - "disabled in firmware."); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "AMD Secure Encrypted Virtualization appears t= o be " + "disabled in firmware."); + return VIR_VALIDATE_FAILURE(level); } } =20 - virHostMsgFail(level, - "Unknown if this platform has Secure Guest support"); - return VIR_HOST_VALIDATE_FAILURE(level); + virValidateFail(level, + "Unknown if this platform has Secure Guest support"); + return VIR_VALIDATE_FAILURE(level); } diff --git a/tools/virt-host-validate-common.h b/tools/virt-host-validate-c= ommon.h index 9334fa8588..7fb3545fe3 100644 --- a/tools/virt-host-validate-common.h +++ b/tools/virt-host-validate-common.h @@ -24,14 +24,7 @@ #include "internal.h" #include "virbitmap.h" #include "virenum.h" - -typedef enum { - VIR_HOST_VALIDATE_FAIL, - VIR_HOST_VALIDATE_WARN, - VIR_HOST_VALIDATE_NOTE, - - VIR_HOST_VALIDATE_LAST, -} virHostValidateLevel; +#include "virt-validate-common.h" =20 typedef enum { VIR_HOST_VALIDATE_CPU_FLAG_VMX =3D 0, @@ -45,61 +38,36 @@ typedef enum { =20 VIR_ENUM_DECL(virHostValidateCPUFlag); =20 -/** - * VIR_HOST_VALIDATE_FAILURE - * @level: the virHostValidateLevel to be checked - * - * This macro is to be used in to return a failures based on the - * virHostValidateLevel use in the function. - * - * If the virHostValidateLevel is VIR_HOST_VALIDATE_FAIL, -1 is returned. - * 0 is returned otherwise (as the virHosValidateLevel is then either a - * Warn or a Note). - */ - -#define VIR_HOST_VALIDATE_FAILURE(level) (level =3D=3D VIR_HOST_VALIDATE_F= AIL) ? -1 : 0 - -void virHostMsgSetQuiet(bool quietFlag); - -void virHostMsgCheck(const char *prefix, - const char *format, - ...) G_GNUC_PRINTF(2, 3); - -void virHostMsgPass(void); -void virHostMsgFail(virHostValidateLevel level, - const char *format, - ...) G_GNUC_PRINTF(2, 3); - int virHostValidateDeviceExists(const char *hvname, const char *dev_name, - virHostValidateLevel level, + virValidateLevel level, const char *hint); =20 int virHostValidateDeviceAccessible(const char *hvname, const char *dev_name, - virHostValidateLevel level, + virValidateLevel level, const char *hint); =20 virBitmap *virHostValidateGetCPUFlags(void); =20 int virHostValidateLinuxKernel(const char *hvname, int version, - virHostValidateLevel level, + virValidateLevel level, const char *hint); =20 int virHostValidateNamespace(const char *hvname, const char *ns_name, - virHostValidateLevel level, + virValidateLevel level, const char *hint); =20 int virHostValidateCGroupControllers(const char *hvname, int controllers, - virHostValidateLevel level); + virValidateLevel level); =20 int virHostValidateIOMMU(const char *hvname, - virHostValidateLevel level); + virValidateLevel level); =20 int virHostValidateSecureGuests(const char *hvname, - virHostValidateLevel level); + virValidateLevel level); =20 bool virHostKernelModuleIsLoaded(const char *module); diff --git a/tools/virt-host-validate-lxc.c b/tools/virt-host-validate-lxc.c index 8613f37cc7..5d6dbdf647 100644 --- a/tools/virt-host-validate-lxc.c +++ b/tools/virt-host-validate-lxc.c @@ -30,37 +30,37 @@ int virHostValidateLXC(void) int ret =3D 0; =20 if (virHostValidateLinuxKernel("LXC", (2 << 16) | (6 << 8) | 26, - VIR_HOST_VALIDATE_FAIL, + VIR_VALIDATE_FAIL, _("Upgrade to a kernel supporting names= paces")) < 0) ret =3D -1; =20 if (virHostValidateNamespace("LXC", "ipc", - VIR_HOST_VALIDATE_FAIL, + VIR_VALIDATE_FAIL, _("IPC namespace support is required")) <= 0) ret =3D -1; =20 if (virHostValidateNamespace("LXC", "mnt", - VIR_HOST_VALIDATE_FAIL, + VIR_VALIDATE_FAIL, _("Mount namespace support is required"))= < 0) ret =3D -1; =20 if (virHostValidateNamespace("LXC", "pid", - VIR_HOST_VALIDATE_FAIL, + VIR_VALIDATE_FAIL, _("PID namespace support is required")) <= 0) ret =3D -1; =20 if (virHostValidateNamespace("LXC", "uts", - VIR_HOST_VALIDATE_FAIL, + VIR_VALIDATE_FAIL, _("UTS namespace support is required")) <= 0) ret =3D -1; =20 if (virHostValidateNamespace("LXC", "net", - VIR_HOST_VALIDATE_WARN, + VIR_VALIDATE_WARN, _("Network namespace support is recommend= ed")) < 0) ret =3D -1; =20 if (virHostValidateNamespace("LXC", "user", - VIR_HOST_VALIDATE_WARN, + VIR_VALIDATE_WARN, _("User namespace support is recommended"= )) < 0) ret =3D -1; =20 @@ -72,13 +72,13 @@ int virHostValidateLXC(void) (1 << VIR_CGROUP_CONTROLLER_DEVIC= ES) | (1 << VIR_CGROUP_CONTROLLER_FREEZ= ER) | (1 << VIR_CGROUP_CONTROLLER_BLKIO= ), - VIR_HOST_VALIDATE_FAIL) < 0) { + VIR_VALIDATE_FAIL) < 0) { ret =3D -1; } =20 #if WITH_FUSE if (virHostValidateDeviceExists("LXC", "/sys/fs/fuse/connections", - VIR_HOST_VALIDATE_FAIL, + VIR_VALIDATE_FAIL, _("Load the 'fuse' module to enable /p= roc/ overrides")) < 0) ret =3D -1; #endif diff --git a/tools/virt-host-validate-qemu.c b/tools/virt-host-validate-qem= u.c index b685fa01ba..833bb1b914 100644 --- a/tools/virt-host-validate-qemu.c +++ b/tools/virt-host-validate-qemu.c @@ -64,44 +64,44 @@ int virHostValidateQEMU(void) } =20 if (hasVirtFlag) { - virHostMsgCheck("QEMU", "%s", _("Checking for hardware virtualizat= ion")); + virValidateCheck("QEMU", "%s", _("Checking for hardware virtualiza= tion")); if (hasHwVirt) { - virHostMsgPass(); + virValidatePass(); } else { - virHostMsgFail(VIR_HOST_VALIDATE_FAIL, - _("Host not compatible with KVM; HW virtualizat= ion CPU features not found. Only emulated CPUs are available; performance w= ill be significantly limited")); + virValidateFail(VIR_VALIDATE_FAIL, + _("Host not compatible with KVM; HW virtualiza= tion CPU features not found. Only emulated CPUs are available; performance = will be significantly limited")); ret =3D -1; } } =20 if (hasHwVirt || !hasVirtFlag) { if (virHostValidateDeviceExists("QEMU", "/dev/kvm", - VIR_HOST_VALIDATE_FAIL, + VIR_VALIDATE_FAIL, kvmhint) <0) ret =3D -1; else if (virHostValidateDeviceAccessible("QEMU", "/dev/kvm", - VIR_HOST_VALIDATE_FAIL, + VIR_VALIDATE_FAIL, _("Check /dev/kvm is worl= d writable or you are in a group that is allowed to access it")) < 0) ret =3D -1; } =20 if (arch =3D=3D VIR_ARCH_PPC64 || arch =3D=3D VIR_ARCH_PPC64LE) { - virHostMsgCheck("QEMU", "%s", _("Checking for PowerPC KVM module l= oaded")); + virValidateCheck("QEMU", "%s", _("Checking for PowerPC KVM module = loaded")); =20 if (!virHostKernelModuleIsLoaded("kvm_hv")) - virHostMsgFail(VIR_HOST_VALIDATE_WARN, - _("Load kvm_hv for better performance")); + virValidateFail(VIR_VALIDATE_WARN, + _("Load kvm_hv for better performance")); else - virHostMsgPass(); + virValidatePass(); } =20 if (virHostValidateDeviceExists("QEMU", "/dev/vhost-net", - VIR_HOST_VALIDATE_WARN, + VIR_VALIDATE_WARN, _("Load the 'vhost_net' module to impr= ove performance of virtio networking")) < 0) ret =3D -1; =20 if (virHostValidateDeviceExists("QEMU", "/dev/net/tun", - VIR_HOST_VALIDATE_FAIL, + VIR_VALIDATE_FAIL, _("Load the 'tun' module to enable net= working for QEMU guests")) < 0) ret =3D -1; =20 @@ -112,16 +112,16 @@ int virHostValidateQEMU(void) (1 << VIR_CGROUP_CONTROLLER_CPUSE= T) | (1 << VIR_CGROUP_CONTROLLER_DEVIC= ES) | (1 << VIR_CGROUP_CONTROLLER_BLKIO= ), - VIR_HOST_VALIDATE_WARN) < 0) { + VIR_VALIDATE_WARN) < 0) { ret =3D -1; } =20 if (virHostValidateIOMMU("QEMU", - VIR_HOST_VALIDATE_WARN) < 0) + VIR_VALIDATE_WARN) < 0) ret =3D -1; =20 if (virHostValidateSecureGuests("QEMU", - VIR_HOST_VALIDATE_WARN) < 0) + VIR_VALIDATE_WARN) < 0) ret =3D -1; =20 return ret; diff --git a/tools/virt-host-validate.c b/tools/virt-host-validate.c index d9fa52c310..426648a5d3 100644 --- a/tools/virt-host-validate.c +++ b/tools/virt-host-validate.c @@ -124,7 +124,7 @@ main(int argc, char **argv) if (argc > 1) hvname =3D argv[optind]; =20 - virHostMsgSetQuiet(quiet); + virValidateSetQuiet(quiet); =20 #if WITH_QEMU if (!hvname || STREQ(hvname, "qemu")) { diff --git a/tools/virt-validate-common.c b/tools/virt-validate-common.c new file mode 100644 index 0000000000..88c10e846f --- /dev/null +++ b/tools/virt-validate-common.c @@ -0,0 +1,110 @@ +/* + * virt-validate-common.c: Sanity check helper APIs + * + * Copyright (C) 2012-2024 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + */ + +#include + +#include "virt-validate-common.h" + +static bool quiet; + +void virValidateSetQuiet(bool quietFlag) +{ + quiet =3D quietFlag; +} + +void virValidateCheck(const char *prefix, + const char *format, + ...) +{ + va_list args; + g_autofree char *msg =3D NULL; + + if (quiet) + return; + + va_start(args, format); + msg =3D g_strdup_vprintf(format, args); + va_end(args); + + fprintf(stdout, "%1$6s: %2$-69s: ", prefix, msg); +} + +static bool virValidateWantEscape(void) +{ + static bool detectTty =3D true; + static bool wantEscape; + if (detectTty) { + if (isatty(STDOUT_FILENO)) + wantEscape =3D true; + detectTty =3D false; + } + return wantEscape; +} + +void virValidatePass(void) +{ + if (quiet) + return; + + if (virValidateWantEscape()) + fprintf(stdout, "\033[32m%s\033[0m\n", _("PASS")); + else + fprintf(stdout, "%s\n", _("PASS")); +} + + +static const char * failMessages[] =3D { + N_("FAIL"), + N_("WARN"), + N_("NOTE"), +}; + +G_STATIC_ASSERT(G_N_ELEMENTS(failMessages) =3D=3D VIR_VALIDATE_LAST); + +static const char *failEscapeCodes[] =3D { + "\033[31m", + "\033[33m", + "\033[34m", +}; + +G_STATIC_ASSERT(G_N_ELEMENTS(failEscapeCodes) =3D=3D VIR_VALIDATE_LAST); + +void virValidateFail(virValidateLevel level, + const char *format, + ...) +{ + va_list args; + g_autofree char *msg =3D NULL; + + if (quiet) + return; + + va_start(args, format); + msg =3D g_strdup_vprintf(format, args); + va_end(args); + + if (virValidateWantEscape()) + fprintf(stdout, "%s%s\033[0m (%s)\n", + failEscapeCodes[level], _(failMessages[level]), msg); + else + fprintf(stdout, "%s (%s)\n", + _(failMessages[level]), msg); +} diff --git a/tools/virt-validate-common.h b/tools/virt-validate-common.h new file mode 100644 index 0000000000..7f7c373a66 --- /dev/null +++ b/tools/virt-validate-common.h @@ -0,0 +1,57 @@ +/* + * virt-validate-common.h: Sanity check helper APIs + * + * Copyright (C) 2012-2024 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + */ + +#pragma once + +#include "internal.h" + +typedef enum { + VIR_VALIDATE_FAIL, + VIR_VALIDATE_WARN, + VIR_VALIDATE_NOTE, + + VIR_VALIDATE_LAST, +} virValidateLevel; + +/** + * VIR_VALIDATE_FAILURE + * @level: the virValidateLevel to be checked + * + * This macro is to be used in to return a failures based on the + * virValidateLevel use in the function. + * + * If the virValidateLevel is VIR_VALIDATE_FAIL, -1 is returned. + * 0 is returned otherwise (as the virValidateLevel is then either a + * Warn or a Note). + */ + +#define VIR_VALIDATE_FAILURE(level) (level =3D=3D VIR_VALIDATE_FAIL) ? -1 = : 0 + +void virValidateSetQuiet(bool quietFlag); + +void virValidateCheck(const char *prefix, + const char *format, + ...) G_GNUC_PRINTF(2, 3); + +void virValidatePass(void); +void virValidateFail(virValidateLevel level, + const char *format, + ...) G_GNUC_PRINTF(2, 3); --=20 2.43.0