[libvirt] [PATCH v2] Add host UUID (to libvirt capabilities)
Scott Feldman
scofeldm at cisco.com
Mon May 24 16:48:32 UTC 2010
Thanks Stefan! Using/testing this now. I'm hitting this on make check:
TEST: capabilityschematest
!!!!!!!!!!!! 12 FAILED
FAIL: capabilityschematest
-scott
On 5/24/10 6:56 AM, "Stefan Berger" <stefanb at linux.vnet.ibm.com> wrote:
> This patch adds the host UUID (to the capabilities of libvirt). The user
> may provide it in libvirtd.conf overriding whatever sysfs may
> return. If none or no valid UUID is provided in libvirtd.conf, reading the
> UUID from sysfs is attempted. If that function doesn't provide a valid
> (not all digits may be equal), generate a temporary one.
> virSetHostUUIDStr() should be called first with the UUID read from
> libvirtd.conf, but may only be called once. Subsequently the functions
> virGetHostUUID[Str]() can be called to get the UUID of the host.
>
> Changes from V1 to V2:
> - addressing comments from Daniel Berrange:
> - rewrite/ code to get the UUID from 2 possible sysfs files
> - got rid of dmidecide dependency
> - call the newly added virGetHostUUID() function in udevGetDMIData() to get
> the UUID of the host ( even if it's just a temporary UUID )
>
> Besides that, this patch
> - adds uuid to the capabilties XML schema
> - displays the UUID in in 'virsh capabilities'
> - adds 3 public functions to uuid.h for setting and getting the UUID of
> the host
>
> This patch contains recycled code from Scott Feldman
> (getDMISystemUUID()).
>
> Signed-off-by: Stefan Berger <stefanb at us.ibm.com>
>
> ---
> daemon/libvirtd.c | 5 +
> src/conf/capabilities.c | 4 +
> src/util/uuid.c | 126
> ++++++++++++++++++++++++++++++++++++++++++++++++
> src/util/uuid.h | 4 +
> 4 files changed, 139 insertions(+)
>
> Index: libvirt-acl/daemon/libvirtd.c
> ===================================================================
> --- libvirt-acl.orig/daemon/libvirtd.c
> +++ libvirt-acl/daemon/libvirtd.c
> @@ -57,6 +57,7 @@
> #include "dispatch.h"
>
> #include "util.h"
> +#include "uuid.h"
> #include "remote_driver.h"
> #include "conf.h"
> #include "event.h"
> @@ -2718,6 +2719,7 @@ remoteReadConfigFile (struct qemud_serve
> char *unix_sock_rw_perms = NULL;
> char *unix_sock_group = NULL;
> char *buf = NULL;
> + char *host_uuid = NULL;
>
> #if HAVE_POLKIT
> /* Change the default back to no auth for non-root */
> @@ -2840,6 +2842,10 @@ remoteReadConfigFile (struct qemud_serve
> GET_CONF_INT (conf, filename, max_requests);
> GET_CONF_INT (conf, filename, max_client_requests);
>
> + GET_CONF_STR (conf, filename, host_uuid);
> + virSetHostUUIDStr(host_uuid);
> + VIR_FREE(host_uuid);
> +
> virConfFree (conf);
> return 0;
>
> Index: libvirt-acl/src/util/uuid.h
> ===================================================================
> --- libvirt-acl.orig/src/util/uuid.h
> +++ libvirt-acl/src/util/uuid.h
> @@ -22,6 +22,10 @@
> #ifndef __VIR_UUID_H__
> # define __VIR_UUID_H__
>
> +int virSetHostUUIDStr(const char *host_uuid);
> +int virGetHostUUID(unsigned char *host_uuid);
> +int virGetHostUUIDStr(char *host_uuid);
> +
> int virUUIDGenerate(unsigned char *uuid);
>
> int virUUIDParse(const char *uuidstr,
> Index: libvirt-acl/src/util/uuid.c
> ===================================================================
> --- libvirt-acl.orig/src/util/uuid.c
> +++ libvirt-acl/src/util/uuid.c
> @@ -38,11 +38,14 @@
> #include "util.h"
> #include "virterror_internal.h"
> #include "logging.h"
> +#include "memory.h"
>
> #ifndef ENODATA
> # define ENODATA EIO
> #endif
>
> +static unsigned char host_uuid[VIR_UUID_BUFLEN];
> +
> static int
> virUUIDGenerateRandomBytes(unsigned char *buf,
> int buflen)
> @@ -208,3 +211,134 @@ void virUUIDFormat(const unsigned char *
> uuid[12], uuid[13], uuid[14], uuid[15]);
> uuidstr[VIR_UUID_STRING_BUFLEN-1] = '\0';
> }
> +
> +
> +
> +/**
> + * isValidHostUUID
> + *
> + * @uuid: The UUID to test
> + *
> + * Do some basic tests to check whether the given UUID is
> + * valid as a host UUID.
> + * Basic tests:
> + * - Not all of the digits may be equal
> + */
> +static int
> +isValidHostUUID(unsigned char *uuid)
> +{
> + unsigned int i, ctr = 1;
> + unsigned char c;
> +
> + if (!uuid)
> + return 0;
> +
> + c = uuid[0];
> +
> + for (i = 1; i < VIR_UUID_BUFLEN; i++)
> + if (uuid[i] == c)
> + ctr++;
> +
> + return (ctr != VIR_UUID_BUFLEN);
> +}
> +
> +static int
> +getDMISystemUUID(char *uuid, int len)
> +{
> + unsigned int i = 0;
> + const char *paths[] = {
> + "/sys/devices/virtual/dmi/id/product_uuid",
> + "/sys/class/dmi/id/product_uuid",
> + NULL
> + };
> +
> + while (paths[i]) {
> + int fd = open(paths[i], O_RDONLY);
> + if (fd > 0) {
> + if (saferead(fd, uuid, len) == len) {
> + close(fd);
> + return 0;
> + }
> + close(fd);
> + }
> + i++;
> + }
> +
> + return -1;
> +}
> +
> +
> +/**
> + * setHostUUID
> + *
> + * @host_uuid: UUID that the host is supposed to have
> + *
> + * Set the UUID of the host if it hasn't been set, yet
> + * Returns 0 in case of success, an error code in case of error.
> + */
> +int
> +virSetHostUUIDStr(const char *uuid)
> +{
> + char dmiuuid[VIR_UUID_STRING_BUFLEN];
> +
> + if (isValidHostUUID(host_uuid))
> + return EEXIST;
> +
> + if (!uuid) {
> + if (!getDMISystemUUID(dmiuuid, sizeof(dmiuuid))) {
> + if (!virUUIDParse(dmiuuid, host_uuid)) {
> + return 0;
> + }
> + }
> + } else {
> + if (!virUUIDParse(uuid, host_uuid))
> + return 0;
> + }
> +
> + if (!isValidHostUUID(host_uuid))
> + return virUUIDGenerate(host_uuid);
> + return 0;
> +}
> +
> +/**
> + * getHostUUID:
> + *
> + * @host_uuid: memory to store the host_uuid into
> + *
> + * Get the UUID of the host. Returns 0 in case of success,
> + * an error code otherwise.
> + * Returns 0 in case of success, an error code in case of error.
> + */
> +int virGetHostUUID(unsigned char *uuid)
> +{
> + int ret = 0;
> +
> + if (!isValidHostUUID(host_uuid))
> + ret = virSetHostUUIDStr(NULL);
> +
> + memcpy(uuid, host_uuid, sizeof(host_uuid));
> +
> + return ret;
> +}
> +
> +
> +/**
> + * getHostUUID:
> + *
> + * @host_uuid: memory to store the host_uuid into
> + *
> + * Get the UUID of the host. Returns 0 in case of success,
> + * an error code otherwise.
> + * Returns 0 in case of success, an error code in case of error.
> + */
> +int virGetHostUUIDStr(char *uuid)
> +{
> + int ret = 0;
> +
> + if (!isValidHostUUID(host_uuid))
> + ret = virSetHostUUIDStr(NULL);
> +
> + virUUIDFormat(host_uuid, uuid);
> +
> + return ret;
> +}
> Index: libvirt-acl/src/conf/capabilities.c
> ===================================================================
> --- libvirt-acl.orig/src/conf/capabilities.c
> +++ libvirt-acl/src/conf/capabilities.c
> @@ -27,6 +27,7 @@
> #include "buf.h"
> #include "memory.h"
> #include "util.h"
> +#include "uuid.h"
> #include "cpu_conf.h"
>
> /**
> @@ -662,9 +663,12 @@ virCapabilitiesFormatXML(virCapsPtr caps
> {
> virBuffer xml = VIR_BUFFER_INITIALIZER;
> int i, j, k;
> + char host_uuid[VIR_UUID_STRING_BUFLEN];
> + virGetHostUUIDStr(host_uuid);
>
> virBufferAddLit(&xml, "<capabilities>\n\n");
> virBufferAddLit(&xml, " <host>\n");
> + virBufferVSprintf(&xml," <uuid>%s</uuid>\n", host_uuid);
> virBufferAddLit(&xml, " <cpu>\n");
> virBufferVSprintf(&xml, " <arch>%s</arch>\n",
> caps->host.arch);
> Index: libvirt-acl/docs/schemas/capability.rng
> ===================================================================
> --- libvirt-acl.orig/docs/schemas/capability.rng
> +++ libvirt-acl/docs/schemas/capability.rng
> @@ -18,6 +18,9 @@
>
> <define name='hostcaps'>
> <element name='host'>
> + <element name='uuid'>
> + <ref name='UUID'/>
> + </element>
> <element name='cpu'>
> <element name='arch'>
> <ref name='archnames'/>
> @@ -349,4 +352,15 @@
> <param name='pattern'>[a-zA-Z0-9\-_]+</param>
> </data>
> </define>
> +
> + <define name="UUID">
> + <choice>
> + <data type="string">
> + <param name="pattern">[a-fA-F0-9]{32}</param>
> + </data>
> + <data type="string">
> + <param
> name="pattern">[a-fA-F0-9]{8}\-([a-fA-F0-9]{4}\-){3}[a-fA-F0-9]{12}</param>
> + </data>
> + </choice>
> + </define>
> </grammar>
> Index: libvirt-acl/src/libvirt_private.syms
> ===================================================================
> --- libvirt-acl.orig/src/libvirt_private.syms
> +++ libvirt-acl/src/libvirt_private.syms
> @@ -708,6 +708,9 @@ usbDeviceFileIterate;
> virUUIDFormat;
> virUUIDGenerate;
> virUUIDParse;
> +virSetHostUUIDStr;
> +virGetHostUUID;
> +virGetHostUUIDStr;
>
>
> # virterror_internal.h
> Index: libvirt-acl/daemon/libvirtd.conf
> ===================================================================
> --- libvirt-acl.orig/daemon/libvirtd.conf
> +++ libvirt-acl/daemon/libvirtd.conf
> @@ -312,3 +312,12 @@
> # e.g.:
> # log_outputs="3:syslog:libvirtd"
> # to log all warnings and errors to syslog under the libvirtd ident
> +
> +# UUID of the host:
> +# Provide the UUID of the host here in case the command
> +# 'dmidecode -s system-uuid' does not provide a valid uuid. In case
> +# 'dmidecode' does not provide a valid UUID and none is provided here, a
> +# temporary UUID will be generated.
> +# Keep the format of the example UUID below.
> +
> +#host_uuid = '8510b1a1-1afa-4da6-8111-785fae202c1d'
> Index: libvirt-acl/src/node_device/node_device_udev.c
> ===================================================================
> --- libvirt-acl.orig/src/node_device/node_device_udev.c
> +++ libvirt-acl/src/node_device/node_device_udev.c
> @@ -1473,12 +1473,8 @@ udevGetDMIData(union _virNodeDevCapData
> goto out;
> }
>
> - if (udevGetStringSysfsAttr(device,
> - "product_uuid",
> - &tmp) == PROPERTY_ERROR) {
> + if (virGetHostUUID(data->system.hardware.uuid))
> goto out;
> - }
> - virUUIDParse(tmp, data->system.hardware.uuid);
>
> if (udevGetStringSysfsAttr(device,
> "bios_vendor",
>
More information about the libvir-list
mailing list