aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS7
-rw-r--r--arch_init.c19
-rw-r--r--block/Makefile.objs2
-rw-r--r--block/iscsi.c2
-rw-r--r--block/vdi.c73
-rw-r--r--block/vhdx-endian.c3
-rw-r--r--block/vhdx.c9
-rw-r--r--block/vpc.c10
-rwxr-xr-xconfigure70
-rw-r--r--crypto/block-luks.c26
-rw-r--r--hw/ipmi/ipmi_bmc_sim.c2
-rw-r--r--hw/nvram/fw_cfg.c2
-rw-r--r--hw/ppc/spapr.c7
-rw-r--r--hw/ppc/spapr_rtas.c3
-rw-r--r--hw/smbios/smbios.c13
-rw-r--r--hw/xenpv/xen_domainbuild.c6
-rw-r--r--include/qemu/uuid.h59
-rw-r--r--include/sysemu/sysemu.h7
-rw-r--r--qmp.c11
-rw-r--r--stubs/uuid.c2
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/docker/Makefile.include2
-rwxr-xr-xtests/docker/common.rc14
-rwxr-xr-xtests/docker/docker.py14
-rw-r--r--tests/docker/dockerfiles/centos6.docker6
-rw-r--r--tests/docker/dockerfiles/fedora.docker16
-rw-r--r--tests/docker/dockerfiles/ubuntu.docker4
-rwxr-xr-xtests/docker/run26
-rwxr-xr-xtests/docker/test-quick2
-rw-r--r--tests/test-crypto-block.c2
-rw-r--r--tests/test-uuid.c177
-rw-r--r--ui/spice-core.c2
-rw-r--r--util/Makefile.objs1
-rw-r--r--util/uuid.c114
-rw-r--r--vl.c7
36 files changed, 486 insertions, 237 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 09d13bf1c0..bc4466399f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1342,6 +1342,13 @@ F: include/qemu/throttle.h
F: util/throttle.c
L: qemu-block@nongnu.org
+UUID
+M: Fam Zheng <famz@redhat.com>
+S: Supported
+F: util/uuid.c
+F: include/qemu/uuid.h
+F: tests/test-uuid.c
+
Usermode Emulation
------------------
Overall
diff --git a/arch_init.c b/arch_init.c
index fa059731ed..5cc58b2c35 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -235,25 +235,6 @@ void audio_init(void)
}
}
-int qemu_uuid_parse(const char *str, uint8_t *uuid)
-{
- int ret;
-
- if (strlen(str) != 36) {
- return -1;
- }
-
- ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
- &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
- &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14],
- &uuid[15]);
-
- if (ret != 16) {
- return -1;
- }
- return 0;
-}
-
void do_acpitable_option(const QemuOpts *opts)
{
#ifdef TARGET_I386
diff --git a/block/Makefile.objs b/block/Makefile.objs
index cb158e9275..7d4031dae5 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -2,7 +2,7 @@ block-obj-y += raw_bsd.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o dmg.o
block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o
block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-y += qed-check.o
-block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o
+block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
block-obj-y += quorum.o
block-obj-y += parallels.o blkdebug.o blkverify.o blkreplay.o
block-obj-y += block-backend.o snapshot.o qapi.o
diff --git a/block/iscsi.c b/block/iscsi.c
index 8a940317d6..dff548a139 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -36,7 +36,7 @@
#include "block/block_int.h"
#include "block/scsi.h"
#include "qemu/iov.h"
-#include "sysemu/sysemu.h"
+#include "qemu/uuid.h"
#include "qmp-commands.h"
#include "qapi/qmp/qstring.h"
#include "crypto/secret.h"
diff --git a/block/vdi.c b/block/vdi.c
index 8a1cf97928..96b78d5a43 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -58,14 +58,7 @@
#include "migration/migration.h"
#include "qemu/coroutine.h"
#include "qemu/cutils.h"
-
-#if defined(CONFIG_UUID)
-#include <uuid/uuid.h>
-#else
-/* TODO: move uuid emulation to some central place in QEMU. */
-#include "sysemu/sysemu.h" /* UUID_FMT */
-typedef unsigned char uuid_t[16];
-#endif
+#include "qemu/uuid.h"
/* Code configuration options. */
@@ -140,28 +133,6 @@ typedef unsigned char uuid_t[16];
#define VDI_DISK_SIZE_MAX ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
(uint64_t)DEFAULT_CLUSTER_SIZE)
-#if !defined(CONFIG_UUID)
-static inline void uuid_generate(uuid_t out)
-{
- memset(out, 0, sizeof(uuid_t));
-}
-
-static inline int uuid_is_null(const uuid_t uu)
-{
- uuid_t null_uuid = { 0 };
- return memcmp(uu, null_uuid, sizeof(uuid_t)) == 0;
-}
-
-# if defined(CONFIG_VDI_DEBUG)
-static inline void uuid_unparse(const uuid_t uu, char *out)
-{
- snprintf(out, 37, UUID_FMT,
- uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7],
- uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
-}
-# endif
-#endif
-
typedef struct {
char text[0x40];
uint32_t signature;
@@ -182,10 +153,10 @@ typedef struct {
uint32_t block_extra; /* unused here */
uint32_t blocks_in_image;
uint32_t blocks_allocated;
- uuid_t uuid_image;
- uuid_t uuid_last_snap;
- uuid_t uuid_link;
- uuid_t uuid_parent;
+ QemuUUID uuid_image;
+ QemuUUID uuid_last_snap;
+ QemuUUID uuid_link;
+ QemuUUID uuid_parent;
uint64_t unused2[7];
} QEMU_PACKED VdiHeader;
@@ -206,16 +177,6 @@ typedef struct {
Error *migration_blocker;
} BDRVVdiState;
-/* Change UUID from little endian (IPRT = VirtualBox format) to big endian
- * format (network byte order, standard, see RFC 4122) and vice versa.
- */
-static void uuid_convert(uuid_t uuid)
-{
- bswap32s((uint32_t *)&uuid[0]);
- bswap16s((uint16_t *)&uuid[4]);
- bswap16s((uint16_t *)&uuid[6]);
-}
-
static void vdi_header_to_cpu(VdiHeader *header)
{
le32_to_cpus(&header->signature);
@@ -234,10 +195,10 @@ static void vdi_header_to_cpu(VdiHeader *header)
le32_to_cpus(&header->block_extra);
le32_to_cpus(&header->blocks_in_image);
le32_to_cpus(&header->blocks_allocated);
- uuid_convert(header->uuid_image);
- uuid_convert(header->uuid_last_snap);
- uuid_convert(header->uuid_link);
- uuid_convert(header->uuid_parent);
+ qemu_uuid_bswap(&header->uuid_image);
+ qemu_uuid_bswap(&header->uuid_last_snap);
+ qemu_uuid_bswap(&header->uuid_link);
+ qemu_uuid_bswap(&header->uuid_parent);
}
static void vdi_header_to_le(VdiHeader *header)
@@ -258,10 +219,10 @@ static void vdi_header_to_le(VdiHeader *header)
cpu_to_le32s(&header->block_extra);
cpu_to_le32s(&header->blocks_in_image);
cpu_to_le32s(&header->blocks_allocated);
- uuid_convert(header->uuid_image);
- uuid_convert(header->uuid_last_snap);
- uuid_convert(header->uuid_link);
- uuid_convert(header->uuid_parent);
+ qemu_uuid_bswap(&header->uuid_image);
+ qemu_uuid_bswap(&header->uuid_last_snap);
+ qemu_uuid_bswap(&header->uuid_link);
+ qemu_uuid_bswap(&header->uuid_parent);
}
#if defined(CONFIG_VDI_DEBUG)
@@ -469,11 +430,11 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
(uint64_t)header.blocks_in_image * header.block_size);
ret = -ENOTSUP;
goto fail;
- } else if (!uuid_is_null(header.uuid_link)) {
+ } else if (!qemu_uuid_is_null(&header.uuid_link)) {
error_setg(errp, "unsupported VDI image (non-NULL link UUID)");
ret = -ENOTSUP;
goto fail;
- } else if (!uuid_is_null(header.uuid_parent)) {
+ } else if (!qemu_uuid_is_null(&header.uuid_parent)) {
error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
ret = -ENOTSUP;
goto fail;
@@ -821,8 +782,8 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
if (image_type == VDI_TYPE_STATIC) {
header.blocks_allocated = blocks;
}
- uuid_generate(header.uuid_image);
- uuid_generate(header.uuid_last_snap);
+ qemu_uuid_generate(&header.uuid_image);
+ qemu_uuid_generate(&header.uuid_last_snap);
/* There is no need to set header.uuid_link or header.uuid_parent here. */
#if defined(CONFIG_VDI_DEBUG)
vdi_header_print(&header);
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
index c306b90d54..429d7556bd 100644
--- a/block/vhdx-endian.c
+++ b/block/vhdx-endian.c
@@ -21,9 +21,6 @@
#include "qemu/bswap.h"
#include "block/vhdx.h"
-#include <uuid/uuid.h>
-
-
/*
* All the VHDX formats on disk are little endian - the following
* are helper import/export functions to correctly convert
diff --git a/block/vhdx.c b/block/vhdx.c
index 75ef2b1c2d..0ba2f0a2f9 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -25,8 +25,7 @@
#include "qemu/bswap.h"
#include "block/vhdx.h"
#include "migration/migration.h"
-
-#include <uuid/uuid.h>
+#include "qemu/uuid.h"
/* Options for VHDX creation */
@@ -213,11 +212,11 @@ bool vhdx_checksum_is_valid(uint8_t *buf, size_t size, int crc_offset)
*/
void vhdx_guid_generate(MSGUID *guid)
{
- uuid_t uuid;
+ QemuUUID uuid;
assert(guid != NULL);
- uuid_generate(uuid);
- memcpy(guid, uuid, sizeof(MSGUID));
+ qemu_uuid_generate(&uuid);
+ memcpy(guid, &uuid, sizeof(MSGUID));
}
/* Check for region overlaps inside the VHDX image */
diff --git a/block/vpc.c b/block/vpc.c
index 43707ed22c..8d5886f003 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -30,9 +30,7 @@
#include "qemu/module.h"
#include "migration/migration.h"
#include "qemu/bswap.h"
-#if defined(CONFIG_UUID)
-#include <uuid/uuid.h>
-#endif
+#include "qemu/uuid.h"
/**************************************************************/
@@ -89,7 +87,7 @@ typedef struct vhd_footer {
uint32_t checksum;
/* UUID used to identify a parent hard disk (backing file) */
- uint8_t uuid[16];
+ QemuUUID uuid;
uint8_t in_saved_state;
} QEMU_PACKED VHDFooter;
@@ -980,9 +978,7 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
footer->type = cpu_to_be32(disk_type);
-#if defined(CONFIG_UUID)
- uuid_generate(footer->uuid);
-#endif
+ qemu_uuid_generate(&footer->uuid);
footer->checksum = cpu_to_be32(vpc_checksum(buf, HEADER_SIZE));
diff --git a/configure b/configure
index 2efc3382e1..8fa62ade57 100755
--- a/configure
+++ b/configure
@@ -212,7 +212,6 @@ sdlabi=""
virtfs=""
vnc="yes"
sparse="no"
-uuid=""
vde=""
vnc_sasl=""
vnc_jpeg=""
@@ -317,7 +316,6 @@ vte=""
virglrenderer=""
tpm="yes"
libssh2=""
-vhdx=""
numa=""
tcmalloc="no"
jemalloc="no"
@@ -887,10 +885,6 @@ for opt do
;;
--disable-slirp) slirp="no"
;;
- --disable-uuid) uuid="no"
- ;;
- --enable-uuid) uuid="yes"
- ;;
--disable-vde) vde="no"
;;
--enable-vde) vde="yes"
@@ -1103,6 +1097,12 @@ for opt do
--disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
echo "$0: $opt is obsolete, virtio-blk data-plane is always on" >&2
;;
+ --enable-vhdx|--disable-vhdx)
+ echo "$0: $opt is obsolete, VHDX driver is always built" >&2
+ ;;
+ --enable-uuid|--disable-uuid)
+ echo "$0: $opt is obsolete, UUID support is always built" >&2
+ ;;
--disable-gtk) gtk="no"
;;
--enable-gtk) gtk="yes"
@@ -1143,10 +1143,6 @@ for opt do
;;
--enable-libssh2) libssh2="yes"
;;
- --enable-vhdx) vhdx="yes"
- ;;
- --disable-vhdx) vhdx="no"
- ;;
--disable-numa) numa="no"
;;
--enable-numa) numa="yes"
@@ -1365,7 +1361,6 @@ disabled with --disable-FEATURE, default is enabled if available:
bluez bluez stack connectivity
kvm KVM acceleration support
rdma RDMA-based migration support
- uuid uuid support
vde support for vde network
netmap support for netmap network
linux-aio Linux AIO support
@@ -1389,7 +1384,6 @@ disabled with --disable-FEATURE, default is enabled if available:
archipelago Archipelago backend
tpm TPM support
libssh2 ssh block device support
- vhdx support for the Microsoft VHDX image format
numa libnuma support
tcmalloc tcmalloc support
jemalloc jemalloc support
@@ -2662,47 +2656,6 @@ if compile_prog "" "" ; then
fi
##########################################
-# uuid_generate() probe, used for vdi block driver
-# Note that on some systems (notably MacOSX) no extra library
-# need be linked to get the uuid functions.
-if test "$uuid" != "no" ; then
- uuid_libs="-luuid"
- cat > $TMPC << EOF
-#include <uuid/uuid.h>
-int main(void)
-{
- uuid_t my_uuid;
- uuid_generate(my_uuid);
- return 0;
-}
-EOF
- if compile_prog "" "" ; then
- uuid="yes"
- elif compile_prog "" "$uuid_libs" ; then
- uuid="yes"
- libs_softmmu="$uuid_libs $libs_softmmu"
- libs_tools="$uuid_libs $libs_tools"
- else
- if test "$uuid" = "yes" ; then
- feature_not_found "uuid" "Install libuuid devel"
- fi
- uuid=no
- fi
-fi
-
-if test "$vhdx" = "yes" ; then
- if test "$uuid" = "no" ; then
- error_exit "uuid required for VHDX support"
- fi
-elif test "$vhdx" != "no" ; then
- if test "$uuid" = "yes" ; then
- vhdx=yes
- else
- vhdx=no
- fi
-fi
-
-##########################################
# xfsctl() probe, used for raw-posix
if test "$xfs" != "no" ; then
cat > $TMPC << EOF
@@ -4075,7 +4028,7 @@ EOF
if compile_prog "$vss_win32_include" "" ; then
guest_agent_with_vss="yes"
QEMU_CFLAGS="$QEMU_CFLAGS $vss_win32_include"
- libs_qga="-lole32 -loleaut32 -lshlwapi -luuid -lstdc++ -Wl,--enable-stdcall-fixup $libs_qga"
+ libs_qga="-lole32 -loleaut32 -lshlwapi -lstdc++ -Wl,--enable-stdcall-fixup $libs_qga"
qga_vss_provider="qga/vss-win32/qga-vss.dll qga/vss-win32/qga-vss.tlb"
else
if test "$vss_win32_sdk" != "" ; then
@@ -4883,7 +4836,6 @@ echo "preadv support $preadv"
echo "fdatasync $fdatasync"
echo "madvise $madvise"
echo "posix_madvise $posix_madvise"
-echo "uuid support $uuid"
echo "libcap-ng support $cap_ng"
echo "vhost-net support $vhost_net"
echo "vhost-scsi support $vhost_scsi"
@@ -4917,7 +4869,6 @@ echo "TPM support $tpm"
echo "libssh2 support $libssh2"
echo "TPM passthrough $tpm_passthrough"
echo "QOM debugging $qom_cast_debug"
-echo "vhdx $vhdx"
echo "lzo support $lzo"
echo "snappy support $snappy"
echo "bzip2 support $bzip2"
@@ -5074,9 +5025,6 @@ fi
if test "$fnmatch" = "yes" ; then
echo "CONFIG_FNMATCH=y" >> $config_host_mak
fi
-if test "$uuid" = "yes" ; then
- echo "CONFIG_UUID=y" >> $config_host_mak
-fi
if test "$xfs" = "yes" ; then
echo "CONFIG_XFS=y" >> $config_host_mak
fi
@@ -5443,10 +5391,6 @@ if test "$libssh2" = "yes" ; then
echo "LIBSSH2_LIBS=$libssh2_libs" >> $config_host_mak
fi
-if test "$vhdx" = "yes" ; then
- echo "CONFIG_VHDX=y" >> $config_host_mak
-fi
-
# USB host support
if test "$libusb" = "yes"; then
echo "HOST_USB=libusb legacy" >> $config_host_mak
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index a848232034..4530f8241c 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -29,10 +29,7 @@
#include "crypto/pbkdf.h"
#include "crypto/secret.h"
#include "crypto/random.h"
-
-#ifdef CONFIG_UUID
-#include <uuid/uuid.h>
-#endif
+#include "qemu/uuid.h"
#include "qemu/coroutine.h"
@@ -877,18 +874,12 @@ qcrypto_block_luks_open(QCryptoBlock *block,
}
-static int
-qcrypto_block_luks_uuid_gen(uint8_t *uuidstr, Error **errp)
+static void
+qcrypto_block_luks_uuid_gen(uint8_t *uuidstr)
{
-#ifdef CONFIG_UUID
- uuid_t uuid;
- uuid_generate(uuid);
- uuid_unparse(uuid, (char *)uuidstr);
- return 0;
-#else
- error_setg(errp, "Unable to generate uuids on this platform");
- return -1;
-#endif
+ QemuUUID uuid;
+ qemu_uuid_generate(&uuid);
+ qemu_uuid_unparse(&uuid, (char *)uuidstr);
}
static int
@@ -965,10 +956,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
* it out to disk
*/
luks->header.version = QCRYPTO_BLOCK_LUKS_VERSION;
- if (qcrypto_block_luks_uuid_gen(luks->header.uuid,
- errp) < 0) {
- goto error;
- }
+ qcrypto_block_luks_uuid_gen(luks->header.uuid);
cipher_alg = qcrypto_block_luks_cipher_alg_lookup(luks_opts.cipher_alg,
errp);
diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index dc9c14cd29..17c7c0ea07 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -1773,7 +1773,7 @@ static void ipmi_sim_realize(DeviceState *dev, Error **errp)
ibs->acpi_power_state[1] = 0;
if (qemu_uuid_set) {
- memcpy(&ibs->uuid, qemu_uuid, 16);
+ memcpy(&ibs->uuid, &qemu_uuid, 16);
} else {
memset(&ibs->uuid, 0, 16);
}
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 1776b1b3c4..92aa563929 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -883,7 +883,7 @@ static void fw_cfg_init1(DeviceState *dev)
qdev_init_nofail(dev);
fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
- fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
+ fw_cfg_add_bytes(s, FW_CFG_UUID, &qemu_uuid, 16);
fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)!machine->enable_graphics);
fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ca77bb0dea..bdb689c552 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -332,12 +332,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
g_free(buf);
}
- buf = g_strdup_printf(UUID_FMT, qemu_uuid[0], qemu_uuid[1],
- qemu_uuid[2], qemu_uuid[3], qemu_uuid[4],
- qemu_uuid[5], qemu_uuid[6], qemu_uuid[7],
- qemu_uuid[8], qemu_uuid[9], qemu_uuid[10],
- qemu_uuid[11], qemu_uuid[12], qemu_uuid[13],
- qemu_uuid[14], qemu_uuid[15]);
+ buf = qemu_uuid_unparse_strdup(&qemu_uuid);
_FDT((fdt_property_string(fdt, "vm,uuid", buf)));
if (qemu_uuid_set) {
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 27b5ad4bc4..02ce27314a 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -303,7 +303,8 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
break;
}
case RTAS_SYSPARM_UUID:
- ret = sysparm_st(buffer, length, qemu_uuid, (qemu_uuid_set ? 16 : 0));
+ ret = sysparm_st(buffer, length, (unsigned char *)&qemu_uuid,
+ (qemu_uuid_set ? 16 : 0));
break;
default:
ret = RTAS_OUT_NOT_SUPPORTED;
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 74c7102929..9a6552aa60 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -20,6 +20,7 @@
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "sysemu/sysemu.h"
+#include "qemu/uuid.h"
#include "sysemu/cpus.h"
#include "hw/smbios/smbios.h"
#include "hw/loader.h"
@@ -79,7 +80,7 @@ static struct {
static struct {
const char *manufacturer, *product, *version, *serial, *sku, *family;
- /* uuid is in qemu_uuid[] */
+ /* uuid is in qemu_uuid */
} type1;
static struct {
@@ -408,7 +409,7 @@ static void smbios_build_type_1_fields(void)
* BIOS.
*/
smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
- qemu_uuid, 16);
+ &qemu_uuid, 16);
}
}
@@ -483,9 +484,9 @@ static void smbios_build_type_0_table(void)
/* Encode UUID from the big endian encoding described on RFC4122 to the wire
* format specified by SMBIOS version 2.6.
*/
-static void smbios_encode_uuid(struct smbios_uuid *uuid, const uint8_t *buf)
+static void smbios_encode_uuid(struct smbios_uuid *uuid, QemuUUID *in)
{
- memcpy(uuid, buf, 16);
+ memcpy(uuid, &in, 16);
if (smbios_uuid_encoded) {
uuid->time_low = bswap32(uuid->time_low);
uuid->time_mid = bswap16(uuid->time_mid);
@@ -502,7 +503,7 @@ static void smbios_build_type_1_table(void)
SMBIOS_TABLE_SET_STR(1, version_str, type1.version);
SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial);
if (qemu_uuid_set) {
- smbios_encode_uuid(&t->uuid, qemu_uuid);
+ smbios_encode_uuid(&t->uuid, &qemu_uuid);
} else {
memset(&t->uuid, 0, 16);
}
@@ -1001,7 +1002,7 @@ void smbios_entry_add(QemuOpts *opts)
val = qemu_opt_get(opts, "uuid");
if (val) {
- if (qemu_uuid_parse(val, qemu_uuid) != 0) {
+ if (qemu_uuid_parse(val, &qemu_uuid) != 0) {
error_report("Invalid UUID");
exit(1);
}
diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c
index 5a9f5ac806..b439b0ed5d 100644
--- a/hw/xenpv/xen_domainbuild.c
+++ b/hw/xenpv/xen_domainbuild.c
@@ -53,11 +53,7 @@ int xenstore_domain_init1(const char *kernel, const char *ramdisk,
char *dom, uuid_string[42], vm[256], path[256];
int i;
- snprintf(uuid_string, sizeof(uuid_string), UUID_FMT,
- qemu_uuid[0], qemu_uuid[1], qemu_uuid[2], qemu_uuid[3],
- qemu_uuid[4], qemu_uuid[5], qemu_uuid[6], qemu_uuid[7],
- qemu_uuid[8], qemu_uuid[9], qemu_uuid[10], qemu_uuid[11],
- qemu_uuid[12], qemu_uuid[13], qemu_uuid[14], qemu_uuid[15]);
+ qemu_uuid_unparse(&qemu_uuid, uuid_string);
dom = xs_get_domain_path(xenstore, xen_domid);
snprintf(vm, sizeof(vm), "/vm/%s", uuid_string);
diff --git a/include/qemu/uuid.h b/include/qemu/uuid.h
new file mode 100644
index 0000000000..afe4840296
--- /dev/null
+++ b/include/qemu/uuid.h
@@ -0,0 +1,59 @@
+/*
+ * QEMU UUID functions
+ *
+ * Copyright 2016 Red Hat, Inc.
+ *
+ * Authors:
+ * Fam Zheng <famz@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#ifndef QEMU_UUID_H
+#define QEMU_UUID_H
+
+#include "qemu-common.h"
+
+/* Version 4 UUID (pseudo random numbers), RFC4122 4.4. */
+
+typedef struct {
+ union {
+ unsigned char data[16];
+ struct {
+ /* Generated in BE endian, can be swapped with qemu_uuid_bswap. */
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_high_and_version;
+ uint8_t clock_seq_and_reserved;
+ uint8_t clock_seq_low;
+ uint8_t node[6];
+ } fields;
+ };
+} QemuUUID;
+
+#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-" \
+ "%02hhx%02hhx-%02hhx%02hhx-" \
+ "%02hhx%02hhx-" \
+ "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
+
+#define UUID_FMT_LEN 36
+
+#define UUID_NONE "00000000-0000-0000-0000-000000000000"
+
+void qemu_uuid_generate(QemuUUID *out);
+
+int qemu_uuid_is_null(const QemuUUID *uu);
+
+void qemu_uuid_unparse(const QemuUUID *uuid, char *out);
+
+char *qemu_uuid_unparse_strdup(const QemuUUID *uuid);
+
+int qemu_uuid_parse(const char *str, QemuUUID *uuid);
+
+void qemu_uuid_bswap(QemuUUID *uuid);
+
+#endif
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index ee7c7608e0..ef2c50bb04 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -9,6 +9,7 @@
#include "qemu/notify.h"
#include "qemu/main-loop.h"
#include "qemu/bitmap.h"
+#include "qemu/uuid.h"
#include "qom/object.h"
/* vl.c */
@@ -16,12 +17,8 @@
extern const char *bios_name;
extern const char *qemu_name;
-extern uint8_t qemu_uuid[];
+extern QemuUUID qemu_uuid;
extern bool qemu_uuid_set;
-int qemu_uuid_parse(const char *str, uint8_t *uuid);
-
-#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
-#define UUID_NONE "00000000-0000-0000-0000-000000000000"
bool runstate_check(RunState state);
void runstate_set(RunState new_state);
diff --git a/qmp.c b/qmp.c
index 6733463fa2..71f0c8b439 100644
--- a/qmp.c
+++ b/qmp.c
@@ -18,6 +18,7 @@
#include "qemu/cutils.h"
#include "monitor/monitor.h"
#include "sysemu/sysemu.h"
+#include "qemu/uuid.h"
#include "qmp-commands.h"
#include "sysemu/char.h"
#include "ui/qemu-spice.h"
@@ -35,6 +36,7 @@
#include "qom/object_interfaces.h"
#include "hw/mem/pc-dimm.h"
#include "hw/acpi/acpi_dev_interface.h"
+#include "qemu/uuid.h"
NameInfo *qmp_query_name(Error **errp)
{
@@ -74,15 +76,8 @@ KvmInfo *qmp_query_kvm(Error **errp)
UuidInfo *qmp_query_uuid(Error **errp)
{
UuidInfo *info = g_malloc0(sizeof(*info));
- char uuid[64];
- snprintf(uuid, sizeof(uuid), UUID_FMT, qemu_uuid[0], qemu_uuid[1],
- qemu_uuid[2], qemu_uuid[3], qemu_uuid[4], qemu_uuid[5],
- qemu_uuid[6], qemu_uuid[7], qemu_uuid[8], qemu_uuid[9],
- qemu_uuid[10], qemu_uuid[11], qemu_uuid[12], qemu_uuid[13],
- qemu_uuid[14], qemu_uuid[15]);
-
- info->UUID = g_strdup(uuid);
+ info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid);
return info;
}
diff --git a/stubs/uuid.c b/stubs/uuid.c
index 92ad717831..a880de8d61 100644
--- a/stubs/uuid.c
+++ b/stubs/uuid.c
@@ -1,6 +1,6 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "sysemu/sysemu.h"
+#include "qemu/uuid.h"
#include "qmp-commands.h"
UuidInfo *qmp_query_uuid(Error **errp)
diff --git a/tests/.gitignore b/tests/.gitignore
index b4a9cfc8c4..24ac6cfa77 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -70,6 +70,7 @@ test-string-output-visitor
test-thread-pool
test-throttle
test-timed-average
+test-uuid
test-visitor-serialization
test-vmstate
test-write-threshold
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 1fb3866a99..54424a818c 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -115,6 +115,7 @@ check-unit-y += tests/test-logging$(EXESUF)
check-unit-$(CONFIG_REPLICATION) += tests/test-replication$(EXESUF)
check-unit-y += tests/test-bufferiszero$(EXESUF)
gcov-files-check-bufferiszero-y = util/bufferiszero.c
+check-unit-y += tests/test-uuid$(EXESUF)
check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
@@ -660,6 +661,7 @@ tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-ob
tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
tests/ptimer-test$(EXESUF): tests/ptimer-test.o tests/ptimer-test-stubs.o hw/core/ptimer.o
+tests/test-uuid$(EXESUF): tests/test-uuid.o $(test-util-obj-y)
tests/migration/stress$(EXESUF): tests/migration/stress.o
$(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ," LINK $(TARGET_DIR)$@")
diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
index 19d4cc7077..2fcc3c6418 100644
--- a/tests/docker/Makefile.include
+++ b/tests/docker/Makefile.include
@@ -117,7 +117,7 @@ docker-run-%: docker-qemu-src
$(if $(DEBUG),-i,--net=none) \
-e TARGET_LIST=$(TARGET_LIST) \
-e EXTRA_CONFIGURE_OPTS=$(EXTRA_CONFIGURE_OPTS) \
- -e V=$V -e J=$J -e DEBUG=$(DEBUG)\
+ -e V=$V -e J=$J -e DEBUG=$(DEBUG) -e SHOW_ENV=$(SHOW_ENV)\
-e CCACHE_DIR=/var/tmp/ccache \
-v $$(readlink -e $(DOCKER_SRC_COPY)):/var/tmp/qemu:z$(COMMA)ro \
-v $(DOCKER_CCACHE_DIR):/var/tmp/ccache:z \
diff --git a/tests/docker/common.rc b/tests/docker/common.rc
index 0c6d8d5ece..510a3ad3f4 100755
--- a/tests/docker/common.rc
+++ b/tests/docker/common.rc
@@ -23,11 +23,13 @@ requires()
build_qemu()
{
- $QEMU_SRC/configure \
- --enable-werror \
- ${TARGET_LIST:+"--target-list=${TARGET_LIST}"} \
- --prefix="$PWD/install" \
- $EXTRA_CONFIGURE_OPTS \
- "$@"
+ config_opts="--enable-werror \
+ ${TARGET_LIST:+--target-list=${TARGET_LIST}} \
+ --prefix=$PWD/install \
+ $EXTRA_CONFIGURE_OPTS \
+ $@"
+ echo "Configure options:"
+ echo $config_opts
+ $QEMU_SRC/configure $config_opts
make $MAKEFLAGS
}
diff --git a/tests/docker/docker.py b/tests/docker/docker.py
index b85c165130..37d83199e7 100755
--- a/tests/docker/docker.py
+++ b/tests/docker/docker.py
@@ -21,6 +21,7 @@ import uuid
import argparse
import tempfile
import re
+import signal
from tarfile import TarFile, TarInfo
from StringIO import StringIO
from shutil import copy, rmtree
@@ -37,9 +38,12 @@ def _guess_docker_command():
""" Guess a working docker command or raise exception if not found"""
commands = [["docker"], ["sudo", "-n", "docker"]]
for cmd in commands:
- if subprocess.call(cmd + ["images"],
- stdout=DEVNULL, stderr=DEVNULL) == 0:
- return cmd
+ try:
+ if subprocess.call(cmd + ["images"],
+ stdout=DEVNULL, stderr=DEVNULL) == 0:
+ return cmd
+ except OSError:
+ pass
commands_txt = "\n".join([" " + " ".join(x) for x in commands])
raise Exception("Cannot find working docker command. Tried:\n%s" % \
commands_txt)
@@ -98,6 +102,8 @@ class Docker(object):
self._command = _guess_docker_command()
self._instances = []
atexit.register(self._kill_instances)
+ signal.signal(signal.SIGTERM, self._kill_instances)
+ signal.signal(signal.SIGHUP, self._kill_instances)
def _do(self, cmd, quiet=True, infile=None, **kwargs):
if quiet:
@@ -130,7 +136,7 @@ class Docker(object):
self._do_kill_instances(False, False)
return 0
- def _kill_instances(self):
+ def _kill_instances(self, *args, **kwargs):
return self._do_kill_instances(True)
def _output(self, cmd, **kwargs):
diff --git a/tests/docker/dockerfiles/centos6.docker b/tests/docker/dockerfiles/centos6.docker
index 8f4fe46379..34e0d3b91e 100644
--- a/tests/docker/dockerfiles/centos6.docker
+++ b/tests/docker/dockerfiles/centos6.docker
@@ -1,6 +1,8 @@
FROM centos:6
-RUN yum install -y \
+RUN yum install -y epel-release
+ENV PACKAGES libfdt-devel ccache \
tar git make gcc g++ \
zlib-devel glib2-devel SDL-devel pixman-devel \
epel-release
-RUN yum install -y libfdt-devel ccache
+RUN yum install -y $PACKAGES
+RUN rpm -q $PACKAGES | sort > /packages.txt
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
index 1d26a8e98a..478163b8d8 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -1,7 +1,17 @@
-FROM fedora:23
-RUN dnf install -y \
+FROM fedora:latest
+ENV PACKAGES \
ccache git tar PyYAML sparse flex bison \
glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
gcc gcc-c++ clang make perl which bc findutils \
- mingw{32,64}-{pixman,glib2,gmp,SDL,pkg-config,gtk2,gtk3,gnutls,nettle,libtasn1,libjpeg-turbo,libpng,curl,libssh2,bzip2}
+ mingw32-pixman mingw32-glib2 mingw32-gmp mingw32-SDL mingw32-pkg-config \
+ mingw32-gtk2 mingw32-gtk3 mingw32-gnutls mingw32-nettle mingw32-libtasn1 \
+ mingw32-libjpeg-turbo mingw32-libpng mingw32-curl mingw32-libssh2 \
+ mingw32-bzip2 \
+ mingw64-pixman mingw64-glib2 mingw64-gmp mingw64-SDL mingw64-pkg-config \
+ mingw64-gtk2 mingw64-gtk3 mingw64-gnutls mingw64-nettle mingw64-libtasn1 \
+ mingw64-libjpeg-turbo mingw64-libpng mingw64-curl mingw64-libssh2 \
+ mingw64-bzip2
+
+RUN dnf install -y $PACKAGES
+RUN rpm -q $PACKAGES | sort > /packages.txt
ENV FEATURES mingw clang pyyaml
diff --git a/tests/docker/dockerfiles/ubuntu.docker b/tests/docker/dockerfiles/ubuntu.docker
index a8b88c318c..a360a050a2 100644
--- a/tests/docker/dockerfiles/ubuntu.docker
+++ b/tests/docker/dockerfiles/ubuntu.docker
@@ -2,10 +2,12 @@ FROM ubuntu:14.04
RUN echo "deb http://archive.ubuntu.com/ubuntu/ trusty universe multiverse" >> \
/etc/apt/sources.list
RUN apt-get update
-RUN apt-get -y install flex bison \
+ENV PACKAGES flex bison \
libusb-1.0-0-dev libiscsi-dev librados-dev libncurses5-dev \
libseccomp-dev libgnutls-dev libssh2-1-dev libspice-server-dev \
libspice-protocol-dev libnss3-dev libfdt-dev \
libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev \
git make ccache python-yaml gcc clang sparse
+RUN apt-get -y install $PACKAGES
+RUN dpkg -l $PACKAGES | sort > /packages.txt
ENV FEATURES clang pyyaml
diff --git a/tests/docker/run b/tests/docker/run
index d85d49afc1..c1e4513bce 100755
--- a/tests/docker/run
+++ b/tests/docker/run
@@ -40,20 +40,34 @@ for p in dtc pixman; do
fi
done
+if test -n "$SHOW_ENV"; then
+ if test -f /packages.txt; then
+ echo "Packages installed:"
+ cat /packages.txt
+ echo
+ fi
+ echo "Environment variables:"
+ env
+ echo
+fi
+
export QEMU_SRC="$TEST_DIR/src"
cd "$QEMU_SRC/tests/docker"
CMD="$QEMU_SRC/tests/docker/$@"
-if test -n "$DEBUG"; then
- echo "* Prepared to run command:"
- echo " $CMD"
- echo "* Hit Ctrl-D to continue, or type 'exit 1' to abort"
- echo
- $SHELL
+if test -z "$DEBUG"; then
+ exec $CMD
fi
+# DEBUG workflow
+echo "* Prepared to run command:"
+echo " $CMD"
+echo "* Hit Ctrl-D to continue, or type 'exit 1' to abort"
+echo
+$SHELL
+
if "$CMD"; then
exit 0
elif test -n "$DEBUG"; then
diff --git a/tests/docker/test-quick b/tests/docker/test-quick
index 07cdc59a10..7885dfafdb 100755
--- a/tests/docker/test-quick
+++ b/tests/docker/test-quick
@@ -13,7 +13,7 @@
. common.rc
-DEF_TARGET_LIST="$(echo {x86_64,aarch64}-softmmu)"
+DEF_TARGET_LIST="x86_64-softmmu,aarch64-softmmu"
TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \
build_qemu
make check $MAKEFLAGS
diff --git a/tests/test-crypto-block.c b/tests/test-crypto-block.c
index a38110d3ff..1957a86743 100644
--- a/tests/test-crypto-block.c
+++ b/tests/test-crypto-block.c
@@ -28,7 +28,7 @@
#include <sys/resource.h>
#endif
-#if defined(CONFIG_UUID) && (defined(_WIN32) || defined RUSAGE_THREAD)
+#if (defined(_WIN32) || defined RUSAGE_THREAD)
#define TEST_LUKS
#else
#undef TEST_LUKS
diff --git a/tests/test-uuid.c b/tests/test-uuid.c
new file mode 100644
index 0000000000..77dcdc4b55
--- /dev/null
+++ b/tests/test-uuid.c
@@ -0,0 +1,177 @@
+/*
+ * QEMU UUID Library
+ *
+ * Copyright (c) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/uuid.h"
+
+struct {
+ const char *uuidstr;
+ QemuUUID uuid;
+ bool uuidstr_is_valid;
+ bool check_unparse;
+} uuid_test_data[] = {
+ { /* Normal */
+ "586ece27-7f09-41e0-9e74-e901317e9d42",
+ { { {
+ 0x58, 0x6e, 0xce, 0x27, 0x7f, 0x09, 0x41, 0xe0,
+ 0x9e, 0x74, 0xe9, 0x01, 0x31, 0x7e, 0x9d, 0x42,
+ } } },
+ true, true,
+ }, { /* NULL */
+ "00000000-0000-0000-0000-000000000000",
+ { },
+ true, true,
+ }, { /* Upper case */
+ "0CC6C752-3961-4028-A286-C05CC616D396",
+ { { {
+ 0x0c, 0xc6, 0xc7, 0x52, 0x39, 0x61, 0x40, 0x28,
+ 0xa2, 0x86, 0xc0, 0x5c, 0xc6, 0x16, 0xd3, 0x96,
+ } } },
+ true, false,
+ }, { /* Mixed case */
+ "0CC6C752-3961-4028-a286-c05cc616D396",
+ { { {
+ 0x0c, 0xc6, 0xc7, 0x52, 0x39, 0x61, 0x40, 0x28,
+ 0xa2, 0x86, 0xc0, 0x5c, 0xc6, 0x16, 0xd3, 0x96,
+ } } },
+ true, false,
+ }, { /* Empty */
+ ""
+ }, { /* Too short */
+ "abc",
+ }, { /* Non-hex */
+ "abcdefgh-0000-0000-0000-000000000000",
+ }, { /* No '-' */
+ "0cc6c75239614028a286c05cc616d396",
+ }, { /* '-' in wrong position */
+ "0cc6c-7523961-4028-a286-c05cc616d396",
+ }, { /* Double '-' */
+ "0cc6c752--3961-4028-a286-c05cc616d396",
+ }, { /* Too long */
+ "0000000000000000000000000000000000000000000000",
+ }, { /* Invalid char in the beginning */
+ ")cc6c752-3961-4028-a286-c05cc616d396",
+ }, { /* Invalid char in the beginning, in extra */
+ ")0cc6c752-3961-4028-a286-c05cc616d396",
+ }, { /* Invalid char in the middle */
+ "0cc6c752-39*1-4028-a286-c05cc616d396",
+ }, { /* Invalid char in the middle, in extra */
+ "0cc6c752-39*61-4028-a286-c05cc616d396",
+ }, { /* Invalid char in the end */
+ "0cc6c752-3961-4028-a286-c05cc616d39&",
+ }, { /* Invalid char in the end, in extra */
+ "0cc6c752-3961-4028-a286-c05cc616d396&",
+ }, { /* Short end and trailing space */
+ "0cc6c752-3961-4028-a286-c05cc616d39 ",
+ }, { /* Leading space and short end */
+ " 0cc6c752-3961-4028-a286-c05cc616d39",
+ },
+};
+
+static inline bool uuid_is_valid(QemuUUID *uuid)
+{
+ return qemu_uuid_is_null(uuid) ||
+ ((uuid->data[6] & 0xf0) == 0x40 && (uuid->data[8] & 0xc0) == 0x80);
+}
+
+static void test_uuid_generate(void)
+{
+ QemuUUID uuid;
+ int i;
+
+ for (i = 0; i < 100; ++i) {
+ qemu_uuid_generate(&uuid);
+ g_assert(uuid_is_valid(&uuid));
+ }
+}
+
+static void test_uuid_is_null(void)
+{
+ QemuUUID uuid_null = { };
+ QemuUUID uuid_not_null = { { {
+ 0x58, 0x6e, 0xce, 0x27, 0x7f, 0x09, 0x41, 0xe0,
+ 0x9e, 0x74, 0xe9, 0x01, 0x31, 0x7e, 0x9d, 0x42
+ } } };
+ QemuUUID uuid_not_null_2 = { { { 1 } } };
+
+ g_assert(qemu_uuid_is_null(&uuid_null));
+ g_assert_false(qemu_uuid_is_null(&uuid_not_null));
+ g_assert_false(qemu_uuid_is_null(&uuid_not_null_2));
+}
+
+static void test_uuid_parse(void)
+{
+ int i, r;
+
+ for (i = 0; i < ARRAY_SIZE(uuid_test_data); i++) {
+ QemuUUID uuid;
+ bool is_valid = uuid_test_data[i].uuidstr_is_valid;
+
+ r = qemu_uuid_parse(uuid_test_data[i].uuidstr, &uuid);
+ g_assert_cmpint(!r, ==, is_valid);
+ if (is_valid) {
+ g_assert_cmpint(is_valid, ==, uuid_is_valid(&uuid));
+ g_assert_cmpmem(&uuid_test_data[i].uuid, sizeof(uuid),
+ &uuid, sizeof(uuid));
+ }
+ }
+}
+
+static void test_uuid_unparse(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(uuid_test_data); i++) {
+ char out[37];
+
+ if (!uuid_test_data[i].check_unparse) {
+ continue;
+ }
+ qemu_uuid_unparse(&uuid_test_data[i].uuid, out);
+ g_assert_cmpstr(uuid_test_data[i].uuidstr, ==, out);
+ }
+}
+
+static void test_uuid_unparse_strdup(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(uuid_test_data); i++) {
+ char *out;
+
+ if (!uuid_test_data[i].check_unparse) {
+ continue;
+ }
+ out = qemu_uuid_unparse_strdup(&uuid_test_data[i].uuid);
+ g_assert_cmpstr(uuid_test_data[i].uuidstr, ==, out);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/uuid/generate", test_uuid_generate);
+ g_test_add_func("/uuid/is_null", test_uuid_is_null);
+ g_test_add_func("/uuid/parse", test_uuid_parse);
+ g_test_add_func("/uuid/unparse", test_uuid_unparse);
+ g_test_add_func("/uuid/unparse_strdup", test_uuid_unparse_strdup);
+
+ return g_test_run();
+}
diff --git a/ui/spice-core.c b/ui/spice-core.c
index da0505434a..1452e77fd1 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -796,7 +796,7 @@ void qemu_spice_init(void)
qemu_opt_foreach(opts, add_channel, &tls_port, NULL);
spice_server_set_name(spice_server, qemu_name);
- spice_server_set_uuid(spice_server, qemu_uuid);
+ spice_server_set_uuid(spice_server, (unsigned char *)&qemu_uuid);
seamless_migration = qemu_opt_get_bool(opts, "seamless-migration", 0);
spice_server_set_seamless_migration(spice_server, seamless_migration);
diff --git a/util/Makefile.objs b/util/Makefile.objs
index ffca8f3002..36c7dcc1fa 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -21,6 +21,7 @@ util-obj-y += iov.o qemu-config.o qemu-sockets.o uri.o notify.o
util-obj-y += qemu-option.o qemu-progress.o
util-obj-y += hexdump.o
util-obj-y += crc32c.o
+util-obj-y += uuid.o
util-obj-y += throttle.o
util-obj-y += getauxval.o
util-obj-y += readline.o
diff --git a/util/uuid.c b/util/uuid.c
new file mode 100644
index 0000000000..dd6b5fdf05
--- /dev/null
+++ b/util/uuid.c
@@ -0,0 +1,114 @@
+/*
+ * QEMU UUID functions
+ *
+ * Copyright 2016 Red Hat, Inc.
+ *
+ * Authors:
+ * Fam Zheng <famz@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/uuid.h"
+#include "qemu/bswap.h"
+
+void qemu_uuid_generate(QemuUUID *uuid)
+{
+ int i;
+ uint32_t tmp[4];
+
+ QEMU_BUILD_BUG_ON(sizeof(QemuUUID) != 16);
+
+ for (i = 0; i < 4; ++i) {
+ tmp[i] = g_random_int();
+ }
+ memcpy(uuid, tmp, sizeof(tmp));
+ /* Set the two most significant bits (bits 6 and 7) of the
+ clock_seq_hi_and_reserved to zero and one, respectively. */
+ uuid->data[8] = (uuid->data[8] & 0x3f) | 0x80;
+ /* Set the four most significant bits (bits 12 through 15) of the
+ time_hi_and_version field to the 4-bit version number.
+ */
+ uuid->data[6] = (uuid->data[6] & 0xf) | 0x40;
+}
+
+int qemu_uuid_is_null(const QemuUUID *uu)
+{
+ static QemuUUID null_uuid;
+ return memcmp(uu, &null_uuid, sizeof(QemuUUID)) == 0;
+}
+
+void qemu_uuid_unparse(const QemuUUID *uuid, char *out)
+{
+ const unsigned char *uu = &uuid->data[0];
+ snprintf(out, UUID_FMT_LEN + 1, UUID_FMT,
+ uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7],
+ uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
+}
+
+char *qemu_uuid_unparse_strdup(const QemuUUID *uuid)
+{
+ const unsigned char *uu = &uuid->data[0];
+ return g_strdup_printf(UUID_FMT,
+ uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6],
+ uu[7], uu[8], uu[9], uu[10], uu[11], uu[12],
+ uu[13], uu[14], uu[15]);
+}
+
+static bool qemu_uuid_is_valid(const char *str)
+{
+ int i;
+
+ for (i = 0; i < strlen(str); i++) {
+ const char c = str[i];
+ if (i == 8 || i == 13 || i == 18 || i == 23) {
+ if (str[i] != '-') {
+ return false;
+ }
+ } else {
+ if ((c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'F') ||
+ (c >= 'a' && c <= 'f')) {
+ continue;
+ }
+ return false;
+ }
+ }
+ return i == 36;
+}
+
+int qemu_uuid_parse(const char *str, QemuUUID *uuid)
+{
+ unsigned char *uu = &uuid->data[0];
+ int ret;
+
+ if (!qemu_uuid_is_valid(str)) {
+ return -1;
+ }
+
+ ret = sscanf(str, UUID_FMT, &uu[0], &uu[1], &uu[2], &uu[3],
+ &uu[4], &uu[5], &uu[6], &uu[7], &uu[8], &uu[9],
+ &uu[10], &uu[11], &uu[12], &uu[13], &uu[14],
+ &uu[15]);
+
+ if (ret != 16) {
+ return -1;
+ }
+ return 0;
+}
+
+/* Swap from UUID format endian (BE) to the opposite or vice versa.
+ */
+void qemu_uuid_bswap(QemuUUID *uuid)
+{
+ assert(QEMU_PTR_IS_ALIGNED(uuid, sizeof(uint32_t)));
+ bswap32s(&uuid->fields.time_low);
+ bswap16s(&uuid->fields.time_mid);
+ bswap16s(&uuid->fields.time_high_and_version);
+}
diff --git a/vl.c b/vl.c
index fd321e2fd4..215a6f9c7a 100644
--- a/vl.c
+++ b/vl.c
@@ -25,6 +25,7 @@
#include "qemu-version.h"
#include "qemu/cutils.h"
#include "qemu/help_option.h"
+#include "qemu/uuid.h"
#ifdef CONFIG_SECCOMP
#include "sysemu/seccomp.h"
@@ -182,10 +183,10 @@ uint8_t qemu_extra_params_fw[2];
int icount_align_option;
-/* The bytes in qemu_uuid[] are in the order specified by RFC4122, _not_ in the
+/* The bytes in qemu_uuid are in the order specified by RFC4122, _not_ in the
* little-endian "wire format" described in the SMBIOS 2.6 specification.
*/
-uint8_t qemu_uuid[16];
+QemuUUID qemu_uuid;
bool qemu_uuid_set;
static NotifierList exit_notifiers =
@@ -3779,7 +3780,7 @@ int main(int argc, char **argv, char **envp)
cursor_hide = 0;
break;
case QEMU_OPTION_uuid:
- if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
+ if (qemu_uuid_parse(optarg, &qemu_uuid) < 0) {
error_report("failed to parse UUID string: wrong format");
exit(1);
}