-----BEGIN PGP SIGNATURE-----

Version: GnuPG v2
 
 iQEcBAABCAAGBQJX5LZ0AAoJEMo1YkxqkXHGmgAIAKeDTKx0sA76ewIvH9fKdmUu
 NNatJw59XnVX8lpfOU5yISkJ4BD6oBdN7tbWaOW8yzcAeYu1Ff5iUu4LBEUFb7eW
 g6zqUCV58XjaCTLmTiAfa19Exfnh6pXZlZMRP4Hr3vUVSCHFmC0EyTEllfHxU/jW
 aPHtAEge/p6EDAHygHJBTSQzsaXRdyJNyt/AKPreDtblNRT8VgapCDzZQPcCVGH1
 F9grWVu0B/VVDS0mfgSRhT0UeF/vtiikuRW92sC4woVVB+brJyG4VwGT8oeUN8RU
 30/tGo5p9fpqef3iP669uUrloLfmWcKcIJuPfQ4ZUlZh8kIV+lWK9kZuTVgocGw=
 =xLJw
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/famz/tags/various-pull-request' into staging

# gpg: Signature made Fri 23 Sep 2016 05:58:28 BST
# gpg:                using RSA key 0xCA35624C6A9171C6
# gpg: Good signature from "Fam Zheng <famz@redhat.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 5003 7CB7 9706 0F76 F021  AD56 CA35 624C 6A91 71C6

* remotes/famz/tags/various-pull-request: (23 commits)
  docker: exec $CMD
  docker: Terminate instances at SIGTERM and SIGHUP
  docker: Support showing environment information
  docker: Print used options before doing configure
  docker: Flatten default target list in test-quick
  docker: Update fedora image to latest
  docker: Generate /packages.txt in ubuntu image
  docker: Generate /packages.txt in fedora image
  docker: Generate /packages.txt in centos6 image
  tests: Ignore test-uuid
  Add UUID files to MAINTAINERS
  tests: Add uuid tests
  uuid: Tighten uuid parse
  vl: Switch qemu_uuid to QemuUUID
  configure: Remove detection code for UUID
  tests: No longer dependent on CONFIG_UUID
  crypto: Switch to QEMU UUID API
  vpc: Use QEMU UUID API
  vdi: Use QEMU UUID API
  vhdx: Use QEMU UUID API
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

# Conflicts:
#	tests/Makefile.include
master
Peter Maydell 2016-09-23 13:10:43 +01:00
commit 4c892756fd
36 changed files with 486 additions and 237 deletions

View File

@ -1342,6 +1342,13 @@ F: include/qemu/throttle.h
F: util/throttle.c F: util/throttle.c
L: qemu-block@nongnu.org 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 Usermode Emulation
------------------ ------------------
Overall Overall

View File

@ -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) void do_acpitable_option(const QemuOpts *opts)
{ {
#ifdef TARGET_I386 #ifdef TARGET_I386

View File

@ -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 += 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.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-y += qed-check.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 += quorum.o
block-obj-y += parallels.o blkdebug.o blkverify.o blkreplay.o block-obj-y += parallels.o blkdebug.o blkverify.o blkreplay.o
block-obj-y += block-backend.o snapshot.o qapi.o block-obj-y += block-backend.o snapshot.o qapi.o

View File

@ -36,7 +36,7 @@
#include "block/block_int.h" #include "block/block_int.h"
#include "block/scsi.h" #include "block/scsi.h"
#include "qemu/iov.h" #include "qemu/iov.h"
#include "sysemu/sysemu.h" #include "qemu/uuid.h"
#include "qmp-commands.h" #include "qmp-commands.h"
#include "qapi/qmp/qstring.h" #include "qapi/qmp/qstring.h"
#include "crypto/secret.h" #include "crypto/secret.h"

View File

@ -58,14 +58,7 @@
#include "migration/migration.h" #include "migration/migration.h"
#include "qemu/coroutine.h" #include "qemu/coroutine.h"
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "qemu/uuid.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
/* Code configuration options. */ /* 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 * \ #define VDI_DISK_SIZE_MAX ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
(uint64_t)DEFAULT_CLUSTER_SIZE) (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 { typedef struct {
char text[0x40]; char text[0x40];
uint32_t signature; uint32_t signature;
@ -182,10 +153,10 @@ typedef struct {
uint32_t block_extra; /* unused here */ uint32_t block_extra; /* unused here */
uint32_t blocks_in_image; uint32_t blocks_in_image;
uint32_t blocks_allocated; uint32_t blocks_allocated;
uuid_t uuid_image; QemuUUID uuid_image;
uuid_t uuid_last_snap; QemuUUID uuid_last_snap;
uuid_t uuid_link; QemuUUID uuid_link;
uuid_t uuid_parent; QemuUUID uuid_parent;
uint64_t unused2[7]; uint64_t unused2[7];
} QEMU_PACKED VdiHeader; } QEMU_PACKED VdiHeader;
@ -206,16 +177,6 @@ typedef struct {
Error *migration_blocker; Error *migration_blocker;
} BDRVVdiState; } 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) static void vdi_header_to_cpu(VdiHeader *header)
{ {
le32_to_cpus(&header->signature); 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->block_extra);
le32_to_cpus(&header->blocks_in_image); le32_to_cpus(&header->blocks_in_image);
le32_to_cpus(&header->blocks_allocated); le32_to_cpus(&header->blocks_allocated);
uuid_convert(header->uuid_image); qemu_uuid_bswap(&header->uuid_image);
uuid_convert(header->uuid_last_snap); qemu_uuid_bswap(&header->uuid_last_snap);
uuid_convert(header->uuid_link); qemu_uuid_bswap(&header->uuid_link);
uuid_convert(header->uuid_parent); qemu_uuid_bswap(&header->uuid_parent);
} }
static void vdi_header_to_le(VdiHeader *header) 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->block_extra);
cpu_to_le32s(&header->blocks_in_image); cpu_to_le32s(&header->blocks_in_image);
cpu_to_le32s(&header->blocks_allocated); cpu_to_le32s(&header->blocks_allocated);
uuid_convert(header->uuid_image); qemu_uuid_bswap(&header->uuid_image);
uuid_convert(header->uuid_last_snap); qemu_uuid_bswap(&header->uuid_last_snap);
uuid_convert(header->uuid_link); qemu_uuid_bswap(&header->uuid_link);
uuid_convert(header->uuid_parent); qemu_uuid_bswap(&header->uuid_parent);
} }
#if defined(CONFIG_VDI_DEBUG) #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); (uint64_t)header.blocks_in_image * header.block_size);
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; 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)"); error_setg(errp, "unsupported VDI image (non-NULL link UUID)");
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; 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)"); error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
ret = -ENOTSUP; ret = -ENOTSUP;
goto fail; goto fail;
@ -821,8 +782,8 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
if (image_type == VDI_TYPE_STATIC) { if (image_type == VDI_TYPE_STATIC) {
header.blocks_allocated = blocks; header.blocks_allocated = blocks;
} }
uuid_generate(header.uuid_image); qemu_uuid_generate(&header.uuid_image);
uuid_generate(header.uuid_last_snap); qemu_uuid_generate(&header.uuid_last_snap);
/* There is no need to set header.uuid_link or header.uuid_parent here. */ /* There is no need to set header.uuid_link or header.uuid_parent here. */
#if defined(CONFIG_VDI_DEBUG) #if defined(CONFIG_VDI_DEBUG)
vdi_header_print(&header); vdi_header_print(&header);

View File

@ -21,9 +21,6 @@
#include "qemu/bswap.h" #include "qemu/bswap.h"
#include "block/vhdx.h" #include "block/vhdx.h"
#include <uuid/uuid.h>
/* /*
* All the VHDX formats on disk are little endian - the following * All the VHDX formats on disk are little endian - the following
* are helper import/export functions to correctly convert * are helper import/export functions to correctly convert

View File

@ -25,8 +25,7 @@
#include "qemu/bswap.h" #include "qemu/bswap.h"
#include "block/vhdx.h" #include "block/vhdx.h"
#include "migration/migration.h" #include "migration/migration.h"
#include "qemu/uuid.h"
#include <uuid/uuid.h>
/* Options for VHDX creation */ /* 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) void vhdx_guid_generate(MSGUID *guid)
{ {
uuid_t uuid; QemuUUID uuid;
assert(guid != NULL); assert(guid != NULL);
uuid_generate(uuid); qemu_uuid_generate(&uuid);
memcpy(guid, uuid, sizeof(MSGUID)); memcpy(guid, &uuid, sizeof(MSGUID));
} }
/* Check for region overlaps inside the VHDX image */ /* Check for region overlaps inside the VHDX image */

View File

@ -30,9 +30,7 @@
#include "qemu/module.h" #include "qemu/module.h"
#include "migration/migration.h" #include "migration/migration.h"
#include "qemu/bswap.h" #include "qemu/bswap.h"
#if defined(CONFIG_UUID) #include "qemu/uuid.h"
#include <uuid/uuid.h>
#endif
/**************************************************************/ /**************************************************************/
@ -89,7 +87,7 @@ typedef struct vhd_footer {
uint32_t checksum; uint32_t checksum;
/* UUID used to identify a parent hard disk (backing file) */ /* UUID used to identify a parent hard disk (backing file) */
uint8_t uuid[16]; QemuUUID uuid;
uint8_t in_saved_state; uint8_t in_saved_state;
} QEMU_PACKED VHDFooter; } 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); footer->type = cpu_to_be32(disk_type);
#if defined(CONFIG_UUID) qemu_uuid_generate(&footer->uuid);
uuid_generate(footer->uuid);
#endif
footer->checksum = cpu_to_be32(vpc_checksum(buf, HEADER_SIZE)); footer->checksum = cpu_to_be32(vpc_checksum(buf, HEADER_SIZE));

70
configure vendored
View File

@ -212,7 +212,6 @@ sdlabi=""
virtfs="" virtfs=""
vnc="yes" vnc="yes"
sparse="no" sparse="no"
uuid=""
vde="" vde=""
vnc_sasl="" vnc_sasl=""
vnc_jpeg="" vnc_jpeg=""
@ -317,7 +316,6 @@ vte=""
virglrenderer="" virglrenderer=""
tpm="yes" tpm="yes"
libssh2="" libssh2=""
vhdx=""
numa="" numa=""
tcmalloc="no" tcmalloc="no"
jemalloc="no" jemalloc="no"
@ -887,10 +885,6 @@ for opt do
;; ;;
--disable-slirp) slirp="no" --disable-slirp) slirp="no"
;; ;;
--disable-uuid) uuid="no"
;;
--enable-uuid) uuid="yes"
;;
--disable-vde) vde="no" --disable-vde) vde="no"
;; ;;
--enable-vde) vde="yes" --enable-vde) vde="yes"
@ -1103,6 +1097,12 @@ for opt do
--disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane) --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
echo "$0: $opt is obsolete, virtio-blk data-plane is always on" >&2 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" --disable-gtk) gtk="no"
;; ;;
--enable-gtk) gtk="yes" --enable-gtk) gtk="yes"
@ -1143,10 +1143,6 @@ for opt do
;; ;;
--enable-libssh2) libssh2="yes" --enable-libssh2) libssh2="yes"
;; ;;
--enable-vhdx) vhdx="yes"
;;
--disable-vhdx) vhdx="no"
;;
--disable-numa) numa="no" --disable-numa) numa="no"
;; ;;
--enable-numa) numa="yes" --enable-numa) numa="yes"
@ -1365,7 +1361,6 @@ disabled with --disable-FEATURE, default is enabled if available:
bluez bluez stack connectivity bluez bluez stack connectivity
kvm KVM acceleration support kvm KVM acceleration support
rdma RDMA-based migration support rdma RDMA-based migration support
uuid uuid support
vde support for vde network vde support for vde network
netmap support for netmap network netmap support for netmap network
linux-aio Linux AIO support linux-aio Linux AIO support
@ -1389,7 +1384,6 @@ disabled with --disable-FEATURE, default is enabled if available:
archipelago Archipelago backend archipelago Archipelago backend
tpm TPM support tpm TPM support
libssh2 ssh block device support libssh2 ssh block device support
vhdx support for the Microsoft VHDX image format
numa libnuma support numa libnuma support
tcmalloc tcmalloc support tcmalloc tcmalloc support
jemalloc jemalloc support jemalloc jemalloc support
@ -2661,47 +2655,6 @@ if compile_prog "" "" ; then
fnmatch="yes" fnmatch="yes"
fi 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 # xfsctl() probe, used for raw-posix
if test "$xfs" != "no" ; then if test "$xfs" != "no" ; then
@ -4075,7 +4028,7 @@ EOF
if compile_prog "$vss_win32_include" "" ; then if compile_prog "$vss_win32_include" "" ; then
guest_agent_with_vss="yes" guest_agent_with_vss="yes"
QEMU_CFLAGS="$QEMU_CFLAGS $vss_win32_include" 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" qga_vss_provider="qga/vss-win32/qga-vss.dll qga/vss-win32/qga-vss.tlb"
else else
if test "$vss_win32_sdk" != "" ; then if test "$vss_win32_sdk" != "" ; then
@ -4883,7 +4836,6 @@ echo "preadv support $preadv"
echo "fdatasync $fdatasync" echo "fdatasync $fdatasync"
echo "madvise $madvise" echo "madvise $madvise"
echo "posix_madvise $posix_madvise" echo "posix_madvise $posix_madvise"
echo "uuid support $uuid"
echo "libcap-ng support $cap_ng" echo "libcap-ng support $cap_ng"
echo "vhost-net support $vhost_net" echo "vhost-net support $vhost_net"
echo "vhost-scsi support $vhost_scsi" echo "vhost-scsi support $vhost_scsi"
@ -4917,7 +4869,6 @@ echo "TPM support $tpm"
echo "libssh2 support $libssh2" echo "libssh2 support $libssh2"
echo "TPM passthrough $tpm_passthrough" echo "TPM passthrough $tpm_passthrough"
echo "QOM debugging $qom_cast_debug" echo "QOM debugging $qom_cast_debug"
echo "vhdx $vhdx"
echo "lzo support $lzo" echo "lzo support $lzo"
echo "snappy support $snappy" echo "snappy support $snappy"
echo "bzip2 support $bzip2" echo "bzip2 support $bzip2"
@ -5074,9 +5025,6 @@ fi
if test "$fnmatch" = "yes" ; then if test "$fnmatch" = "yes" ; then
echo "CONFIG_FNMATCH=y" >> $config_host_mak echo "CONFIG_FNMATCH=y" >> $config_host_mak
fi fi
if test "$uuid" = "yes" ; then
echo "CONFIG_UUID=y" >> $config_host_mak
fi
if test "$xfs" = "yes" ; then if test "$xfs" = "yes" ; then
echo "CONFIG_XFS=y" >> $config_host_mak echo "CONFIG_XFS=y" >> $config_host_mak
fi fi
@ -5443,10 +5391,6 @@ if test "$libssh2" = "yes" ; then
echo "LIBSSH2_LIBS=$libssh2_libs" >> $config_host_mak echo "LIBSSH2_LIBS=$libssh2_libs" >> $config_host_mak
fi fi
if test "$vhdx" = "yes" ; then
echo "CONFIG_VHDX=y" >> $config_host_mak
fi
# USB host support # USB host support
if test "$libusb" = "yes"; then if test "$libusb" = "yes"; then
echo "HOST_USB=libusb legacy" >> $config_host_mak echo "HOST_USB=libusb legacy" >> $config_host_mak

View File

@ -29,10 +29,7 @@
#include "crypto/pbkdf.h" #include "crypto/pbkdf.h"
#include "crypto/secret.h" #include "crypto/secret.h"
#include "crypto/random.h" #include "crypto/random.h"
#include "qemu/uuid.h"
#ifdef CONFIG_UUID
#include <uuid/uuid.h>
#endif
#include "qemu/coroutine.h" #include "qemu/coroutine.h"
@ -877,18 +874,12 @@ qcrypto_block_luks_open(QCryptoBlock *block,
} }
static int static void
qcrypto_block_luks_uuid_gen(uint8_t *uuidstr, Error **errp) qcrypto_block_luks_uuid_gen(uint8_t *uuidstr)
{ {
#ifdef CONFIG_UUID QemuUUID uuid;
uuid_t uuid; qemu_uuid_generate(&uuid);
uuid_generate(uuid); qemu_uuid_unparse(&uuid, (char *)uuidstr);
uuid_unparse(uuid, (char *)uuidstr);
return 0;
#else
error_setg(errp, "Unable to generate uuids on this platform");
return -1;
#endif
} }
static int static int
@ -965,10 +956,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
* it out to disk * it out to disk
*/ */
luks->header.version = QCRYPTO_BLOCK_LUKS_VERSION; luks->header.version = QCRYPTO_BLOCK_LUKS_VERSION;
if (qcrypto_block_luks_uuid_gen(luks->header.uuid, qcrypto_block_luks_uuid_gen(luks->header.uuid);
errp) < 0) {
goto error;
}
cipher_alg = qcrypto_block_luks_cipher_alg_lookup(luks_opts.cipher_alg, cipher_alg = qcrypto_block_luks_cipher_alg_lookup(luks_opts.cipher_alg,
errp); errp);

View File

@ -1773,7 +1773,7 @@ static void ipmi_sim_realize(DeviceState *dev, Error **errp)
ibs->acpi_power_state[1] = 0; ibs->acpi_power_state[1] = 0;
if (qemu_uuid_set) { if (qemu_uuid_set) {
memcpy(&ibs->uuid, qemu_uuid, 16); memcpy(&ibs->uuid, &qemu_uuid, 16);
} else { } else {
memset(&ibs->uuid, 0, 16); memset(&ibs->uuid, 0, 16);
} }

View File

@ -883,7 +883,7 @@ static void fw_cfg_init1(DeviceState *dev)
qdev_init_nofail(dev); qdev_init_nofail(dev);
fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4); 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_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_NB_CPUS, (uint16_t)smp_cpus);
fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu); fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);

View File

@ -332,12 +332,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
g_free(buf); g_free(buf);
} }
buf = g_strdup_printf(UUID_FMT, qemu_uuid[0], qemu_uuid[1], buf = qemu_uuid_unparse_strdup(&qemu_uuid);
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]);
_FDT((fdt_property_string(fdt, "vm,uuid", buf))); _FDT((fdt_property_string(fdt, "vm,uuid", buf)));
if (qemu_uuid_set) { if (qemu_uuid_set) {

View File

@ -303,7 +303,8 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
break; break;
} }
case RTAS_SYSPARM_UUID: 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; break;
default: default:
ret = RTAS_OUT_NOT_SUPPORTED; ret = RTAS_OUT_NOT_SUPPORTED;

View File

@ -20,6 +20,7 @@
#include "qemu/config-file.h" #include "qemu/config-file.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "qemu/uuid.h"
#include "sysemu/cpus.h" #include "sysemu/cpus.h"
#include "hw/smbios/smbios.h" #include "hw/smbios/smbios.h"
#include "hw/loader.h" #include "hw/loader.h"
@ -79,7 +80,7 @@ static struct {
static struct { static struct {
const char *manufacturer, *product, *version, *serial, *sku, *family; const char *manufacturer, *product, *version, *serial, *sku, *family;
/* uuid is in qemu_uuid[] */ /* uuid is in qemu_uuid */
} type1; } type1;
static struct { static struct {
@ -408,7 +409,7 @@ static void smbios_build_type_1_fields(void)
* BIOS. * BIOS.
*/ */
smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 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 /* Encode UUID from the big endian encoding described on RFC4122 to the wire
* format specified by SMBIOS version 2.6. * 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) { if (smbios_uuid_encoded) {
uuid->time_low = bswap32(uuid->time_low); uuid->time_low = bswap32(uuid->time_low);
uuid->time_mid = bswap16(uuid->time_mid); 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, version_str, type1.version);
SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial); SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial);
if (qemu_uuid_set) { if (qemu_uuid_set) {
smbios_encode_uuid(&t->uuid, qemu_uuid); smbios_encode_uuid(&t->uuid, &qemu_uuid);
} else { } else {
memset(&t->uuid, 0, 16); memset(&t->uuid, 0, 16);
} }
@ -1001,7 +1002,7 @@ void smbios_entry_add(QemuOpts *opts)
val = qemu_opt_get(opts, "uuid"); val = qemu_opt_get(opts, "uuid");
if (val) { if (val) {
if (qemu_uuid_parse(val, qemu_uuid) != 0) { if (qemu_uuid_parse(val, &qemu_uuid) != 0) {
error_report("Invalid UUID"); error_report("Invalid UUID");
exit(1); exit(1);
} }

View File

@ -53,11 +53,7 @@ int xenstore_domain_init1(const char *kernel, const char *ramdisk,
char *dom, uuid_string[42], vm[256], path[256]; char *dom, uuid_string[42], vm[256], path[256];
int i; int i;
snprintf(uuid_string, sizeof(uuid_string), UUID_FMT, qemu_uuid_unparse(&qemu_uuid, uuid_string);
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]);
dom = xs_get_domain_path(xenstore, xen_domid); dom = xs_get_domain_path(xenstore, xen_domid);
snprintf(vm, sizeof(vm), "/vm/%s", uuid_string); snprintf(vm, sizeof(vm), "/vm/%s", uuid_string);

59
include/qemu/uuid.h Normal file
View File

@ -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

View File

@ -9,6 +9,7 @@
#include "qemu/notify.h" #include "qemu/notify.h"
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
#include "qemu/bitmap.h" #include "qemu/bitmap.h"
#include "qemu/uuid.h"
#include "qom/object.h" #include "qom/object.h"
/* vl.c */ /* vl.c */
@ -16,12 +17,8 @@
extern const char *bios_name; extern const char *bios_name;
extern const char *qemu_name; extern const char *qemu_name;
extern uint8_t qemu_uuid[]; extern QemuUUID qemu_uuid;
extern bool qemu_uuid_set; 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); bool runstate_check(RunState state);
void runstate_set(RunState new_state); void runstate_set(RunState new_state);

11
qmp.c
View File

@ -18,6 +18,7 @@
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "monitor/monitor.h" #include "monitor/monitor.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "qemu/uuid.h"
#include "qmp-commands.h" #include "qmp-commands.h"
#include "sysemu/char.h" #include "sysemu/char.h"
#include "ui/qemu-spice.h" #include "ui/qemu-spice.h"
@ -35,6 +36,7 @@
#include "qom/object_interfaces.h" #include "qom/object_interfaces.h"
#include "hw/mem/pc-dimm.h" #include "hw/mem/pc-dimm.h"
#include "hw/acpi/acpi_dev_interface.h" #include "hw/acpi/acpi_dev_interface.h"
#include "qemu/uuid.h"
NameInfo *qmp_query_name(Error **errp) NameInfo *qmp_query_name(Error **errp)
{ {
@ -74,15 +76,8 @@ KvmInfo *qmp_query_kvm(Error **errp)
UuidInfo *qmp_query_uuid(Error **errp) UuidInfo *qmp_query_uuid(Error **errp)
{ {
UuidInfo *info = g_malloc0(sizeof(*info)); UuidInfo *info = g_malloc0(sizeof(*info));
char uuid[64];
snprintf(uuid, sizeof(uuid), UUID_FMT, qemu_uuid[0], qemu_uuid[1], info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid);
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);
return info; return info;
} }

View File

@ -1,6 +1,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu-common.h" #include "qemu-common.h"
#include "sysemu/sysemu.h" #include "qemu/uuid.h"
#include "qmp-commands.h" #include "qmp-commands.h"
UuidInfo *qmp_query_uuid(Error **errp) UuidInfo *qmp_query_uuid(Error **errp)

1
tests/.gitignore vendored
View File

@ -70,6 +70,7 @@ test-string-output-visitor
test-thread-pool test-thread-pool
test-throttle test-throttle
test-timed-average test-timed-average
test-uuid
test-visitor-serialization test-visitor-serialization
test-vmstate test-vmstate
test-write-threshold test-write-threshold

View File

@ -115,6 +115,7 @@ check-unit-y += tests/test-logging$(EXESUF)
check-unit-$(CONFIG_REPLICATION) += tests/test-replication$(EXESUF) check-unit-$(CONFIG_REPLICATION) += tests/test-replication$(EXESUF)
check-unit-y += tests/test-bufferiszero$(EXESUF) check-unit-y += tests/test-bufferiszero$(EXESUF)
gcov-files-check-bufferiszero-y = util/bufferiszero.c gcov-files-check-bufferiszero-y = util/bufferiszero.c
check-unit-y += tests/test-uuid$(EXESUF)
check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh 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/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/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/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 tests/migration/stress$(EXESUF): tests/migration/stress.o
$(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ," LINK $(TARGET_DIR)$@") $(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ," LINK $(TARGET_DIR)$@")

View File

@ -117,7 +117,7 @@ docker-run-%: docker-qemu-src
$(if $(DEBUG),-i,--net=none) \ $(if $(DEBUG),-i,--net=none) \
-e TARGET_LIST=$(TARGET_LIST) \ -e TARGET_LIST=$(TARGET_LIST) \
-e EXTRA_CONFIGURE_OPTS=$(EXTRA_CONFIGURE_OPTS) \ -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 \ -e CCACHE_DIR=/var/tmp/ccache \
-v $$(readlink -e $(DOCKER_SRC_COPY)):/var/tmp/qemu:z$(COMMA)ro \ -v $$(readlink -e $(DOCKER_SRC_COPY)):/var/tmp/qemu:z$(COMMA)ro \
-v $(DOCKER_CCACHE_DIR):/var/tmp/ccache:z \ -v $(DOCKER_CCACHE_DIR):/var/tmp/ccache:z \

View File

@ -23,11 +23,13 @@ requires()
build_qemu() build_qemu()
{ {
$QEMU_SRC/configure \ config_opts="--enable-werror \
--enable-werror \ ${TARGET_LIST:+--target-list=${TARGET_LIST}} \
${TARGET_LIST:+"--target-list=${TARGET_LIST}"} \ --prefix=$PWD/install \
--prefix="$PWD/install" \ $EXTRA_CONFIGURE_OPTS \
$EXTRA_CONFIGURE_OPTS \ $@"
"$@" echo "Configure options:"
echo $config_opts
$QEMU_SRC/configure $config_opts
make $MAKEFLAGS make $MAKEFLAGS
} }

View File

@ -21,6 +21,7 @@ import uuid
import argparse import argparse
import tempfile import tempfile
import re import re
import signal
from tarfile import TarFile, TarInfo from tarfile import TarFile, TarInfo
from StringIO import StringIO from StringIO import StringIO
from shutil import copy, rmtree from shutil import copy, rmtree
@ -37,9 +38,12 @@ def _guess_docker_command():
""" Guess a working docker command or raise exception if not found""" """ Guess a working docker command or raise exception if not found"""
commands = [["docker"], ["sudo", "-n", "docker"]] commands = [["docker"], ["sudo", "-n", "docker"]]
for cmd in commands: for cmd in commands:
if subprocess.call(cmd + ["images"], try:
stdout=DEVNULL, stderr=DEVNULL) == 0: if subprocess.call(cmd + ["images"],
return cmd stdout=DEVNULL, stderr=DEVNULL) == 0:
return cmd
except OSError:
pass
commands_txt = "\n".join([" " + " ".join(x) for x in commands]) commands_txt = "\n".join([" " + " ".join(x) for x in commands])
raise Exception("Cannot find working docker command. Tried:\n%s" % \ raise Exception("Cannot find working docker command. Tried:\n%s" % \
commands_txt) commands_txt)
@ -98,6 +102,8 @@ class Docker(object):
self._command = _guess_docker_command() self._command = _guess_docker_command()
self._instances = [] self._instances = []
atexit.register(self._kill_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): def _do(self, cmd, quiet=True, infile=None, **kwargs):
if quiet: if quiet:
@ -130,7 +136,7 @@ class Docker(object):
self._do_kill_instances(False, False) self._do_kill_instances(False, False)
return 0 return 0
def _kill_instances(self): def _kill_instances(self, *args, **kwargs):
return self._do_kill_instances(True) return self._do_kill_instances(True)
def _output(self, cmd, **kwargs): def _output(self, cmd, **kwargs):

View File

@ -1,6 +1,8 @@
FROM centos:6 FROM centos:6
RUN yum install -y \ RUN yum install -y epel-release
ENV PACKAGES libfdt-devel ccache \
tar git make gcc g++ \ tar git make gcc g++ \
zlib-devel glib2-devel SDL-devel pixman-devel \ zlib-devel glib2-devel SDL-devel pixman-devel \
epel-release epel-release
RUN yum install -y libfdt-devel ccache RUN yum install -y $PACKAGES
RUN rpm -q $PACKAGES | sort > /packages.txt

View File

@ -1,7 +1,17 @@
FROM fedora:23 FROM fedora:latest
RUN dnf install -y \ ENV PACKAGES \
ccache git tar PyYAML sparse flex bison \ ccache git tar PyYAML sparse flex bison \
glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \ glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
gcc gcc-c++ clang make perl which bc findutils \ 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 ENV FEATURES mingw clang pyyaml

View File

@ -2,10 +2,12 @@ FROM ubuntu:14.04
RUN echo "deb http://archive.ubuntu.com/ubuntu/ trusty universe multiverse" >> \ RUN echo "deb http://archive.ubuntu.com/ubuntu/ trusty universe multiverse" >> \
/etc/apt/sources.list /etc/apt/sources.list
RUN apt-get update 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 \ libusb-1.0-0-dev libiscsi-dev librados-dev libncurses5-dev \
libseccomp-dev libgnutls-dev libssh2-1-dev libspice-server-dev \ libseccomp-dev libgnutls-dev libssh2-1-dev libspice-server-dev \
libspice-protocol-dev libnss3-dev libfdt-dev \ libspice-protocol-dev libnss3-dev libfdt-dev \
libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev \ libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev \
git make ccache python-yaml gcc clang sparse 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 ENV FEATURES clang pyyaml

View File

@ -40,20 +40,34 @@ for p in dtc pixman; do
fi fi
done 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" export QEMU_SRC="$TEST_DIR/src"
cd "$QEMU_SRC/tests/docker" cd "$QEMU_SRC/tests/docker"
CMD="$QEMU_SRC/tests/docker/$@" CMD="$QEMU_SRC/tests/docker/$@"
if test -n "$DEBUG"; then if test -z "$DEBUG"; then
echo "* Prepared to run command:" exec $CMD
echo " $CMD"
echo "* Hit Ctrl-D to continue, or type 'exit 1' to abort"
echo
$SHELL
fi 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 if "$CMD"; then
exit 0 exit 0
elif test -n "$DEBUG"; then elif test -n "$DEBUG"; then

View File

@ -13,7 +13,7 @@
. common.rc . 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} \ TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \
build_qemu build_qemu
make check $MAKEFLAGS make check $MAKEFLAGS

View File

@ -28,7 +28,7 @@
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif
#if defined(CONFIG_UUID) && (defined(_WIN32) || defined RUSAGE_THREAD) #if (defined(_WIN32) || defined RUSAGE_THREAD)
#define TEST_LUKS #define TEST_LUKS
#else #else
#undef TEST_LUKS #undef TEST_LUKS

177
tests/test-uuid.c Normal file
View File

@ -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();
}

View File

@ -796,7 +796,7 @@ void qemu_spice_init(void)
qemu_opt_foreach(opts, add_channel, &tls_port, NULL); qemu_opt_foreach(opts, add_channel, &tls_port, NULL);
spice_server_set_name(spice_server, qemu_name); 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); seamless_migration = qemu_opt_get_bool(opts, "seamless-migration", 0);
spice_server_set_seamless_migration(spice_server, seamless_migration); spice_server_set_seamless_migration(spice_server, seamless_migration);

View File

@ -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 += qemu-option.o qemu-progress.o
util-obj-y += hexdump.o util-obj-y += hexdump.o
util-obj-y += crc32c.o util-obj-y += crc32c.o
util-obj-y += uuid.o
util-obj-y += throttle.o util-obj-y += throttle.o
util-obj-y += getauxval.o util-obj-y += getauxval.o
util-obj-y += readline.o util-obj-y += readline.o

114
util/uuid.c Normal file
View File

@ -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);
}

7
vl.c
View File

@ -25,6 +25,7 @@
#include "qemu-version.h" #include "qemu-version.h"
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "qemu/help_option.h" #include "qemu/help_option.h"
#include "qemu/uuid.h"
#ifdef CONFIG_SECCOMP #ifdef CONFIG_SECCOMP
#include "sysemu/seccomp.h" #include "sysemu/seccomp.h"
@ -182,10 +183,10 @@ uint8_t qemu_extra_params_fw[2];
int icount_align_option; 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. * little-endian "wire format" described in the SMBIOS 2.6 specification.
*/ */
uint8_t qemu_uuid[16]; QemuUUID qemu_uuid;
bool qemu_uuid_set; bool qemu_uuid_set;
static NotifierList exit_notifiers = static NotifierList exit_notifiers =
@ -3779,7 +3780,7 @@ int main(int argc, char **argv, char **envp)
cursor_hide = 0; cursor_hide = 0;
break; break;
case QEMU_OPTION_uuid: 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"); error_report("failed to parse UUID string: wrong format");
exit(1); exit(1);
} }