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@xxxxxxxxxxxxxxxxxx> 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@xxxxxxxxxx> > > --- > 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", > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list