From: Michal Privoznik Date: Tue, 23 Apr 2024 08:41:50 +0000 (+0200) Subject: virfile: Introduce virFileReadValueBitmapAllowEmpty() X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=f3c6c7623c5a03d7090f7064b87fe467f8d0a656;p=libvirt.git virfile: Introduce virFileReadValueBitmapAllowEmpty() Some sysfs files contain either string representation of a bitmap or just a newline character. An example of such file is: /sys/devices/system/cpu/isolated. Our current implementation of virFileReadValueBitmap() fails in the latter case, unfortunately. Introduce a slightly modified version that accepts empty files. Signed-off-by: Michal Privoznik Reviewed-by: Pavel Hrdina --- diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index cc364a421f..661b560ffe 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2361,6 +2361,7 @@ virFileReadHeaderFD; virFileReadHeaderQuiet; virFileReadLimFD; virFileReadValueBitmap; +virFileReadValueBitmapAllowEmpty; virFileReadValueInt; virFileReadValueScaledInt; virFileReadValueString; diff --git a/src/util/virfile.c b/src/util/virfile.c index deaf4555fd..c769f7d650 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -4365,6 +4365,34 @@ virFileReadValueScaledInt(unsigned long long *value, const char *format, ...) * used for small, interface-like files, so it should not be huge (subjective) */ #define VIR_FILE_READ_VALUE_STRING_MAX 4096 +static int +virFileReadValueBitmapImpl(virBitmap **value, + const char *path, + bool allowEmpty) +{ + g_autofree char *str = NULL; + + if (!virFileExists(path)) + return -2; + + if (virFileReadAll(path, VIR_FILE_READ_VALUE_STRING_MAX, &str) < 0) + return -1; + + virStringTrimOptionalNewline(str); + + if (allowEmpty) { + *value = virBitmapParseUnlimitedAllowEmpty(str); + } else { + *value = virBitmapParseUnlimited(str); + } + + if (!*value) + return -1; + + return 0; +} + + /** * virFileReadValueBitmap: * @value: pointer to virBitmap * to be allocated and filled in with the value @@ -4372,13 +4400,13 @@ virFileReadValueScaledInt(unsigned long long *value, const char *format, ...) * * Read int from @format and put it into @value. * - * Return -2 for non-existing file, -1 on other errors and 0 if everything went - * fine. + * Returns: -2 for non-existing file, + * -1 on other errors (with error reported), + * 0 otherwise. */ int virFileReadValueBitmap(virBitmap **value, const char *format, ...) { - g_autofree char *str = NULL; g_autofree char *path = NULL; va_list ap; @@ -4386,21 +4414,36 @@ virFileReadValueBitmap(virBitmap **value, const char *format, ...) path = g_strdup_vprintf(format, ap); va_end(ap); - if (!virFileExists(path)) - return -2; + return virFileReadValueBitmapImpl(value, path, false); +} - if (virFileReadAll(path, VIR_FILE_READ_VALUE_STRING_MAX, &str) < 0) - return -1; - virStringTrimOptionalNewline(str); +/** + * virFileReadValueBitmapAllowEmpty: + * @value: pointer to virBitmap * to be allocated and filled in with the value + * @format, ...: file to read from + * + * Just like virFileReadValueBitmap(), except if the file is empty or contains + * nothing but spaces an empty bitmap is returned instead of an error. + * + * Returns: -2 for non-existing file, + * -1 on other errors (with error reported), + * 0 otherwise. + */ +int +virFileReadValueBitmapAllowEmpty(virBitmap **value, const char *format, ...) +{ + g_autofree char *path = NULL; + va_list ap; - *value = virBitmapParseUnlimited(str); - if (!*value) - return -1; + va_start(ap, format); + path = g_strdup_vprintf(format, ap); + va_end(ap); - return 0; + return virFileReadValueBitmapImpl(value, path, true); } + /** * virFileReadValueString: * @value: pointer to char * to be allocated and filled in with the value diff --git a/src/util/virfile.h b/src/util/virfile.h index 56fe309bce..7df3fcb840 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -354,6 +354,8 @@ int virFileReadValueUllongQuiet(unsigned long long *value, const char *format, . G_GNUC_PRINTF(2, 3); int virFileReadValueBitmap(virBitmap **value, const char *format, ...) G_GNUC_PRINTF(2, 3); +int virFileReadValueBitmapAllowEmpty(virBitmap **value, const char *format, ...) + G_GNUC_PRINTF(2, 3); int virFileReadValueScaledInt(unsigned long long *value, const char *format, ...) G_GNUC_PRINTF(2, 3); int virFileReadValueString(char **value, const char *format, ...)