[libvirt PATCH] conf: skip resource cache init if sysfs files are missing

Ján Tomko jtomko at redhat.com
Tue Oct 11 07:02:07 UTC 2022


On a Monday in 2022, Daniel P. Berrangé wrote:
>On aarch64 the 'id' file is not present for CPU cache information in
>sysfs. This causes the local stateful hypervisor drivers to fail to
>initialize capabilities:
>
>virStateInitialize:657 : Initialisation of cloud-hypervisor state driver failed: no error
>
>The 'no error' is because the 'virFileReadValueNNN' methods return
>ret==-2, with no error raised, when the requeted file does not exist.

*requested

>None of the callers were checking for this scenario when populating
>capabilities. The most graceful way to handle this is to skip the
>cache bank in question.  This fixes failure to launch libvirt drivers
>on certain aarch64 hardware.
>
>Fixes: https://gitlab.com/libvirt/libvirt/-/issues/389
>Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
>---
> src/conf/capabilities.c | 57 ++++++++++++++++++++++++++++++-----------
> 1 file changed, 42 insertions(+), 15 deletions(-)
>
>diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
>index 1a7ebf4a13..ae63515fd3 100644
>--- a/src/conf/capabilities.c
>+++ b/src/conf/capabilities.c
>@@ -2184,6 +2184,7 @@ virCapabilitiesInitCaches(virCaps *caps)
>             g_autofree char *type = NULL;
>             int kernel_type;
>             unsigned int level;
>+            int err;
>
>             if (!STRPREFIX(ent->d_name, "index"))
>                 continue;
>@@ -2199,29 +2200,54 @@ virCapabilitiesInitCaches(virCaps *caps)
>             bank = g_new0(virCapsHostCacheBank, 1);
>             bank->level = level;
>
>-            if (virFileReadValueUint(&bank->id,
>-                                     "%s/cpu/cpu%zd/cache/%s/id",
>-                                     SYSFS_SYSTEM_PATH, pos, ent->d_name) < 0)
>+            err = virFileReadValueUint(&bank->id,
>+                                       "%s/cpu/cpu%zd/cache/%s/id",
>+                                       SYSFS_SYSTEM_PATH, pos, ent->d_name);
>+            if (err == -2) {
>+                VIR_DEBUG("CPU %zd cache %s 'id' missing", pos, ent->d_name);
>+                goto skip_cache;
>+            }
>+            if (err < 0)
>                 goto cleanup;
>
>-            if (virFileReadValueUint(&bank->level,
>-                                     "%s/cpu/cpu%zd/cache/%s/level",
>-                                     SYSFS_SYSTEM_PATH, pos, ent->d_name) < 0)
>+            err = virFileReadValueUint(&bank->level,
>+                                       "%s/cpu/cpu%zd/cache/%s/level",
>+                                       SYSFS_SYSTEM_PATH, pos, ent->d_name);
>+            if (err == -2) {
>+                VIR_DEBUG("CPU %zd cache %s 'level' missing", pos, ent->d_name);
>+                goto skip_cache;
>+            }
>+            if (err < 0)
>                 goto cleanup;
>
>-            if (virFileReadValueString(&type,
>-                                       "%s/cpu/cpu%zd/cache/%s/type",
>-                                       SYSFS_SYSTEM_PATH, pos, ent->d_name) < 0)
>+            err = virFileReadValueString(&type,
>+                                         "%s/cpu/cpu%zd/cache/%s/type",
>+                                         SYSFS_SYSTEM_PATH, pos, ent->d_name);
>+            if (err == -2) {
>+                VIR_DEBUG("CPU %zd cache %s 'type' missing", pos, ent->d_name);
>+                goto skip_cache;
>+            }
>+            if (err < 0)
>                 goto cleanup;
>
>-            if (virFileReadValueScaledInt(&bank->size,
>-                                          "%s/cpu/cpu%zd/cache/%s/size",
>-                                          SYSFS_SYSTEM_PATH, pos, ent->d_name) < 0)
>+            err = virFileReadValueScaledInt(&bank->size,
>+                                            "%s/cpu/cpu%zd/cache/%s/size",
>+                                            SYSFS_SYSTEM_PATH, pos, ent->d_name);
>+            if (err == -2) {
>+                VIR_DEBUG("CPU %zd cache %s 'size' missing", pos, ent->d_name);
>+                goto skip_cache;
>+            }
>+            if (err < 0)
>                 goto cleanup;
>
>-            if (virFileReadValueBitmap(&bank->cpus,
>-                                       "%s/cpu/cpu%zd/cache/%s/shared_cpu_list",
>-                                       SYSFS_SYSTEM_PATH, pos, ent->d_name) < 0)
>+            err = virFileReadValueBitmap(&bank->cpus,
>+                                         "%s/cpu/cpu%zd/cache/%s/shared_cpu_list",
>+                                         SYSFS_SYSTEM_PATH, pos, ent->d_name);
>+            if (err == -2) {
>+                VIR_DEBUG("CPU %zd cache %s 'shared_cpu_list' missing", pos, ent->d_name);
>+                goto skip_cache;
>+            }
>+            if (err < 0)
>                 goto cleanup;
>
>             kernel_type = virCacheKernelTypeFromString(type);
>@@ -2249,6 +2275,7 @@ virCapabilitiesInitCaches(virCaps *caps)
>                 VIR_APPEND_ELEMENT(caps->host.cache.banks, caps->host.cache.nbanks, bank);
>             }
>
>+        skip_cache:
>             g_clear_pointer(&bank, virCapsHostCacheBankFree);

If you define a cleanup function for virCapsHostCacheBank, there is no
need to explicitly clear the pointer and 'goto skip_cache' becomes just
'continue'.

Jano


More information about the libvir-list mailing list