#include "dispatch.h"
#include "util.h"
+#include "uuid.h"
#include "remote_driver.h"
#include "conf.h"
#include "event.h"
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 */
GET_CONF_INT (conf, filename, max_requests);
GET_CONF_INT (conf, filename, max_client_requests);
+ GET_CONF_STR (conf, filename, host_uuid);
+ if (virSetHostUUIDStr(host_uuid))
+ goto free_and_fail;
+
+ VIR_FREE(host_uuid);
+
virConfFree (conf);
return 0;
free_and_fail:
virConfFree (conf);
+ VIR_FREE(host_uuid);
VIR_FREE(mdns_name);
VIR_FREE(unix_sock_ro_perms);
VIR_FREE(unix_sock_rw_perms);
# 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. UUID must not have all digits
+# be the same.
+
+# NB This default all-zeros UUID will not work. Replace
+# it with the output of the 'uuidgen' command and then
+# uncomment this entry
+#host_uuid = "00000000-0000-0000-0000-000000000000"
<define name='hostcaps'>
<element name='host'>
+ <optional>
+ <element name='uuid'>
+ <ref name='UUID'/>
+ </element>
+ </optional>
<element name='cpu'>
<element name='arch'>
<ref name='archnames'/>
<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>
src/internal.h
src/libvirt.c
src/lxc/lxc_container.c
+src/lxc/lxc_conf.c
src/lxc/lxc_controller.c
src/lxc/lxc_driver.c
src/network/bridge_driver.c
#include "buf.h"
#include "memory.h"
#include "util.h"
+#include "uuid.h"
#include "cpu_conf.h"
/**
{
virBuffer xml = VIR_BUFFER_INITIALIZER;
int i, j, k;
+ char host_uuid[VIR_UUID_STRING_BUFLEN];
virBufferAddLit(&xml, "<capabilities>\n\n");
virBufferAddLit(&xml, " <host>\n");
+ if (virUUIDIsValid(caps->host.host_uuid)) {
+ virUUIDFormat(caps->host.host_uuid, host_uuid);
+ virBufferVSprintf(&xml," <uuid>%s</uuid>\n", host_uuid);
+ }
virBufferAddLit(&xml, " <cpu>\n");
virBufferVSprintf(&xml, " <arch>%s</arch>\n",
caps->host.arch);
virCapsHostNUMACellPtr *numaCell;
virCapsHostSecModel secModel;
virCPUDefPtr cpu;
+ unsigned char host_uuid[VIR_UUID_BUFLEN];
};
typedef struct _virCaps virCaps;
virUUIDFormat;
virUUIDGenerate;
virUUIDParse;
+virSetHostUUIDStr;
+virGetHostUUID;
# virterror_internal.h
#include "conf.h"
#include "memory.h"
#include "logging.h"
+#include "uuid.h"
#define VIR_FROM_THIS VIR_FROM_LXC
if ((caps = virCapabilitiesNew(utsname.machine,
0, 0)) == NULL)
- goto no_memory;
+ goto error;
/* Some machines have problematic NUMA toplogy causing
* unexpected failures. We don't want to break the QEMU
VIR_WARN0("Failed to query host NUMA topology, disabling NUMA capabilities");
}
+ if (virGetHostUUID(caps->host.host_uuid)) {
+ lxcError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot get the host uuid"));
+ goto error;
+ }
+
/* XXX shouldn't 'borrow' KVM's prefix */
virCapabilitiesSetMacPrefix(caps, (unsigned char []){ 0x52, 0x54, 0x00 });
NULL,
0,
NULL)) == NULL)
- goto no_memory;
+ goto error;
if (virCapabilitiesAddGuestDomain(guest,
"lxc",
NULL,
0,
NULL) == NULL)
- goto no_memory;
+ goto error;
/* LXC Requires an emulator in the XML */
virCapabilitiesSetEmulatorRequired(caps);
return caps;
-no_memory:
+error:
virCapabilitiesFree(caps);
return NULL;
}
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",
caps->privateDataXMLFormat = qemuDomainObjPrivateXMLFormat;
caps->privateDataXMLParse = qemuDomainObjPrivateXMLParse;
+ if (virGetHostUUID(caps->host.host_uuid)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot get the host uuid"));
+ goto err_exit;
+ }
/* Security driver data */
if (driver->securityPrimaryDriver) {
no_memory:
virReportOOMError();
+err_exit:
virCapabilitiesFree(caps);
return NULL;
}
if ((caps = virCapabilitiesNew(utsname.machine,
0, 0)) == NULL)
- goto no_memory;
+ goto error;
/* Some machines have problematic NUMA toplogy causing
* unexpected failures. We don't want to break the QEMU
VIR_WARN0("Failed to query host NUMA topology, disabling NUMA capabilities");
}
+ if (virGetHostUUID(caps->host.host_uuid)) {
+ umlReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot get the host uuid"));
+ goto error;
+ }
+
if ((guest = virCapabilitiesAddGuest(caps,
"uml",
utsname.machine,
NULL,
0,
NULL)) == NULL)
- goto no_memory;
+ goto error;
if (virCapabilitiesAddGuestDomain(guest,
"uml",
NULL,
0,
NULL) == NULL)
- goto no_memory;
+ goto error;
return caps;
- no_memory:
+ error:
virCapabilitiesFree(caps);
return NULL;
}
#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)
uuid[12], uuid[13], uuid[14], uuid[15]);
uuidstr[VIR_UUID_STRING_BUFLEN-1] = '\0';
}
+
+
+
+/**
+ * virUUIDIsValid
+ *
+ * @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
+ */
+int
+virUUIDIsValid(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)
+{
+ int rc;
+ char dmiuuid[VIR_UUID_STRING_BUFLEN];
+
+ if (virUUIDIsValid(host_uuid))
+ return EEXIST;
+
+ if (!uuid) {
+ if (!getDMISystemUUID(dmiuuid, sizeof(dmiuuid))) {
+ if (!virUUIDParse(dmiuuid, host_uuid))
+ return 0;
+ }
+
+ if (!virUUIDIsValid(host_uuid))
+ return virUUIDGenerate(host_uuid);
+ } else {
+ rc = virUUIDParse(uuid, host_uuid);
+ if (rc)
+ return rc;
+ if (!virUUIDIsValid(host_uuid))
+ return EINVAL;
+ }
+
+ 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 (!virUUIDIsValid(host_uuid))
+ ret = virSetHostUUIDStr(NULL);
+
+ memcpy(uuid, host_uuid, sizeof(host_uuid));
+
+ return ret;
+}
#ifndef __VIR_UUID_H__
# define __VIR_UUID_H__
+int virSetHostUUIDStr(const char *host_uuid);
+int virGetHostUUID(unsigned char *host_uuid);
+
+int virUUIDIsValid(unsigned char *uuid);
+
int virUUIDGenerate(unsigned char *uuid);
int virUUIDParse(const char *uuidstr,
#
# By default, no Username's are checked
sasl_allowed_username_list = ["joe@EXAMPLE.COM", "fred@EXAMPLE.COM" ]
+
+# 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-785fae202c1e"
#
# By default, no Username's are checked
sasl_allowed_username_list = [ "joe@EXAMPLE.COM", "fred@EXAMPLE.COM" ]
+# 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-785fae202c1e"