diff options
Diffstat (limited to 'contrib')
109 files changed, 0 insertions, 39377 deletions
diff --git a/contrib/qemu/block.c b/contrib/qemu/block.c deleted file mode 100644 index b56024113b8..00000000000 --- a/contrib/qemu/block.c +++ /dev/null @@ -1,4604 +0,0 @@ -/* - * QEMU System Emulator block driver - * - * Copyright (c) 2003 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "config-host.h" -#include "qemu-common.h" -#include "trace.h" -#include "monitor/monitor.h" -#include "block/block_int.h" -#include "block/blockjob.h" -#include "qemu/module.h" -#include "qapi/qmp/qjson.h" -#include "sysemu/sysemu.h" -#include "qemu/notify.h" -#include "block/coroutine.h" -#include "qmp-commands.h" -#include "qemu/timer.h" - -#ifdef CONFIG_BSD -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/queue.h> -#ifndef __DragonFly__ -#include <sys/disk.h> -#endif -#endif - -#ifdef _WIN32 -#include <windows.h> -#endif - -#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ - -typedef enum { -    BDRV_REQ_COPY_ON_READ = 0x1, -    BDRV_REQ_ZERO_WRITE   = 0x2, -} BdrvRequestFlags; - -static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load); -static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, -        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, -        BlockDriverCompletionFunc *cb, void *opaque); -static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, -        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, -        BlockDriverCompletionFunc *cb, void *opaque); -static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, -                                         int64_t sector_num, int nb_sectors, -                                         QEMUIOVector *iov); -static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, -                                         int64_t sector_num, int nb_sectors, -                                         QEMUIOVector *iov); -static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, -    BdrvRequestFlags flags); -static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, -    BdrvRequestFlags flags); -static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, -                                               int64_t sector_num, -                                               QEMUIOVector *qiov, -                                               int nb_sectors, -                                               BlockDriverCompletionFunc *cb, -                                               void *opaque, -                                               bool is_write); -static void coroutine_fn bdrv_co_do_rw(void *opaque); -static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors); - -static bool bdrv_exceed_bps_limits(BlockDriverState *bs, int nb_sectors, -        bool is_write, double elapsed_time, uint64_t *wait); -static bool bdrv_exceed_iops_limits(BlockDriverState *bs, bool is_write, -        double elapsed_time, uint64_t *wait); -static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors, -        bool is_write, int64_t *wait); - -static QTAILQ_HEAD(, BlockDriverState) bdrv_states = -    QTAILQ_HEAD_INITIALIZER(bdrv_states); - -static QLIST_HEAD(, BlockDriver) bdrv_drivers = -    QLIST_HEAD_INITIALIZER(bdrv_drivers); - -/* If non-zero, use only whitelisted block drivers */ -static int use_bdrv_whitelist; - -#ifdef _WIN32 -static int is_windows_drive_prefix(const char *filename) -{ -    return (((filename[0] >= 'a' && filename[0] <= 'z') || -             (filename[0] >= 'A' && filename[0] <= 'Z')) && -            filename[1] == ':'); -} - -int is_windows_drive(const char *filename) -{ -    if (is_windows_drive_prefix(filename) && -        filename[2] == '\0') -        return 1; -    if (strstart(filename, "\\\\.\\", NULL) || -        strstart(filename, "//./", NULL)) -        return 1; -    return 0; -} -#endif - -/* throttling disk I/O limits */ -void bdrv_io_limits_disable(BlockDriverState *bs) -{ -    bs->io_limits_enabled = false; - -    while (qemu_co_queue_next(&bs->throttled_reqs)); - -    if (bs->block_timer) { -        qemu_del_timer(bs->block_timer); -        qemu_free_timer(bs->block_timer); -        bs->block_timer = NULL; -    } - -    bs->slice_start = 0; -    bs->slice_end   = 0; -} - -static void bdrv_block_timer(void *opaque) -{ -    BlockDriverState *bs = opaque; - -    qemu_co_queue_next(&bs->throttled_reqs); -} - -void bdrv_io_limits_enable(BlockDriverState *bs) -{ -    qemu_co_queue_init(&bs->throttled_reqs); -    bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs); -    bs->io_limits_enabled = true; -} - -bool bdrv_io_limits_enabled(BlockDriverState *bs) -{ -    BlockIOLimit *io_limits = &bs->io_limits; -    return io_limits->bps[BLOCK_IO_LIMIT_READ] -         || io_limits->bps[BLOCK_IO_LIMIT_WRITE] -         || io_limits->bps[BLOCK_IO_LIMIT_TOTAL] -         || io_limits->iops[BLOCK_IO_LIMIT_READ] -         || io_limits->iops[BLOCK_IO_LIMIT_WRITE] -         || io_limits->iops[BLOCK_IO_LIMIT_TOTAL]; -} - -static void bdrv_io_limits_intercept(BlockDriverState *bs, -                                     bool is_write, int nb_sectors) -{ -    int64_t wait_time = -1; - -    if (!qemu_co_queue_empty(&bs->throttled_reqs)) { -        qemu_co_queue_wait(&bs->throttled_reqs); -    } - -    /* In fact, we hope to keep each request's timing, in FIFO mode. The next -     * throttled requests will not be dequeued until the current request is -     * allowed to be serviced. So if the current request still exceeds the -     * limits, it will be inserted to the head. All requests followed it will -     * be still in throttled_reqs queue. -     */ - -    while (bdrv_exceed_io_limits(bs, nb_sectors, is_write, &wait_time)) { -        qemu_mod_timer(bs->block_timer, -                       wait_time + qemu_get_clock_ns(vm_clock)); -        qemu_co_queue_wait_insert_head(&bs->throttled_reqs); -    } - -    qemu_co_queue_next(&bs->throttled_reqs); -} - -/* check if the path starts with "<protocol>:" */ -static int path_has_protocol(const char *path) -{ -    const char *p; - -#ifdef _WIN32 -    if (is_windows_drive(path) || -        is_windows_drive_prefix(path)) { -        return 0; -    } -    p = path + strcspn(path, ":/\\"); -#else -    p = path + strcspn(path, ":/"); -#endif - -    return *p == ':'; -} - -int path_is_absolute(const char *path) -{ -#ifdef _WIN32 -    /* specific case for names like: "\\.\d:" */ -    if (is_windows_drive(path) || is_windows_drive_prefix(path)) { -        return 1; -    } -    return (*path == '/' || *path == '\\'); -#else -    return (*path == '/'); -#endif -} - -/* if filename is absolute, just copy it to dest. Otherwise, build a -   path to it by considering it is relative to base_path. URL are -   supported. */ -void path_combine(char *dest, int dest_size, -                  const char *base_path, -                  const char *filename) -{ -    const char *p, *p1; -    int len; - -    if (dest_size <= 0) -        return; -    if (path_is_absolute(filename)) { -        pstrcpy(dest, dest_size, filename); -    } else { -        p = strchr(base_path, ':'); -        if (p) -            p++; -        else -            p = base_path; -        p1 = strrchr(base_path, '/'); -#ifdef _WIN32 -        { -            const char *p2; -            p2 = strrchr(base_path, '\\'); -            if (!p1 || p2 > p1) -                p1 = p2; -        } -#endif -        if (p1) -            p1++; -        else -            p1 = base_path; -        if (p1 > p) -            p = p1; -        len = p - base_path; -        if (len > dest_size - 1) -            len = dest_size - 1; -        memcpy(dest, base_path, len); -        dest[len] = '\0'; -        pstrcat(dest, dest_size, filename); -    } -} - -void bdrv_get_full_backing_filename(BlockDriverState *bs, char *dest, size_t sz) -{ -    if (bs->backing_file[0] == '\0' || path_has_protocol(bs->backing_file)) { -        pstrcpy(dest, sz, bs->backing_file); -    } else { -        path_combine(dest, sz, bs->filename, bs->backing_file); -    } -} - -void bdrv_register(BlockDriver *bdrv) -{ -    /* Block drivers without coroutine functions need emulation */ -    if (!bdrv->bdrv_co_readv) { -        bdrv->bdrv_co_readv = bdrv_co_readv_em; -        bdrv->bdrv_co_writev = bdrv_co_writev_em; - -        /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if -         * the block driver lacks aio we need to emulate that too. -         */ -        if (!bdrv->bdrv_aio_readv) { -            /* add AIO emulation layer */ -            bdrv->bdrv_aio_readv = bdrv_aio_readv_em; -            bdrv->bdrv_aio_writev = bdrv_aio_writev_em; -        } -    } - -    QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); -} - -/* create a new block device (by default it is empty) */ -BlockDriverState *bdrv_new(const char *device_name) -{ -    BlockDriverState *bs; - -    bs = g_malloc0(sizeof(BlockDriverState)); -    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); -    if (device_name[0] != '\0') { -        QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); -    } -    bdrv_iostatus_disable(bs); -    notifier_list_init(&bs->close_notifiers); -    notifier_with_return_list_init(&bs->before_write_notifiers); - -    return bs; -} - -void bdrv_add_close_notifier(BlockDriverState *bs, Notifier *notify) -{ -    notifier_list_add(&bs->close_notifiers, notify); -} - -BlockDriver *bdrv_find_format(const char *format_name) -{ -    BlockDriver *drv1; -    QLIST_FOREACH(drv1, &bdrv_drivers, list) { -        if (!strcmp(drv1->format_name, format_name)) { -            return drv1; -        } -    } -    return NULL; -} - -static int bdrv_is_whitelisted(BlockDriver *drv, bool read_only) -{ -    static const char *whitelist_rw[] = { -        CONFIG_BDRV_RW_WHITELIST -    }; -    static const char *whitelist_ro[] = { -        CONFIG_BDRV_RO_WHITELIST -    }; -    const char **p; - -    if (!whitelist_rw[0] && !whitelist_ro[0]) { -        return 1;               /* no whitelist, anything goes */ -    } - -    for (p = whitelist_rw; *p; p++) { -        if (!strcmp(drv->format_name, *p)) { -            return 1; -        } -    } -    if (read_only) { -        for (p = whitelist_ro; *p; p++) { -            if (!strcmp(drv->format_name, *p)) { -                return 1; -            } -        } -    } -    return 0; -} - -BlockDriver *bdrv_find_whitelisted_format(const char *format_name, -                                          bool read_only) -{ -    BlockDriver *drv = bdrv_find_format(format_name); -    return drv && bdrv_is_whitelisted(drv, read_only) ? drv : NULL; -} - -typedef struct CreateCo { -    BlockDriver *drv; -    char *filename; -    QEMUOptionParameter *options; -    int ret; -} CreateCo; - -static void coroutine_fn bdrv_create_co_entry(void *opaque) -{ -    CreateCo *cco = opaque; -    assert(cco->drv); - -    cco->ret = cco->drv->bdrv_create(cco->filename, cco->options); -} - -int bdrv_create(BlockDriver *drv, const char* filename, -    QEMUOptionParameter *options) -{ -    int ret; - -    Coroutine *co; -    CreateCo cco = { -        .drv = drv, -        .filename = g_strdup(filename), -        .options = options, -        .ret = NOT_DONE, -    }; - -    if (!drv->bdrv_create) { -        ret = -ENOTSUP; -        goto out; -    } - -    if (qemu_in_coroutine()) { -        /* Fast-path if already in coroutine context */ -        bdrv_create_co_entry(&cco); -    } else { -        co = qemu_coroutine_create(bdrv_create_co_entry); -        qemu_coroutine_enter(co, &cco); -        while (cco.ret == NOT_DONE) { -            qemu_aio_wait(); -        } -    } - -    ret = cco.ret; - -out: -    g_free(cco.filename); -    return ret; -} - -int bdrv_create_file(const char* filename, QEMUOptionParameter *options) -{ -    BlockDriver *drv; - -    drv = bdrv_find_protocol(filename, true); -    if (drv == NULL) { -        return -ENOENT; -    } - -    return bdrv_create(drv, filename, options); -} - -/* - * Create a uniquely-named empty temporary file. - * Return 0 upon success, otherwise a negative errno value. - */ -int get_tmp_filename(char *filename, int size) -{ -#ifdef _WIN32 -    char temp_dir[MAX_PATH]; -    /* GetTempFileName requires that its output buffer (4th param) -       have length MAX_PATH or greater.  */ -    assert(size >= MAX_PATH); -    return (GetTempPath(MAX_PATH, temp_dir) -            && GetTempFileName(temp_dir, "qem", 0, filename) -            ? 0 : -GetLastError()); -#else -    int fd; -    const char *tmpdir; -    tmpdir = getenv("TMPDIR"); -    if (!tmpdir) -        tmpdir = "/tmp"; -    if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) { -        return -EOVERFLOW; -    } -    fd = mkstemp(filename); -    if (fd < 0) { -        return -errno; -    } -    if (close(fd) != 0) { -        unlink(filename); -        return -errno; -    } -    return 0; -#endif -} - -/* - * Detect host devices. By convention, /dev/cdrom[N] is always - * recognized as a host CDROM. - */ -static BlockDriver *find_hdev_driver(const char *filename) -{ -    int score_max = 0, score; -    BlockDriver *drv = NULL, *d; - -    QLIST_FOREACH(d, &bdrv_drivers, list) { -        if (d->bdrv_probe_device) { -            score = d->bdrv_probe_device(filename); -            if (score > score_max) { -                score_max = score; -                drv = d; -            } -        } -    } - -    return drv; -} - -BlockDriver *bdrv_find_protocol(const char *filename, -                                bool allow_protocol_prefix) -{ -    BlockDriver *drv1; -    char protocol[128]; -    int len; -    const char *p; - -    /* TODO Drivers without bdrv_file_open must be specified explicitly */ - -    /* -     * XXX(hch): we really should not let host device detection -     * override an explicit protocol specification, but moving this -     * later breaks access to device names with colons in them. -     * Thanks to the brain-dead persistent naming schemes on udev- -     * based Linux systems those actually are quite common. -     */ -    drv1 = find_hdev_driver(filename); -    if (drv1) { -        return drv1; -    } - -    if (!path_has_protocol(filename) || !allow_protocol_prefix) { -        return bdrv_find_format("file"); -    } - -    p = strchr(filename, ':'); -    assert(p != NULL); -    len = p - filename; -    if (len > sizeof(protocol) - 1) -        len = sizeof(protocol) - 1; -    memcpy(protocol, filename, len); -    protocol[len] = '\0'; -    QLIST_FOREACH(drv1, &bdrv_drivers, list) { -        if (drv1->protocol_name && -            !strcmp(drv1->protocol_name, protocol)) { -            return drv1; -        } -    } -    return NULL; -} - -static int find_image_format(BlockDriverState *bs, const char *filename, -                             BlockDriver **pdrv) -{ -    int score, score_max; -    BlockDriver *drv1, *drv; -    uint8_t buf[2048]; -    int ret = 0; - -    /* Return the raw BlockDriver * to scsi-generic devices or empty drives */ -    if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) { -        drv = bdrv_find_format("raw"); -        if (!drv) { -            ret = -ENOENT; -        } -        *pdrv = drv; -        return ret; -    } - -    ret = bdrv_pread(bs, 0, buf, sizeof(buf)); -    if (ret < 0) { -        *pdrv = NULL; -        return ret; -    } - -    score_max = 0; -    drv = NULL; -    QLIST_FOREACH(drv1, &bdrv_drivers, list) { -        if (drv1->bdrv_probe) { -            score = drv1->bdrv_probe(buf, ret, filename); -            if (score > score_max) { -                score_max = score; -                drv = drv1; -            } -        } -    } -    if (!drv) { -        ret = -ENOENT; -    } -    *pdrv = drv; -    return ret; -} - -/** - * Set the current 'total_sectors' value - */ -static int refresh_total_sectors(BlockDriverState *bs, int64_t hint) -{ -    BlockDriver *drv = bs->drv; - -    /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */ -    if (bs->sg) -        return 0; - -    /* query actual device if possible, otherwise just trust the hint */ -    if (drv->bdrv_getlength) { -        int64_t length = drv->bdrv_getlength(bs); -        if (length < 0) { -            return length; -        } -        hint = length >> BDRV_SECTOR_BITS; -    } - -    bs->total_sectors = hint; -    return 0; -} - -/** - * Set open flags for a given discard mode - * - * Return 0 on success, -1 if the discard mode was invalid. - */ -int bdrv_parse_discard_flags(const char *mode, int *flags) -{ -    *flags &= ~BDRV_O_UNMAP; - -    if (!strcmp(mode, "off") || !strcmp(mode, "ignore")) { -        /* do nothing */ -    } else if (!strcmp(mode, "on") || !strcmp(mode, "unmap")) { -        *flags |= BDRV_O_UNMAP; -    } else { -        return -1; -    } - -    return 0; -} - -/** - * Set open flags for a given cache mode - * - * Return 0 on success, -1 if the cache mode was invalid. - */ -int bdrv_parse_cache_flags(const char *mode, int *flags) -{ -    *flags &= ~BDRV_O_CACHE_MASK; - -    if (!strcmp(mode, "off") || !strcmp(mode, "none")) { -        *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; -    } else if (!strcmp(mode, "directsync")) { -        *flags |= BDRV_O_NOCACHE; -    } else if (!strcmp(mode, "writeback")) { -        *flags |= BDRV_O_CACHE_WB; -    } else if (!strcmp(mode, "unsafe")) { -        *flags |= BDRV_O_CACHE_WB; -        *flags |= BDRV_O_NO_FLUSH; -    } else if (!strcmp(mode, "writethrough")) { -        /* this is the default */ -    } else { -        return -1; -    } - -    return 0; -} - -/** - * The copy-on-read flag is actually a reference count so multiple users may - * use the feature without worrying about clobbering its previous state. - * Copy-on-read stays enabled until all users have called to disable it. - */ -void bdrv_enable_copy_on_read(BlockDriverState *bs) -{ -    bs->copy_on_read++; -} - -void bdrv_disable_copy_on_read(BlockDriverState *bs) -{ -    assert(bs->copy_on_read > 0); -    bs->copy_on_read--; -} - -static int bdrv_open_flags(BlockDriverState *bs, int flags) -{ -    int open_flags = flags | BDRV_O_CACHE_WB; - -    /* -     * Clear flags that are internal to the block layer before opening the -     * image. -     */ -    open_flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); - -    /* -     * Snapshots should be writable. -     */ -    if (bs->is_temporary) { -        open_flags |= BDRV_O_RDWR; -    } - -    return open_flags; -} - -/* - * Common part for opening disk images and files - * - * Removes all processed options from *options. - */ -static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, -    QDict *options, int flags, BlockDriver *drv) -{ -    int ret, open_flags; -    const char *filename; - -    assert(drv != NULL); -    assert(bs->file == NULL); -    assert(options != NULL && bs->options != options); - -    if (file != NULL) { -        filename = file->filename; -    } else { -        filename = qdict_get_try_str(options, "filename"); -    } - -    trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name); - -    /* bdrv_open() with directly using a protocol as drv. This layer is already -     * opened, so assign it to bs (while file becomes a closed BlockDriverState) -     * and return immediately. */ -    if (file != NULL && drv->bdrv_file_open) { -        bdrv_swap(file, bs); -        return 0; -    } - -    bs->open_flags = flags; -    bs->buffer_alignment = 512; -    open_flags = bdrv_open_flags(bs, flags); -    bs->read_only = !(open_flags & BDRV_O_RDWR); - -    if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) { -        return -ENOTSUP; -    } - -    assert(bs->copy_on_read == 0); /* bdrv_new() and bdrv_close() make it so */ -    if (!bs->read_only && (flags & BDRV_O_COPY_ON_READ)) { -        bdrv_enable_copy_on_read(bs); -    } - -    if (filename != NULL) { -        pstrcpy(bs->filename, sizeof(bs->filename), filename); -    } else { -        bs->filename[0] = '\0'; -    } - -    bs->drv = drv; -    bs->opaque = g_malloc0(drv->instance_size); - -    bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB); - -    /* Open the image, either directly or using a protocol */ -    if (drv->bdrv_file_open) { -        assert(file == NULL); -        assert(drv->bdrv_parse_filename || filename != NULL); -        ret = drv->bdrv_file_open(bs, options, open_flags); -    } else { -        if (file == NULL) { -            qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't use '%s' as a " -                          "block driver for the protocol level", -                          drv->format_name); -            ret = -EINVAL; -            goto free_and_fail; -        } -        assert(file != NULL); -        bs->file = file; -        ret = drv->bdrv_open(bs, options, open_flags); -    } - -    if (ret < 0) { -        goto free_and_fail; -    } - -    ret = refresh_total_sectors(bs, bs->total_sectors); -    if (ret < 0) { -        goto free_and_fail; -    } - -#ifndef _WIN32 -    if (bs->is_temporary) { -        assert(filename != NULL); -        unlink(filename); -    } -#endif -    return 0; - -free_and_fail: -    bs->file = NULL; -    g_free(bs->opaque); -    bs->opaque = NULL; -    bs->drv = NULL; -    return ret; -} - -/* - * Opens a file using a protocol (file, host_device, nbd, ...) - * - * options is a QDict of options to pass to the block drivers, or NULL for an - * empty set of options. The reference to the QDict belongs to the block layer - * after the call (even on failure), so if the caller intends to reuse the - * dictionary, it needs to use QINCREF() before calling bdrv_file_open. - */ -int bdrv_file_open(BlockDriverState **pbs, const char *filename, -                   QDict *options, int flags) -{ -    BlockDriverState *bs; -    BlockDriver *drv; -    const char *drvname; -    bool allow_protocol_prefix = false; -    int ret; - -    /* NULL means an empty set of options */ -    if (options == NULL) { -        options = qdict_new(); -    } - -    bs = bdrv_new(""); -    bs->options = options; -    options = qdict_clone_shallow(options); - -    /* Fetch the file name from the options QDict if necessary */ -    if (!filename) { -        filename = qdict_get_try_str(options, "filename"); -    } else if (filename && !qdict_haskey(options, "filename")) { -        qdict_put(options, "filename", qstring_from_str(filename)); -        allow_protocol_prefix = true; -    } else { -        qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and " -                      "'filename' options at the same time"); -        ret = -EINVAL; -        goto fail; -    } - -    /* Find the right block driver */ -    drvname = qdict_get_try_str(options, "driver"); -    if (drvname) { -        drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR)); -        qdict_del(options, "driver"); -    } else if (filename) { -        drv = bdrv_find_protocol(filename, allow_protocol_prefix); -        if (!drv) { -            qerror_report(ERROR_CLASS_GENERIC_ERROR, "Unknown protocol"); -        } -    } else { -        qerror_report(ERROR_CLASS_GENERIC_ERROR, -                      "Must specify either driver or file"); -        drv = NULL; -    } - -    if (!drv) { -        ret = -ENOENT; -        goto fail; -    } - -    /* Parse the filename and open it */ -    if (drv->bdrv_parse_filename && filename) { -        Error *local_err = NULL; -        drv->bdrv_parse_filename(filename, options, &local_err); -        if (error_is_set(&local_err)) { -            qerror_report_err(local_err); -            error_free(local_err); -            ret = -EINVAL; -            goto fail; -        } -        qdict_del(options, "filename"); -    } else if (!drv->bdrv_parse_filename && !filename) { -        qerror_report(ERROR_CLASS_GENERIC_ERROR, -                      "The '%s' block driver requires a file name", -                      drv->format_name); -        ret = -EINVAL; -        goto fail; -    } - -    ret = bdrv_open_common(bs, NULL, options, flags, drv); -    if (ret < 0) { -        goto fail; -    } - -    /* Check if any unknown options were used */ -    if (qdict_size(options) != 0) { -        const QDictEntry *entry = qdict_first(options); -        qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block protocol '%s' doesn't " -                      "support the option '%s'", -                      drv->format_name, entry->key); -        ret = -EINVAL; -        goto fail; -    } -    QDECREF(options); - -    bs->growable = 1; -    *pbs = bs; -    return 0; - -fail: -    QDECREF(options); -    if (!bs->drv) { -        QDECREF(bs->options); -    } -    bdrv_delete(bs); -    return ret; -} - -/* - * Opens the backing file for a BlockDriverState if not yet open - * - * options is a QDict of options to pass to the block drivers, or NULL for an - * empty set of options. The reference to the QDict is transferred to this - * function (even on failure), so if the caller intends to reuse the dictionary, - * it needs to use QINCREF() before calling bdrv_file_open. - */ -int bdrv_open_backing_file(BlockDriverState *bs, QDict *options) -{ -    char backing_filename[PATH_MAX]; -    int back_flags, ret; -    BlockDriver *back_drv = NULL; - -    if (bs->backing_hd != NULL) { -        QDECREF(options); -        return 0; -    } - -    /* NULL means an empty set of options */ -    if (options == NULL) { -        options = qdict_new(); -    } - -    bs->open_flags &= ~BDRV_O_NO_BACKING; -    if (qdict_haskey(options, "file.filename")) { -        backing_filename[0] = '\0'; -    } else if (bs->backing_file[0] == '\0' && qdict_size(options) == 0) { -        QDECREF(options); -        return 0; -    } - -    bs->backing_hd = bdrv_new(""); -    bdrv_get_full_backing_filename(bs, backing_filename, -                                   sizeof(backing_filename)); - -    if (bs->backing_format[0] != '\0') { -        back_drv = bdrv_find_format(bs->backing_format); -    } - -    /* backing files always opened read-only */ -    back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT); - -    ret = bdrv_open(bs->backing_hd, -                    *backing_filename ? backing_filename : NULL, options, -                    back_flags, back_drv); -    if (ret < 0) { -        bdrv_delete(bs->backing_hd); -        bs->backing_hd = NULL; -        bs->open_flags |= BDRV_O_NO_BACKING; -        return ret; -    } -    return 0; -} - -static void extract_subqdict(QDict *src, QDict **dst, const char *start) -{ -    const QDictEntry *entry, *next; -    const char *p; - -    *dst = qdict_new(); -    entry = qdict_first(src); - -    while (entry != NULL) { -        next = qdict_next(src, entry); -        if (strstart(entry->key, start, &p)) { -            qobject_incref(entry->value); -            qdict_put_obj(*dst, p, entry->value); -            qdict_del(src, entry->key); -        } -        entry = next; -    } -} - -/* - * Opens a disk image (raw, qcow2, vmdk, ...) - * - * options is a QDict of options to pass to the block drivers, or NULL for an - * empty set of options. The reference to the QDict belongs to the block layer - * after the call (even on failure), so if the caller intends to reuse the - * dictionary, it needs to use QINCREF() before calling bdrv_open. - */ -int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, -              int flags, BlockDriver *drv) -{ -    int ret; -    /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ -    char tmp_filename[PATH_MAX + 1]; -    BlockDriverState *file = NULL; -    QDict *file_options = NULL; - -    /* NULL means an empty set of options */ -    if (options == NULL) { -        options = qdict_new(); -    } - -    bs->options = options; -    options = qdict_clone_shallow(options); - -    /* For snapshot=on, create a temporary qcow2 overlay */ -    if (flags & BDRV_O_SNAPSHOT) { -        BlockDriverState *bs1; -        int64_t total_size; -        BlockDriver *bdrv_qcow2; -        QEMUOptionParameter *create_options; -        char backing_filename[PATH_MAX]; - -        if (qdict_size(options) != 0) { -            error_report("Can't use snapshot=on with driver-specific options"); -            ret = -EINVAL; -            goto fail; -        } -        assert(filename != NULL); - -        /* if snapshot, we create a temporary backing file and open it -           instead of opening 'filename' directly */ - -        /* if there is a backing file, use it */ -        bs1 = bdrv_new(""); -        ret = bdrv_open(bs1, filename, NULL, 0, drv); -        if (ret < 0) { -            bdrv_delete(bs1); -            goto fail; -        } -        total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK; - -        bdrv_delete(bs1); - -        ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename)); -        if (ret < 0) { -            goto fail; -        } - -        /* Real path is meaningless for protocols */ -        if (path_has_protocol(filename)) { -            snprintf(backing_filename, sizeof(backing_filename), -                     "%s", filename); -        } else if (!realpath(filename, backing_filename)) { -            ret = -errno; -            goto fail; -        } - -        bdrv_qcow2 = bdrv_find_format("qcow2"); -        create_options = parse_option_parameters("", bdrv_qcow2->create_options, -                                                 NULL); - -        set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size); -        set_option_parameter(create_options, BLOCK_OPT_BACKING_FILE, -                             backing_filename); -        if (drv) { -            set_option_parameter(create_options, BLOCK_OPT_BACKING_FMT, -                drv->format_name); -        } - -        ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options); -        free_option_parameters(create_options); -        if (ret < 0) { -            goto fail; -        } - -        filename = tmp_filename; -        drv = bdrv_qcow2; -        bs->is_temporary = 1; -    } - -    /* Open image file without format layer */ -    if (flags & BDRV_O_RDWR) { -        flags |= BDRV_O_ALLOW_RDWR; -    } - -    extract_subqdict(options, &file_options, "file."); - -    ret = bdrv_file_open(&file, filename, file_options, -                         bdrv_open_flags(bs, flags | BDRV_O_UNMAP)); -    if (ret < 0) { -        goto fail; -    } - -    /* Find the right image format driver */ -    if (!drv) { -        ret = find_image_format(file, filename, &drv); -    } - -    if (!drv) { -        goto unlink_and_fail; -    } - -    /* Open the image */ -    ret = bdrv_open_common(bs, file, options, flags, drv); -    if (ret < 0) { -        goto unlink_and_fail; -    } - -    if (bs->file != file) { -        bdrv_delete(file); -        file = NULL; -    } - -    /* If there is a backing file, use it */ -    if ((flags & BDRV_O_NO_BACKING) == 0) { -        QDict *backing_options; - -        extract_subqdict(options, &backing_options, "backing."); -        ret = bdrv_open_backing_file(bs, backing_options); -        if (ret < 0) { -            goto close_and_fail; -        } -    } - -    /* Check if any unknown options were used */ -    if (qdict_size(options) != 0) { -        const QDictEntry *entry = qdict_first(options); -        qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by " -            "device '%s' doesn't support the option '%s'", -            drv->format_name, bs->device_name, entry->key); - -        ret = -EINVAL; -        goto close_and_fail; -    } -    QDECREF(options); - -    if (!bdrv_key_required(bs)) { -        bdrv_dev_change_media_cb(bs, true); -    } - -    /* throttling disk I/O limits */ -    if (bs->io_limits_enabled) { -        bdrv_io_limits_enable(bs); -    } - -    return 0; - -unlink_and_fail: -    if (file != NULL) { -        bdrv_delete(file); -    } -    if (bs->is_temporary) { -        unlink(filename); -    } -fail: -    QDECREF(bs->options); -    QDECREF(options); -    bs->options = NULL; -    return ret; - -close_and_fail: -    bdrv_close(bs); -    QDECREF(options); -    return ret; -} - -typedef struct BlockReopenQueueEntry { -     bool prepared; -     BDRVReopenState state; -     QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry; -} BlockReopenQueueEntry; - -/* - * Adds a BlockDriverState to a simple queue for an atomic, transactional - * reopen of multiple devices. - * - * bs_queue can either be an existing BlockReopenQueue that has had QSIMPLE_INIT - * already performed, or alternatively may be NULL a new BlockReopenQueue will - * be created and initialized. This newly created BlockReopenQueue should be - * passed back in for subsequent calls that are intended to be of the same - * atomic 'set'. - * - * bs is the BlockDriverState to add to the reopen queue. - * - * flags contains the open flags for the associated bs - * - * returns a pointer to bs_queue, which is either the newly allocated - * bs_queue, or the existing bs_queue being used. - * - */ -BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue, -                                    BlockDriverState *bs, int flags) -{ -    assert(bs != NULL); - -    BlockReopenQueueEntry *bs_entry; -    if (bs_queue == NULL) { -        bs_queue = g_new0(BlockReopenQueue, 1); -        QSIMPLEQ_INIT(bs_queue); -    } - -    if (bs->file) { -        bdrv_reopen_queue(bs_queue, bs->file, flags); -    } - -    bs_entry = g_new0(BlockReopenQueueEntry, 1); -    QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry); - -    bs_entry->state.bs = bs; -    bs_entry->state.flags = flags; - -    return bs_queue; -} - -/* - * Reopen multiple BlockDriverStates atomically & transactionally. - * - * The queue passed in (bs_queue) must have been built up previous - * via bdrv_reopen_queue(). - * - * Reopens all BDS specified in the queue, with the appropriate - * flags.  All devices are prepared for reopen, and failure of any - * device will cause all device changes to be abandonded, and intermediate - * data cleaned up. - * - * If all devices prepare successfully, then the changes are committed - * to all devices. - * - */ -int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp) -{ -    int ret = -1; -    BlockReopenQueueEntry *bs_entry, *next; -    Error *local_err = NULL; - -    assert(bs_queue != NULL); - -    bdrv_drain_all(); - -    QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) { -        if (bdrv_reopen_prepare(&bs_entry->state, bs_queue, &local_err)) { -            error_propagate(errp, local_err); -            goto cleanup; -        } -        bs_entry->prepared = true; -    } - -    /* If we reach this point, we have success and just need to apply the -     * changes -     */ -    QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) { -        bdrv_reopen_commit(&bs_entry->state); -    } - -    ret = 0; - -cleanup: -    QSIMPLEQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) { -        if (ret && bs_entry->prepared) { -            bdrv_reopen_abort(&bs_entry->state); -        } -        g_free(bs_entry); -    } -    g_free(bs_queue); -    return ret; -} - - -/* Reopen a single BlockDriverState with the specified flags. */ -int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp) -{ -    int ret = -1; -    Error *local_err = NULL; -    BlockReopenQueue *queue = bdrv_reopen_queue(NULL, bs, bdrv_flags); - -    ret = bdrv_reopen_multiple(queue, &local_err); -    if (local_err != NULL) { -        error_propagate(errp, local_err); -    } -    return ret; -} - - -/* - * Prepares a BlockDriverState for reopen. All changes are staged in the - * 'opaque' field of the BDRVReopenState, which is used and allocated by - * the block driver layer .bdrv_reopen_prepare() - * - * bs is the BlockDriverState to reopen - * flags are the new open flags - * queue is the reopen queue - * - * Returns 0 on success, non-zero on error.  On error errp will be set - * as well. - * - * On failure, bdrv_reopen_abort() will be called to clean up any data. - * It is the responsibility of the caller to then call the abort() or - * commit() for any other BDS that have been left in a prepare() state - * - */ -int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, -                        Error **errp) -{ -    int ret = -1; -    Error *local_err = NULL; -    BlockDriver *drv; - -    assert(reopen_state != NULL); -    assert(reopen_state->bs->drv != NULL); -    drv = reopen_state->bs->drv; - -    /* if we are to stay read-only, do not allow permission change -     * to r/w */ -    if (!(reopen_state->bs->open_flags & BDRV_O_ALLOW_RDWR) && -        reopen_state->flags & BDRV_O_RDWR) { -        error_set(errp, QERR_DEVICE_IS_READ_ONLY, -                  reopen_state->bs->device_name); -        goto error; -    } - - -    ret = bdrv_flush(reopen_state->bs); -    if (ret) { -        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "Error (%s) flushing drive", -                  strerror(-ret)); -        goto error; -    } - -    if (drv->bdrv_reopen_prepare) { -        ret = drv->bdrv_reopen_prepare(reopen_state, queue, &local_err); -        if (ret) { -            if (local_err != NULL) { -                error_propagate(errp, local_err); -            } else { -                error_setg(errp, "failed while preparing to reopen image '%s'", -                           reopen_state->bs->filename); -            } -            goto error; -        } -    } else { -        /* It is currently mandatory to have a bdrv_reopen_prepare() -         * handler for each supported drv. */ -        error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, -                  drv->format_name, reopen_state->bs->device_name, -                 "reopening of file"); -        ret = -1; -        goto error; -    } - -    ret = 0; - -error: -    return ret; -} - -/* - * Takes the staged changes for the reopen from bdrv_reopen_prepare(), and - * makes them final by swapping the staging BlockDriverState contents into - * the active BlockDriverState contents. - */ -void bdrv_reopen_commit(BDRVReopenState *reopen_state) -{ -    BlockDriver *drv; - -    assert(reopen_state != NULL); -    drv = reopen_state->bs->drv; -    assert(drv != NULL); - -    /* If there are any driver level actions to take */ -    if (drv->bdrv_reopen_commit) { -        drv->bdrv_reopen_commit(reopen_state); -    } - -    /* set BDS specific flags now */ -    reopen_state->bs->open_flags         = reopen_state->flags; -    reopen_state->bs->enable_write_cache = !!(reopen_state->flags & -                                              BDRV_O_CACHE_WB); -    reopen_state->bs->read_only = !(reopen_state->flags & BDRV_O_RDWR); -} - -/* - * Abort the reopen, and delete and free the staged changes in - * reopen_state - */ -void bdrv_reopen_abort(BDRVReopenState *reopen_state) -{ -    BlockDriver *drv; - -    assert(reopen_state != NULL); -    drv = reopen_state->bs->drv; -    assert(drv != NULL); - -    if (drv->bdrv_reopen_abort) { -        drv->bdrv_reopen_abort(reopen_state); -    } -} - - -void bdrv_close(BlockDriverState *bs) -{ -    if (bs->job) { -        block_job_cancel_sync(bs->job); -    } -    bdrv_drain_all(); /* complete I/O */ -    bdrv_flush(bs); -    bdrv_drain_all(); /* in case flush left pending I/O */ -    notifier_list_notify(&bs->close_notifiers, bs); - -    if (bs->drv) { -        if (bs->backing_hd) { -            bdrv_delete(bs->backing_hd); -            bs->backing_hd = NULL; -        } -        bs->drv->bdrv_close(bs); -        g_free(bs->opaque); -#ifdef _WIN32 -        if (bs->is_temporary) { -            unlink(bs->filename); -        } -#endif -        bs->opaque = NULL; -        bs->drv = NULL; -        bs->copy_on_read = 0; -        bs->backing_file[0] = '\0'; -        bs->backing_format[0] = '\0'; -        bs->total_sectors = 0; -        bs->encrypted = 0; -        bs->valid_key = 0; -        bs->sg = 0; -        bs->growable = 0; -        QDECREF(bs->options); -        bs->options = NULL; - -        if (bs->file != NULL) { -            bdrv_delete(bs->file); -            bs->file = NULL; -        } -    } - -    bdrv_dev_change_media_cb(bs, false); - -    /*throttling disk I/O limits*/ -    if (bs->io_limits_enabled) { -        bdrv_io_limits_disable(bs); -    } -} - -void bdrv_close_all(void) -{ -    BlockDriverState *bs; - -    QTAILQ_FOREACH(bs, &bdrv_states, list) { -        bdrv_close(bs); -    } -} - -/* - * Wait for pending requests to complete across all BlockDriverStates - * - * This function does not flush data to disk, use bdrv_flush_all() for that - * after calling this function. - * - * Note that completion of an asynchronous I/O operation can trigger any - * number of other I/O operations on other devices---for example a coroutine - * can be arbitrarily complex and a constant flow of I/O can come until the - * coroutine is complete.  Because of this, it is not possible to have a - * function to drain a single device's I/O queue. - */ -void bdrv_drain_all(void) -{ -    BlockDriverState *bs; -    bool busy; - -    do { -        busy = qemu_aio_wait(); - -        /* FIXME: We do not have timer support here, so this is effectively -         * a busy wait. -         */ -        QTAILQ_FOREACH(bs, &bdrv_states, list) { -            if (!qemu_co_queue_empty(&bs->throttled_reqs)) { -                qemu_co_queue_restart_all(&bs->throttled_reqs); -                busy = true; -            } -        } -    } while (busy); - -    /* If requests are still pending there is a bug somewhere */ -    QTAILQ_FOREACH(bs, &bdrv_states, list) { -        assert(QLIST_EMPTY(&bs->tracked_requests)); -        assert(qemu_co_queue_empty(&bs->throttled_reqs)); -    } -} - -/* make a BlockDriverState anonymous by removing from bdrv_state list. -   Also, NULL terminate the device_name to prevent double remove */ -void bdrv_make_anon(BlockDriverState *bs) -{ -    if (bs->device_name[0] != '\0') { -        QTAILQ_REMOVE(&bdrv_states, bs, list); -    } -    bs->device_name[0] = '\0'; -} - -static void bdrv_rebind(BlockDriverState *bs) -{ -    if (bs->drv && bs->drv->bdrv_rebind) { -        bs->drv->bdrv_rebind(bs); -    } -} - -static void bdrv_move_feature_fields(BlockDriverState *bs_dest, -                                     BlockDriverState *bs_src) -{ -    /* move some fields that need to stay attached to the device */ -    bs_dest->open_flags         = bs_src->open_flags; - -    /* dev info */ -    bs_dest->dev_ops            = bs_src->dev_ops; -    bs_dest->dev_opaque         = bs_src->dev_opaque; -    bs_dest->dev                = bs_src->dev; -    bs_dest->buffer_alignment   = bs_src->buffer_alignment; -    bs_dest->copy_on_read       = bs_src->copy_on_read; - -    bs_dest->enable_write_cache = bs_src->enable_write_cache; - -    /* i/o timing parameters */ -    bs_dest->slice_start        = bs_src->slice_start; -    bs_dest->slice_end          = bs_src->slice_end; -    bs_dest->slice_submitted    = bs_src->slice_submitted; -    bs_dest->io_limits          = bs_src->io_limits; -    bs_dest->throttled_reqs     = bs_src->throttled_reqs; -    bs_dest->block_timer        = bs_src->block_timer; -    bs_dest->io_limits_enabled  = bs_src->io_limits_enabled; - -    /* r/w error */ -    bs_dest->on_read_error      = bs_src->on_read_error; -    bs_dest->on_write_error     = bs_src->on_write_error; - -    /* i/o status */ -    bs_dest->iostatus_enabled   = bs_src->iostatus_enabled; -    bs_dest->iostatus           = bs_src->iostatus; - -    /* dirty bitmap */ -    bs_dest->dirty_bitmap       = bs_src->dirty_bitmap; - -    /* job */ -    bs_dest->in_use             = bs_src->in_use; -    bs_dest->job                = bs_src->job; - -    /* keep the same entry in bdrv_states */ -    pstrcpy(bs_dest->device_name, sizeof(bs_dest->device_name), -            bs_src->device_name); -    bs_dest->list = bs_src->list; -} - -/* - * Swap bs contents for two image chains while they are live, - * while keeping required fields on the BlockDriverState that is - * actually attached to a device. - * - * This will modify the BlockDriverState fields, and swap contents - * between bs_new and bs_old. Both bs_new and bs_old are modified. - * - * bs_new is required to be anonymous. - * - * This function does not create any image files. - */ -void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old) -{ -    BlockDriverState tmp; - -    /* bs_new must be anonymous and shouldn't have anything fancy enabled */ -    assert(bs_new->device_name[0] == '\0'); -    assert(bs_new->dirty_bitmap == NULL); -    assert(bs_new->job == NULL); -    assert(bs_new->dev == NULL); -    assert(bs_new->in_use == 0); -    assert(bs_new->io_limits_enabled == false); -    assert(bs_new->block_timer == NULL); - -    tmp = *bs_new; -    *bs_new = *bs_old; -    *bs_old = tmp; - -    /* there are some fields that should not be swapped, move them back */ -    bdrv_move_feature_fields(&tmp, bs_old); -    bdrv_move_feature_fields(bs_old, bs_new); -    bdrv_move_feature_fields(bs_new, &tmp); - -    /* bs_new shouldn't be in bdrv_states even after the swap!  */ -    assert(bs_new->device_name[0] == '\0'); - -    /* Check a few fields that should remain attached to the device */ -    assert(bs_new->dev == NULL); -    assert(bs_new->job == NULL); -    assert(bs_new->in_use == 0); -    assert(bs_new->io_limits_enabled == false); -    assert(bs_new->block_timer == NULL); - -    bdrv_rebind(bs_new); -    bdrv_rebind(bs_old); -} - -/* - * Add new bs contents at the top of an image chain while the chain is - * live, while keeping required fields on the top layer. - * - * This will modify the BlockDriverState fields, and swap contents - * between bs_new and bs_top. Both bs_new and bs_top are modified. - * - * bs_new is required to be anonymous. - * - * This function does not create any image files. - */ -void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top) -{ -    bdrv_swap(bs_new, bs_top); - -    /* The contents of 'tmp' will become bs_top, as we are -     * swapping bs_new and bs_top contents. */ -    bs_top->backing_hd = bs_new; -    bs_top->open_flags &= ~BDRV_O_NO_BACKING; -    pstrcpy(bs_top->backing_file, sizeof(bs_top->backing_file), -            bs_new->filename); -    pstrcpy(bs_top->backing_format, sizeof(bs_top->backing_format), -            bs_new->drv ? bs_new->drv->format_name : ""); -} - -void bdrv_delete(BlockDriverState *bs) -{ -    assert(!bs->dev); -    assert(!bs->job); -    assert(!bs->in_use); - -    /* remove from list, if necessary */ -    bdrv_make_anon(bs); - -    bdrv_close(bs); - -    g_free(bs); -} - -int bdrv_attach_dev(BlockDriverState *bs, void *dev) -/* TODO change to DeviceState *dev when all users are qdevified */ -{ -    if (bs->dev) { -        return -EBUSY; -    } -    bs->dev = dev; -    bdrv_iostatus_reset(bs); -    return 0; -} - -/* TODO qdevified devices don't use this, remove when devices are qdevified */ -void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev) -{ -    if (bdrv_attach_dev(bs, dev) < 0) { -        abort(); -    } -} - -void bdrv_detach_dev(BlockDriverState *bs, void *dev) -/* TODO change to DeviceState *dev when all users are qdevified */ -{ -    assert(bs->dev == dev); -    bs->dev = NULL; -    bs->dev_ops = NULL; -    bs->dev_opaque = NULL; -    bs->buffer_alignment = 512; -} - -/* TODO change to return DeviceState * when all users are qdevified */ -void *bdrv_get_attached_dev(BlockDriverState *bs) -{ -    return bs->dev; -} - -void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, -                      void *opaque) -{ -    bs->dev_ops = ops; -    bs->dev_opaque = opaque; -} - -void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv, -                               enum MonitorEvent ev, -                               BlockErrorAction action, bool is_read) -{ -    QObject *data; -    const char *action_str; - -    switch (action) { -    case BDRV_ACTION_REPORT: -        action_str = "report"; -        break; -    case BDRV_ACTION_IGNORE: -        action_str = "ignore"; -        break; -    case BDRV_ACTION_STOP: -        action_str = "stop"; -        break; -    default: -        abort(); -    } - -    data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }", -                              bdrv->device_name, -                              action_str, -                              is_read ? "read" : "write"); -    monitor_protocol_event(ev, data); - -    qobject_decref(data); -} - -static void bdrv_emit_qmp_eject_event(BlockDriverState *bs, bool ejected) -{ -    QObject *data; - -    data = qobject_from_jsonf("{ 'device': %s, 'tray-open': %i }", -                              bdrv_get_device_name(bs), ejected); -    monitor_protocol_event(QEVENT_DEVICE_TRAY_MOVED, data); - -    qobject_decref(data); -} - -static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load) -{ -    if (bs->dev_ops && bs->dev_ops->change_media_cb) { -        bool tray_was_closed = !bdrv_dev_is_tray_open(bs); -        bs->dev_ops->change_media_cb(bs->dev_opaque, load); -        if (tray_was_closed) { -            /* tray open */ -            bdrv_emit_qmp_eject_event(bs, true); -        } -        if (load) { -            /* tray close */ -            bdrv_emit_qmp_eject_event(bs, false); -        } -    } -} - -bool bdrv_dev_has_removable_media(BlockDriverState *bs) -{ -    return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb); -} - -void bdrv_dev_eject_request(BlockDriverState *bs, bool force) -{ -    if (bs->dev_ops && bs->dev_ops->eject_request_cb) { -        bs->dev_ops->eject_request_cb(bs->dev_opaque, force); -    } -} - -bool bdrv_dev_is_tray_open(BlockDriverState *bs) -{ -    if (bs->dev_ops && bs->dev_ops->is_tray_open) { -        return bs->dev_ops->is_tray_open(bs->dev_opaque); -    } -    return false; -} - -static void bdrv_dev_resize_cb(BlockDriverState *bs) -{ -    if (bs->dev_ops && bs->dev_ops->resize_cb) { -        bs->dev_ops->resize_cb(bs->dev_opaque); -    } -} - -bool bdrv_dev_is_medium_locked(BlockDriverState *bs) -{ -    if (bs->dev_ops && bs->dev_ops->is_medium_locked) { -        return bs->dev_ops->is_medium_locked(bs->dev_opaque); -    } -    return false; -} - -/* - * Run consistency checks on an image - * - * Returns 0 if the check could be completed (it doesn't mean that the image is - * free of errors) or -errno when an internal error occurred. The results of the - * check are stored in res. - */ -int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix) -{ -    if (bs->drv->bdrv_check == NULL) { -        return -ENOTSUP; -    } - -    memset(res, 0, sizeof(*res)); -    return bs->drv->bdrv_check(bs, res, fix); -} - -#define COMMIT_BUF_SECTORS 2048 - -/* commit COW file into the raw image */ -int bdrv_commit(BlockDriverState *bs) -{ -    BlockDriver *drv = bs->drv; -    int64_t sector, total_sectors; -    int n, ro, open_flags; -    int ret = 0; -    uint8_t *buf; -    char filename[PATH_MAX]; - -    if (!drv) -        return -ENOMEDIUM; -     -    if (!bs->backing_hd) { -        return -ENOTSUP; -    } - -    if (bdrv_in_use(bs) || bdrv_in_use(bs->backing_hd)) { -        return -EBUSY; -    } - -    ro = bs->backing_hd->read_only; -    /* Use pstrcpy (not strncpy): filename must be NUL-terminated. */ -    pstrcpy(filename, sizeof(filename), bs->backing_hd->filename); -    open_flags =  bs->backing_hd->open_flags; - -    if (ro) { -        if (bdrv_reopen(bs->backing_hd, open_flags | BDRV_O_RDWR, NULL)) { -            return -EACCES; -        } -    } - -    total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; -    buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE); - -    for (sector = 0; sector < total_sectors; sector += n) { -        if (bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) { - -            if (bdrv_read(bs, sector, buf, n) != 0) { -                ret = -EIO; -                goto ro_cleanup; -            } - -            if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) { -                ret = -EIO; -                goto ro_cleanup; -            } -        } -    } - -    if (drv->bdrv_make_empty) { -        ret = drv->bdrv_make_empty(bs); -        bdrv_flush(bs); -    } - -    /* -     * Make sure all data we wrote to the backing device is actually -     * stable on disk. -     */ -    if (bs->backing_hd) -        bdrv_flush(bs->backing_hd); - -ro_cleanup: -    g_free(buf); - -    if (ro) { -        /* ignoring error return here */ -        bdrv_reopen(bs->backing_hd, open_flags & ~BDRV_O_RDWR, NULL); -    } - -    return ret; -} - -int bdrv_commit_all(void) -{ -    BlockDriverState *bs; - -    QTAILQ_FOREACH(bs, &bdrv_states, list) { -        if (bs->drv && bs->backing_hd) { -            int ret = bdrv_commit(bs); -            if (ret < 0) { -                return ret; -            } -        } -    } -    return 0; -} - -/** - * Remove an active request from the tracked requests list - * - * This function should be called when a tracked request is completing. - */ -static void tracked_request_end(BdrvTrackedRequest *req) -{ -    QLIST_REMOVE(req, list); -    qemu_co_queue_restart_all(&req->wait_queue); -} - -/** - * Add an active request to the tracked requests list - */ -static void tracked_request_begin(BdrvTrackedRequest *req, -                                  BlockDriverState *bs, -                                  int64_t sector_num, -                                  int nb_sectors, bool is_write) -{ -    *req = (BdrvTrackedRequest){ -        .bs = bs, -        .sector_num = sector_num, -        .nb_sectors = nb_sectors, -        .is_write = is_write, -        .co = qemu_coroutine_self(), -    }; - -    qemu_co_queue_init(&req->wait_queue); - -    QLIST_INSERT_HEAD(&bs->tracked_requests, req, list); -} - -/** - * Round a region to cluster boundaries - */ -void bdrv_round_to_clusters(BlockDriverState *bs, -                            int64_t sector_num, int nb_sectors, -                            int64_t *cluster_sector_num, -                            int *cluster_nb_sectors) -{ -    BlockDriverInfo bdi; - -    if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) { -        *cluster_sector_num = sector_num; -        *cluster_nb_sectors = nb_sectors; -    } else { -        int64_t c = bdi.cluster_size / BDRV_SECTOR_SIZE; -        *cluster_sector_num = QEMU_ALIGN_DOWN(sector_num, c); -        *cluster_nb_sectors = QEMU_ALIGN_UP(sector_num - *cluster_sector_num + -                                            nb_sectors, c); -    } -} - -static bool tracked_request_overlaps(BdrvTrackedRequest *req, -                                     int64_t sector_num, int nb_sectors) { -    /*        aaaa   bbbb */ -    if (sector_num >= req->sector_num + req->nb_sectors) { -        return false; -    } -    /* bbbb   aaaa        */ -    if (req->sector_num >= sector_num + nb_sectors) { -        return false; -    } -    return true; -} - -static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors) -{ -    BdrvTrackedRequest *req; -    int64_t cluster_sector_num; -    int cluster_nb_sectors; -    bool retry; - -    /* If we touch the same cluster it counts as an overlap.  This guarantees -     * that allocating writes will be serialized and not race with each other -     * for the same cluster.  For example, in copy-on-read it ensures that the -     * CoR read and write operations are atomic and guest writes cannot -     * interleave between them. -     */ -    bdrv_round_to_clusters(bs, sector_num, nb_sectors, -                           &cluster_sector_num, &cluster_nb_sectors); - -    do { -        retry = false; -        QLIST_FOREACH(req, &bs->tracked_requests, list) { -            if (tracked_request_overlaps(req, cluster_sector_num, -                                         cluster_nb_sectors)) { -                /* Hitting this means there was a reentrant request, for -                 * example, a block driver issuing nested requests.  This must -                 * never happen since it means deadlock. -                 */ -                assert(qemu_coroutine_self() != req->co); - -                qemu_co_queue_wait(&req->wait_queue); -                retry = true; -                break; -            } -        } -    } while (retry); -} - -/* - * Return values: - * 0        - success - * -EINVAL  - backing format specified, but no file - * -ENOSPC  - can't update the backing file because no space is left in the - *            image file header - * -ENOTSUP - format driver doesn't support changing the backing file - */ -int bdrv_change_backing_file(BlockDriverState *bs, -    const char *backing_file, const char *backing_fmt) -{ -    BlockDriver *drv = bs->drv; -    int ret; - -    /* Backing file format doesn't make sense without a backing file */ -    if (backing_fmt && !backing_file) { -        return -EINVAL; -    } - -    if (drv->bdrv_change_backing_file != NULL) { -        ret = drv->bdrv_change_backing_file(bs, backing_file, backing_fmt); -    } else { -        ret = -ENOTSUP; -    } - -    if (ret == 0) { -        pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_file ?: ""); -        pstrcpy(bs->backing_format, sizeof(bs->backing_format), backing_fmt ?: ""); -    } -    return ret; -} - -/* - * Finds the image layer in the chain that has 'bs' as its backing file. - * - * active is the current topmost image. - * - * Returns NULL if bs is not found in active's image chain, - * or if active == bs. - */ -BlockDriverState *bdrv_find_overlay(BlockDriverState *active, -                                    BlockDriverState *bs) -{ -    BlockDriverState *overlay = NULL; -    BlockDriverState *intermediate; - -    assert(active != NULL); -    assert(bs != NULL); - -    /* if bs is the same as active, then by definition it has no overlay -     */ -    if (active == bs) { -        return NULL; -    } - -    intermediate = active; -    while (intermediate->backing_hd) { -        if (intermediate->backing_hd == bs) { -            overlay = intermediate; -            break; -        } -        intermediate = intermediate->backing_hd; -    } - -    return overlay; -} - -typedef struct BlkIntermediateStates { -    BlockDriverState *bs; -    QSIMPLEQ_ENTRY(BlkIntermediateStates) entry; -} BlkIntermediateStates; - - -/* - * Drops images above 'base' up to and including 'top', and sets the image - * above 'top' to have base as its backing file. - * - * Requires that the overlay to 'top' is opened r/w, so that the backing file - * information in 'bs' can be properly updated. - * - * E.g., this will convert the following chain: - * bottom <- base <- intermediate <- top <- active - * - * to - * - * bottom <- base <- active - * - * It is allowed for bottom==base, in which case it converts: - * - * base <- intermediate <- top <- active - * - * to - * - * base <- active - * - * Error conditions: - *  if active == top, that is considered an error - * - */ -int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top, -                           BlockDriverState *base) -{ -    BlockDriverState *intermediate; -    BlockDriverState *base_bs = NULL; -    BlockDriverState *new_top_bs = NULL; -    BlkIntermediateStates *intermediate_state, *next; -    int ret = -EIO; - -    QSIMPLEQ_HEAD(states_to_delete, BlkIntermediateStates) states_to_delete; -    QSIMPLEQ_INIT(&states_to_delete); - -    if (!top->drv || !base->drv) { -        goto exit; -    } - -    new_top_bs = bdrv_find_overlay(active, top); - -    if (new_top_bs == NULL) { -        /* we could not find the image above 'top', this is an error */ -        goto exit; -    } - -    /* special case of new_top_bs->backing_hd already pointing to base - nothing -     * to do, no intermediate images */ -    if (new_top_bs->backing_hd == base) { -        ret = 0; -        goto exit; -    } - -    intermediate = top; - -    /* now we will go down through the list, and add each BDS we find -     * into our deletion queue, until we hit the 'base' -     */ -    while (intermediate) { -        intermediate_state = g_malloc0(sizeof(BlkIntermediateStates)); -        intermediate_state->bs = intermediate; -        QSIMPLEQ_INSERT_TAIL(&states_to_delete, intermediate_state, entry); - -        if (intermediate->backing_hd == base) { -            base_bs = intermediate->backing_hd; -            break; -        } -        intermediate = intermediate->backing_hd; -    } -    if (base_bs == NULL) { -        /* something went wrong, we did not end at the base. safely -         * unravel everything, and exit with error */ -        goto exit; -    } - -    /* success - we can delete the intermediate states, and link top->base */ -    ret = bdrv_change_backing_file(new_top_bs, base_bs->filename, -                                   base_bs->drv ? base_bs->drv->format_name : ""); -    if (ret) { -        goto exit; -    } -    new_top_bs->backing_hd = base_bs; - - -    QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, next) { -        /* so that bdrv_close() does not recursively close the chain */ -        intermediate_state->bs->backing_hd = NULL; -        bdrv_delete(intermediate_state->bs); -    } -    ret = 0; - -exit: -    QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, next) { -        g_free(intermediate_state); -    } -    return ret; -} - - -static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset, -                                   size_t size) -{ -    int64_t len; - -    if (!bdrv_is_inserted(bs)) -        return -ENOMEDIUM; - -    if (bs->growable) -        return 0; - -    len = bdrv_getlength(bs); - -    if (offset < 0) -        return -EIO; - -    if ((offset > len) || (len - offset < size)) -        return -EIO; - -    return 0; -} - -static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num, -                              int nb_sectors) -{ -    return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE, -                                   nb_sectors * BDRV_SECTOR_SIZE); -} - -typedef struct RwCo { -    BlockDriverState *bs; -    int64_t sector_num; -    int nb_sectors; -    QEMUIOVector *qiov; -    bool is_write; -    int ret; -} RwCo; - -static void coroutine_fn bdrv_rw_co_entry(void *opaque) -{ -    RwCo *rwco = opaque; - -    if (!rwco->is_write) { -        rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num, -                                     rwco->nb_sectors, rwco->qiov, 0); -    } else { -        rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num, -                                      rwco->nb_sectors, rwco->qiov, 0); -    } -} - -/* - * Process a vectored synchronous request using coroutines - */ -static int bdrv_rwv_co(BlockDriverState *bs, int64_t sector_num, -                       QEMUIOVector *qiov, bool is_write) -{ -    Coroutine *co; -    RwCo rwco = { -        .bs = bs, -        .sector_num = sector_num, -        .nb_sectors = qiov->size >> BDRV_SECTOR_BITS, -        .qiov = qiov, -        .is_write = is_write, -        .ret = NOT_DONE, -    }; -    assert((qiov->size & (BDRV_SECTOR_SIZE - 1)) == 0); - -    /** -     * In sync call context, when the vcpu is blocked, this throttling timer -     * will not fire; so the I/O throttling function has to be disabled here -     * if it has been enabled. -     */ -    if (bs->io_limits_enabled) { -        fprintf(stderr, "Disabling I/O throttling on '%s' due " -                        "to synchronous I/O.\n", bdrv_get_device_name(bs)); -        bdrv_io_limits_disable(bs); -    } - -    if (qemu_in_coroutine()) { -        /* Fast-path if already in coroutine context */ -        bdrv_rw_co_entry(&rwco); -    } else { -        co = qemu_coroutine_create(bdrv_rw_co_entry); -        qemu_coroutine_enter(co, &rwco); -        while (rwco.ret == NOT_DONE) { -            qemu_aio_wait(); -        } -    } -    return rwco.ret; -} - -/* - * Process a synchronous request using coroutines - */ -static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, -                      int nb_sectors, bool is_write) -{ -    QEMUIOVector qiov; -    struct iovec iov = { -        .iov_base = (void *)buf, -        .iov_len = nb_sectors * BDRV_SECTOR_SIZE, -    }; - -    qemu_iovec_init_external(&qiov, &iov, 1); -    return bdrv_rwv_co(bs, sector_num, &qiov, is_write); -} - -/* return < 0 if error. See bdrv_write() for the return codes */ -int bdrv_read(BlockDriverState *bs, int64_t sector_num, -              uint8_t *buf, int nb_sectors) -{ -    return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false); -} - -/* Just like bdrv_read(), but with I/O throttling temporarily disabled */ -int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num, -                          uint8_t *buf, int nb_sectors) -{ -    bool enabled; -    int ret; - -    enabled = bs->io_limits_enabled; -    bs->io_limits_enabled = false; -    ret = bdrv_read(bs, 0, buf, 1); -    bs->io_limits_enabled = enabled; -    return ret; -} - -/* Return < 0 if error. Important errors are: -  -EIO         generic I/O error (may happen for all errors) -  -ENOMEDIUM   No media inserted. -  -EINVAL      Invalid sector number or nb_sectors -  -EACCES      Trying to write a read-only device -*/ -int bdrv_write(BlockDriverState *bs, int64_t sector_num, -               const uint8_t *buf, int nb_sectors) -{ -    return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true); -} - -int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov) -{ -    return bdrv_rwv_co(bs, sector_num, qiov, true); -} - -int bdrv_pread(BlockDriverState *bs, int64_t offset, -               void *buf, int count1) -{ -    uint8_t tmp_buf[BDRV_SECTOR_SIZE]; -    int len, nb_sectors, count; -    int64_t sector_num; -    int ret; - -    count = count1; -    /* first read to align to sector start */ -    len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); -    if (len > count) -        len = count; -    sector_num = offset >> BDRV_SECTOR_BITS; -    if (len > 0) { -        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) -            return ret; -        memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len); -        count -= len; -        if (count == 0) -            return count1; -        sector_num++; -        buf += len; -    } - -    /* read the sectors "in place" */ -    nb_sectors = count >> BDRV_SECTOR_BITS; -    if (nb_sectors > 0) { -        if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0) -            return ret; -        sector_num += nb_sectors; -        len = nb_sectors << BDRV_SECTOR_BITS; -        buf += len; -        count -= len; -    } - -    /* add data from the last sector */ -    if (count > 0) { -        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) -            return ret; -        memcpy(buf, tmp_buf, count); -    } -    return count1; -} - -int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov) -{ -    uint8_t tmp_buf[BDRV_SECTOR_SIZE]; -    int len, nb_sectors, count; -    int64_t sector_num; -    int ret; - -    count = qiov->size; - -    /* first write to align to sector start */ -    len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); -    if (len > count) -        len = count; -    sector_num = offset >> BDRV_SECTOR_BITS; -    if (len > 0) { -        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) -            return ret; -        qemu_iovec_to_buf(qiov, 0, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), -                          len); -        if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) -            return ret; -        count -= len; -        if (count == 0) -            return qiov->size; -        sector_num++; -    } - -    /* write the sectors "in place" */ -    nb_sectors = count >> BDRV_SECTOR_BITS; -    if (nb_sectors > 0) { -        QEMUIOVector qiov_inplace; - -        qemu_iovec_init(&qiov_inplace, qiov->niov); -        qemu_iovec_concat(&qiov_inplace, qiov, len, -                          nb_sectors << BDRV_SECTOR_BITS); -        ret = bdrv_writev(bs, sector_num, &qiov_inplace); -        qemu_iovec_destroy(&qiov_inplace); -        if (ret < 0) { -            return ret; -        } - -        sector_num += nb_sectors; -        len = nb_sectors << BDRV_SECTOR_BITS; -        count -= len; -    } - -    /* add data from the last sector */ -    if (count > 0) { -        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0) -            return ret; -        qemu_iovec_to_buf(qiov, qiov->size - count, tmp_buf, count); -        if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0) -            return ret; -    } -    return qiov->size; -} - -int bdrv_pwrite(BlockDriverState *bs, int64_t offset, -                const void *buf, int count1) -{ -    QEMUIOVector qiov; -    struct iovec iov = { -        .iov_base   = (void *) buf, -        .iov_len    = count1, -    }; - -    qemu_iovec_init_external(&qiov, &iov, 1); -    return bdrv_pwritev(bs, offset, &qiov); -} - -/* - * Writes to the file and ensures that no writes are reordered across this - * request (acts as a barrier) - * - * Returns 0 on success, -errno in error cases. - */ -int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, -    const void *buf, int count) -{ -    int ret; - -    ret = bdrv_pwrite(bs, offset, buf, count); -    if (ret < 0) { -        return ret; -    } - -    /* No flush needed for cache modes that already do it */ -    if (bs->enable_write_cache) { -        bdrv_flush(bs); -    } - -    return 0; -} - -static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) -{ -    /* Perform I/O through a temporary buffer so that users who scribble over -     * their read buffer while the operation is in progress do not end up -     * modifying the image file.  This is critical for zero-copy guest I/O -     * where anything might happen inside guest memory. -     */ -    void *bounce_buffer; - -    BlockDriver *drv = bs->drv; -    struct iovec iov; -    QEMUIOVector bounce_qiov; -    int64_t cluster_sector_num; -    int cluster_nb_sectors; -    size_t skip_bytes; -    int ret; - -    /* Cover entire cluster so no additional backing file I/O is required when -     * allocating cluster in the image file. -     */ -    bdrv_round_to_clusters(bs, sector_num, nb_sectors, -                           &cluster_sector_num, &cluster_nb_sectors); - -    trace_bdrv_co_do_copy_on_readv(bs, sector_num, nb_sectors, -                                   cluster_sector_num, cluster_nb_sectors); - -    iov.iov_len = cluster_nb_sectors * BDRV_SECTOR_SIZE; -    iov.iov_base = bounce_buffer = qemu_blockalign(bs, iov.iov_len); -    qemu_iovec_init_external(&bounce_qiov, &iov, 1); - -    ret = drv->bdrv_co_readv(bs, cluster_sector_num, cluster_nb_sectors, -                             &bounce_qiov); -    if (ret < 0) { -        goto err; -    } - -    if (drv->bdrv_co_write_zeroes && -        buffer_is_zero(bounce_buffer, iov.iov_len)) { -        ret = bdrv_co_do_write_zeroes(bs, cluster_sector_num, -                                      cluster_nb_sectors); -    } else { -        /* This does not change the data on the disk, it is not necessary -         * to flush even in cache=writethrough mode. -         */ -        ret = drv->bdrv_co_writev(bs, cluster_sector_num, cluster_nb_sectors, -                                  &bounce_qiov); -    } - -    if (ret < 0) { -        /* It might be okay to ignore write errors for guest requests.  If this -         * is a deliberate copy-on-read then we don't want to ignore the error. -         * Simply report it in all cases. -         */ -        goto err; -    } - -    skip_bytes = (sector_num - cluster_sector_num) * BDRV_SECTOR_SIZE; -    qemu_iovec_from_buf(qiov, 0, bounce_buffer + skip_bytes, -                        nb_sectors * BDRV_SECTOR_SIZE); - -err: -    qemu_vfree(bounce_buffer); -    return ret; -} - -/* - * Handle a read request in coroutine context - */ -static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, -    BdrvRequestFlags flags) -{ -    BlockDriver *drv = bs->drv; -    BdrvTrackedRequest req; -    int ret; - -    if (!drv) { -        return -ENOMEDIUM; -    } -    if (bdrv_check_request(bs, sector_num, nb_sectors)) { -        return -EIO; -    } - -    /* throttling disk read I/O */ -    if (bs->io_limits_enabled) { -        bdrv_io_limits_intercept(bs, false, nb_sectors); -    } - -    if (bs->copy_on_read) { -        flags |= BDRV_REQ_COPY_ON_READ; -    } -    if (flags & BDRV_REQ_COPY_ON_READ) { -        bs->copy_on_read_in_flight++; -    } - -    if (bs->copy_on_read_in_flight) { -        wait_for_overlapping_requests(bs, sector_num, nb_sectors); -    } - -    tracked_request_begin(&req, bs, sector_num, nb_sectors, false); - -    if (flags & BDRV_REQ_COPY_ON_READ) { -        int pnum; - -        ret = bdrv_co_is_allocated(bs, sector_num, nb_sectors, &pnum); -        if (ret < 0) { -            goto out; -        } - -        if (!ret || pnum != nb_sectors) { -            ret = bdrv_co_do_copy_on_readv(bs, sector_num, nb_sectors, qiov); -            goto out; -        } -    } - -    ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); - -out: -    tracked_request_end(&req); - -    if (flags & BDRV_REQ_COPY_ON_READ) { -        bs->copy_on_read_in_flight--; -    } - -    return ret; -} - -int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, -    int nb_sectors, QEMUIOVector *qiov) -{ -    trace_bdrv_co_readv(bs, sector_num, nb_sectors); - -    return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov, 0); -} - -int coroutine_fn bdrv_co_copy_on_readv(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) -{ -    trace_bdrv_co_copy_on_readv(bs, sector_num, nb_sectors); - -    return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov, -                            BDRV_REQ_COPY_ON_READ); -} - -static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors) -{ -    BlockDriver *drv = bs->drv; -    QEMUIOVector qiov; -    struct iovec iov; -    int ret; - -    /* TODO Emulate only part of misaligned requests instead of letting block -     * drivers return -ENOTSUP and emulate everything */ - -    /* First try the efficient write zeroes operation */ -    if (drv->bdrv_co_write_zeroes) { -        ret = drv->bdrv_co_write_zeroes(bs, sector_num, nb_sectors); -        if (ret != -ENOTSUP) { -            return ret; -        } -    } - -    /* Fall back to bounce buffer if write zeroes is unsupported */ -    iov.iov_len  = nb_sectors * BDRV_SECTOR_SIZE; -    iov.iov_base = qemu_blockalign(bs, iov.iov_len); -    memset(iov.iov_base, 0, iov.iov_len); -    qemu_iovec_init_external(&qiov, &iov, 1); - -    ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, &qiov); - -    qemu_vfree(iov.iov_base); -    return ret; -} - -/* - * Handle a write request in coroutine context - */ -static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, -    BdrvRequestFlags flags) -{ -    BlockDriver *drv = bs->drv; -    BdrvTrackedRequest req; -    int ret; - -    if (!bs->drv) { -        return -ENOMEDIUM; -    } -    if (bs->read_only) { -        return -EACCES; -    } -    if (bdrv_check_request(bs, sector_num, nb_sectors)) { -        return -EIO; -    } - -    /* throttling disk write I/O */ -    if (bs->io_limits_enabled) { -        bdrv_io_limits_intercept(bs, true, nb_sectors); -    } - -    if (bs->copy_on_read_in_flight) { -        wait_for_overlapping_requests(bs, sector_num, nb_sectors); -    } - -    tracked_request_begin(&req, bs, sector_num, nb_sectors, true); - -    ret = notifier_with_return_list_notify(&bs->before_write_notifiers, &req); - -    if (ret < 0) { -        /* Do nothing, write notifier decided to fail this request */ -    } else if (flags & BDRV_REQ_ZERO_WRITE) { -        ret = bdrv_co_do_write_zeroes(bs, sector_num, nb_sectors); -    } else { -        ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); -    } - -    if (ret == 0 && !bs->enable_write_cache) { -        ret = bdrv_co_flush(bs); -    } - -    if (bs->dirty_bitmap) { -        bdrv_set_dirty(bs, sector_num, nb_sectors); -    } - -    if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { -        bs->wr_highest_sector = sector_num + nb_sectors - 1; -    } - -    tracked_request_end(&req); - -    return ret; -} - -int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, -    int nb_sectors, QEMUIOVector *qiov) -{ -    trace_bdrv_co_writev(bs, sector_num, nb_sectors); - -    return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov, 0); -} - -int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, -                                      int64_t sector_num, int nb_sectors) -{ -    trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors); - -    return bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL, -                             BDRV_REQ_ZERO_WRITE); -} - -/** - * Truncate file to 'offset' bytes (needed only for file protocols) - */ -int bdrv_truncate(BlockDriverState *bs, int64_t offset) -{ -    BlockDriver *drv = bs->drv; -    int ret; -    if (!drv) -        return -ENOMEDIUM; -    if (!drv->bdrv_truncate) -        return -ENOTSUP; -    if (bs->read_only) -        return -EACCES; -    if (bdrv_in_use(bs)) -        return -EBUSY; -    ret = drv->bdrv_truncate(bs, offset); -    if (ret == 0) { -        ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); -        bdrv_dev_resize_cb(bs); -    } -    return ret; -} - -/** - * Length of a allocated file in bytes. Sparse files are counted by actual - * allocated space. Return < 0 if error or unknown. - */ -int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) -{ -    BlockDriver *drv = bs->drv; -    if (!drv) { -        return -ENOMEDIUM; -    } -    if (drv->bdrv_get_allocated_file_size) { -        return drv->bdrv_get_allocated_file_size(bs); -    } -    if (bs->file) { -        return bdrv_get_allocated_file_size(bs->file); -    } -    return -ENOTSUP; -} - -/** - * Length of a file in bytes. Return < 0 if error or unknown. - */ -int64_t bdrv_getlength(BlockDriverState *bs) -{ -    BlockDriver *drv = bs->drv; -    if (!drv) -        return -ENOMEDIUM; - -    if (bs->growable || bdrv_dev_has_removable_media(bs)) { -        if (drv->bdrv_getlength) { -            return drv->bdrv_getlength(bs); -        } -    } -    return bs->total_sectors * BDRV_SECTOR_SIZE; -} - -/* return 0 as number of sectors if no device present or error */ -void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) -{ -    int64_t length; -    length = bdrv_getlength(bs); -    if (length < 0) -        length = 0; -    else -        length = length >> BDRV_SECTOR_BITS; -    *nb_sectors_ptr = length; -} - -/* throttling disk io limits */ -void bdrv_set_io_limits(BlockDriverState *bs, -                        BlockIOLimit *io_limits) -{ -    bs->io_limits = *io_limits; -    bs->io_limits_enabled = bdrv_io_limits_enabled(bs); -} - -void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error, -                       BlockdevOnError on_write_error) -{ -    bs->on_read_error = on_read_error; -    bs->on_write_error = on_write_error; -} - -BlockdevOnError bdrv_get_on_error(BlockDriverState *bs, bool is_read) -{ -    return is_read ? bs->on_read_error : bs->on_write_error; -} - -BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int error) -{ -    BlockdevOnError on_err = is_read ? bs->on_read_error : bs->on_write_error; - -    switch (on_err) { -    case BLOCKDEV_ON_ERROR_ENOSPC: -        return (error == ENOSPC) ? BDRV_ACTION_STOP : BDRV_ACTION_REPORT; -    case BLOCKDEV_ON_ERROR_STOP: -        return BDRV_ACTION_STOP; -    case BLOCKDEV_ON_ERROR_REPORT: -        return BDRV_ACTION_REPORT; -    case BLOCKDEV_ON_ERROR_IGNORE: -        return BDRV_ACTION_IGNORE; -    default: -        abort(); -    } -} - -/* This is done by device models because, while the block layer knows - * about the error, it does not know whether an operation comes from - * the device or the block layer (from a job, for example). - */ -void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action, -                       bool is_read, int error) -{ -    assert(error >= 0); -    bdrv_emit_qmp_error_event(bs, QEVENT_BLOCK_IO_ERROR, action, is_read); -    if (action == BDRV_ACTION_STOP) { -        vm_stop(RUN_STATE_IO_ERROR); -        bdrv_iostatus_set_err(bs, error); -    } -} - -int bdrv_is_read_only(BlockDriverState *bs) -{ -    return bs->read_only; -} - -int bdrv_is_sg(BlockDriverState *bs) -{ -    return bs->sg; -} - -int bdrv_enable_write_cache(BlockDriverState *bs) -{ -    return bs->enable_write_cache; -} - -void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce) -{ -    bs->enable_write_cache = wce; - -    /* so a reopen() will preserve wce */ -    if (wce) { -        bs->open_flags |= BDRV_O_CACHE_WB; -    } else { -        bs->open_flags &= ~BDRV_O_CACHE_WB; -    } -} - -int bdrv_is_encrypted(BlockDriverState *bs) -{ -    if (bs->backing_hd && bs->backing_hd->encrypted) -        return 1; -    return bs->encrypted; -} - -int bdrv_key_required(BlockDriverState *bs) -{ -    BlockDriverState *backing_hd = bs->backing_hd; - -    if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key) -        return 1; -    return (bs->encrypted && !bs->valid_key); -} - -int bdrv_set_key(BlockDriverState *bs, const char *key) -{ -    int ret; -    if (bs->backing_hd && bs->backing_hd->encrypted) { -        ret = bdrv_set_key(bs->backing_hd, key); -        if (ret < 0) -            return ret; -        if (!bs->encrypted) -            return 0; -    } -    if (!bs->encrypted) { -        return -EINVAL; -    } else if (!bs->drv || !bs->drv->bdrv_set_key) { -        return -ENOMEDIUM; -    } -    ret = bs->drv->bdrv_set_key(bs, key); -    if (ret < 0) { -        bs->valid_key = 0; -    } else if (!bs->valid_key) { -        bs->valid_key = 1; -        /* call the change callback now, we skipped it on open */ -        bdrv_dev_change_media_cb(bs, true); -    } -    return ret; -} - -const char *bdrv_get_format_name(BlockDriverState *bs) -{ -    return bs->drv ? bs->drv->format_name : NULL; -} - -void bdrv_iterate_format(void (*it)(void *opaque, const char *name), -                         void *opaque) -{ -    BlockDriver *drv; - -    QLIST_FOREACH(drv, &bdrv_drivers, list) { -        it(opaque, drv->format_name); -    } -} - -BlockDriverState *bdrv_find(const char *name) -{ -    BlockDriverState *bs; - -    QTAILQ_FOREACH(bs, &bdrv_states, list) { -        if (!strcmp(name, bs->device_name)) { -            return bs; -        } -    } -    return NULL; -} - -BlockDriverState *bdrv_next(BlockDriverState *bs) -{ -    if (!bs) { -        return QTAILQ_FIRST(&bdrv_states); -    } -    return QTAILQ_NEXT(bs, list); -} - -void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) -{ -    BlockDriverState *bs; - -    QTAILQ_FOREACH(bs, &bdrv_states, list) { -        it(opaque, bs); -    } -} - -const char *bdrv_get_device_name(BlockDriverState *bs) -{ -    return bs->device_name; -} - -int bdrv_get_flags(BlockDriverState *bs) -{ -    return bs->open_flags; -} - -int bdrv_flush_all(void) -{ -    BlockDriverState *bs; -    int result = 0; - -    QTAILQ_FOREACH(bs, &bdrv_states, list) { -        int ret = bdrv_flush(bs); -        if (ret < 0 && !result) { -            result = ret; -        } -    } - -    return result; -} - -int bdrv_has_zero_init_1(BlockDriverState *bs) -{ -    return 1; -} - -int bdrv_has_zero_init(BlockDriverState *bs) -{ -    assert(bs->drv); - -    if (bs->drv->bdrv_has_zero_init) { -        return bs->drv->bdrv_has_zero_init(bs); -    } - -    /* safe default */ -    return 0; -} - -typedef struct BdrvCoIsAllocatedData { -    BlockDriverState *bs; -    BlockDriverState *base; -    int64_t sector_num; -    int nb_sectors; -    int *pnum; -    int ret; -    bool done; -} BdrvCoIsAllocatedData; - -/* - * Returns true iff the specified sector is present in the disk image. Drivers - * not implementing the functionality are assumed to not support backing files, - * hence all their sectors are reported as allocated. - * - * If 'sector_num' is beyond the end of the disk image the return value is 0 - * and 'pnum' is set to 0. - * - * 'pnum' is set to the number of sectors (including and immediately following - * the specified sector) that are known to be in the same - * allocated/unallocated state. - * - * 'nb_sectors' is the max value 'pnum' should be set to.  If nb_sectors goes - * beyond the end of the disk image it will be clamped. - */ -int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num, -                                      int nb_sectors, int *pnum) -{ -    int64_t n; - -    if (sector_num >= bs->total_sectors) { -        *pnum = 0; -        return 0; -    } - -    n = bs->total_sectors - sector_num; -    if (n < nb_sectors) { -        nb_sectors = n; -    } - -    if (!bs->drv->bdrv_co_is_allocated) { -        *pnum = nb_sectors; -        return 1; -    } - -    return bs->drv->bdrv_co_is_allocated(bs, sector_num, nb_sectors, pnum); -} - -/* Coroutine wrapper for bdrv_is_allocated() */ -static void coroutine_fn bdrv_is_allocated_co_entry(void *opaque) -{ -    BdrvCoIsAllocatedData *data = opaque; -    BlockDriverState *bs = data->bs; - -    data->ret = bdrv_co_is_allocated(bs, data->sector_num, data->nb_sectors, -                                     data->pnum); -    data->done = true; -} - -/* - * Synchronous wrapper around bdrv_co_is_allocated(). - * - * See bdrv_co_is_allocated() for details. - */ -int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, -                      int *pnum) -{ -    Coroutine *co; -    BdrvCoIsAllocatedData data = { -        .bs = bs, -        .sector_num = sector_num, -        .nb_sectors = nb_sectors, -        .pnum = pnum, -        .done = false, -    }; - -    co = qemu_coroutine_create(bdrv_is_allocated_co_entry); -    qemu_coroutine_enter(co, &data); -    while (!data.done) { -        qemu_aio_wait(); -    } -    return data.ret; -} - -/* - * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP] - * - * Return true if the given sector is allocated in any image between - * BASE and TOP (inclusive).  BASE can be NULL to check if the given - * sector is allocated in any image of the chain.  Return false otherwise. - * - * 'pnum' is set to the number of sectors (including and immediately following - *  the specified sector) that are known to be in the same - *  allocated/unallocated state. - * - */ -int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, -                                            BlockDriverState *base, -                                            int64_t sector_num, -                                            int nb_sectors, int *pnum) -{ -    BlockDriverState *intermediate; -    int ret, n = nb_sectors; - -    intermediate = top; -    while (intermediate && intermediate != base) { -        int pnum_inter; -        ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors, -                                   &pnum_inter); -        if (ret < 0) { -            return ret; -        } else if (ret) { -            *pnum = pnum_inter; -            return 1; -        } - -        /* -         * [sector_num, nb_sectors] is unallocated on top but intermediate -         * might have -         * -         * [sector_num+x, nr_sectors] allocated. -         */ -        if (n > pnum_inter && -            (intermediate == top || -             sector_num + pnum_inter < intermediate->total_sectors)) { -            n = pnum_inter; -        } - -        intermediate = intermediate->backing_hd; -    } - -    *pnum = n; -    return 0; -} - -/* Coroutine wrapper for bdrv_is_allocated_above() */ -static void coroutine_fn bdrv_is_allocated_above_co_entry(void *opaque) -{ -    BdrvCoIsAllocatedData *data = opaque; -    BlockDriverState *top = data->bs; -    BlockDriverState *base = data->base; - -    data->ret = bdrv_co_is_allocated_above(top, base, data->sector_num, -                                           data->nb_sectors, data->pnum); -    data->done = true; -} - -/* - * Synchronous wrapper around bdrv_co_is_allocated_above(). - * - * See bdrv_co_is_allocated_above() for details. - */ -int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base, -                            int64_t sector_num, int nb_sectors, int *pnum) -{ -    Coroutine *co; -    BdrvCoIsAllocatedData data = { -        .bs = top, -        .base = base, -        .sector_num = sector_num, -        .nb_sectors = nb_sectors, -        .pnum = pnum, -        .done = false, -    }; - -    co = qemu_coroutine_create(bdrv_is_allocated_above_co_entry); -    qemu_coroutine_enter(co, &data); -    while (!data.done) { -        qemu_aio_wait(); -    } -    return data.ret; -} - -const char *bdrv_get_encrypted_filename(BlockDriverState *bs) -{ -    if (bs->backing_hd && bs->backing_hd->encrypted) -        return bs->backing_file; -    else if (bs->encrypted) -        return bs->filename; -    else -        return NULL; -} - -void bdrv_get_backing_filename(BlockDriverState *bs, -                               char *filename, int filename_size) -{ -    pstrcpy(filename, filename_size, bs->backing_file); -} - -int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, -                          const uint8_t *buf, int nb_sectors) -{ -    BlockDriver *drv = bs->drv; -    if (!drv) -        return -ENOMEDIUM; -    if (!drv->bdrv_write_compressed) -        return -ENOTSUP; -    if (bdrv_check_request(bs, sector_num, nb_sectors)) -        return -EIO; - -    assert(!bs->dirty_bitmap); - -    return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); -} - -int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) -{ -    BlockDriver *drv = bs->drv; -    if (!drv) -        return -ENOMEDIUM; -    if (!drv->bdrv_get_info) -        return -ENOTSUP; -    memset(bdi, 0, sizeof(*bdi)); -    return drv->bdrv_get_info(bs, bdi); -} - -int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, -                      int64_t pos, int size) -{ -    QEMUIOVector qiov; -    struct iovec iov = { -        .iov_base   = (void *) buf, -        .iov_len    = size, -    }; - -    qemu_iovec_init_external(&qiov, &iov, 1); -    return bdrv_writev_vmstate(bs, &qiov, pos); -} - -int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos) -{ -    BlockDriver *drv = bs->drv; - -    if (!drv) { -        return -ENOMEDIUM; -    } else if (drv->bdrv_save_vmstate) { -        return drv->bdrv_save_vmstate(bs, qiov, pos); -    } else if (bs->file) { -        return bdrv_writev_vmstate(bs->file, qiov, pos); -    } - -    return -ENOTSUP; -} - -int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, -                      int64_t pos, int size) -{ -    BlockDriver *drv = bs->drv; -    if (!drv) -        return -ENOMEDIUM; -    if (drv->bdrv_load_vmstate) -        return drv->bdrv_load_vmstate(bs, buf, pos, size); -    if (bs->file) -        return bdrv_load_vmstate(bs->file, buf, pos, size); -    return -ENOTSUP; -} - -void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) -{ -    if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) { -        return; -    } - -    bs->drv->bdrv_debug_event(bs, event); -} - -int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, -                          const char *tag) -{ -    while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) { -        bs = bs->file; -    } - -    if (bs && bs->drv && bs->drv->bdrv_debug_breakpoint) { -        return bs->drv->bdrv_debug_breakpoint(bs, event, tag); -    } - -    return -ENOTSUP; -} - -int bdrv_debug_resume(BlockDriverState *bs, const char *tag) -{ -    while (bs && bs->drv && !bs->drv->bdrv_debug_resume) { -        bs = bs->file; -    } - -    if (bs && bs->drv && bs->drv->bdrv_debug_resume) { -        return bs->drv->bdrv_debug_resume(bs, tag); -    } - -    return -ENOTSUP; -} - -bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag) -{ -    while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) { -        bs = bs->file; -    } - -    if (bs && bs->drv && bs->drv->bdrv_debug_is_suspended) { -        return bs->drv->bdrv_debug_is_suspended(bs, tag); -    } - -    return false; -} - -int bdrv_is_snapshot(BlockDriverState *bs) -{ -    return !!(bs->open_flags & BDRV_O_SNAPSHOT); -} - -/* backing_file can either be relative, or absolute, or a protocol.  If it is - * relative, it must be relative to the chain.  So, passing in bs->filename - * from a BDS as backing_file should not be done, as that may be relative to - * the CWD rather than the chain. */ -BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, -        const char *backing_file) -{ -    char *filename_full = NULL; -    char *backing_file_full = NULL; -    char *filename_tmp = NULL; -    int is_protocol = 0; -    BlockDriverState *curr_bs = NULL; -    BlockDriverState *retval = NULL; - -    if (!bs || !bs->drv || !backing_file) { -        return NULL; -    } - -    filename_full     = g_malloc(PATH_MAX); -    backing_file_full = g_malloc(PATH_MAX); -    filename_tmp      = g_malloc(PATH_MAX); - -    is_protocol = path_has_protocol(backing_file); - -    for (curr_bs = bs; curr_bs->backing_hd; curr_bs = curr_bs->backing_hd) { - -        /* If either of the filename paths is actually a protocol, then -         * compare unmodified paths; otherwise make paths relative */ -        if (is_protocol || path_has_protocol(curr_bs->backing_file)) { -            if (strcmp(backing_file, curr_bs->backing_file) == 0) { -                retval = curr_bs->backing_hd; -                break; -            } -        } else { -            /* If not an absolute filename path, make it relative to the current -             * image's filename path */ -            path_combine(filename_tmp, PATH_MAX, curr_bs->filename, -                         backing_file); - -            /* We are going to compare absolute pathnames */ -            if (!realpath(filename_tmp, filename_full)) { -                continue; -            } - -            /* We need to make sure the backing filename we are comparing against -             * is relative to the current image filename (or absolute) */ -            path_combine(filename_tmp, PATH_MAX, curr_bs->filename, -                         curr_bs->backing_file); - -            if (!realpath(filename_tmp, backing_file_full)) { -                continue; -            } - -            if (strcmp(backing_file_full, filename_full) == 0) { -                retval = curr_bs->backing_hd; -                break; -            } -        } -    } - -    g_free(filename_full); -    g_free(backing_file_full); -    g_free(filename_tmp); -    return retval; -} - -int bdrv_get_backing_file_depth(BlockDriverState *bs) -{ -    if (!bs->drv) { -        return 0; -    } - -    if (!bs->backing_hd) { -        return 0; -    } - -    return 1 + bdrv_get_backing_file_depth(bs->backing_hd); -} - -BlockDriverState *bdrv_find_base(BlockDriverState *bs) -{ -    BlockDriverState *curr_bs = NULL; - -    if (!bs) { -        return NULL; -    } - -    curr_bs = bs; - -    while (curr_bs->backing_hd) { -        curr_bs = curr_bs->backing_hd; -    } -    return curr_bs; -} - -/**************************************************************/ -/* async I/Os */ - -BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, -                                 QEMUIOVector *qiov, int nb_sectors, -                                 BlockDriverCompletionFunc *cb, void *opaque) -{ -    trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque); - -    return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, -                                 cb, opaque, false); -} - -BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, -                                  QEMUIOVector *qiov, int nb_sectors, -                                  BlockDriverCompletionFunc *cb, void *opaque) -{ -    trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque); - -    return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, -                                 cb, opaque, true); -} - - -typedef struct MultiwriteCB { -    int error; -    int num_requests; -    int num_callbacks; -    struct { -        BlockDriverCompletionFunc *cb; -        void *opaque; -        QEMUIOVector *free_qiov; -    } callbacks[]; -} MultiwriteCB; - -static void multiwrite_user_cb(MultiwriteCB *mcb) -{ -    int i; - -    for (i = 0; i < mcb->num_callbacks; i++) { -        mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error); -        if (mcb->callbacks[i].free_qiov) { -            qemu_iovec_destroy(mcb->callbacks[i].free_qiov); -        } -        g_free(mcb->callbacks[i].free_qiov); -    } -} - -static void multiwrite_cb(void *opaque, int ret) -{ -    MultiwriteCB *mcb = opaque; - -    trace_multiwrite_cb(mcb, ret); - -    if (ret < 0 && !mcb->error) { -        mcb->error = ret; -    } - -    mcb->num_requests--; -    if (mcb->num_requests == 0) { -        multiwrite_user_cb(mcb); -        g_free(mcb); -    } -} - -static int multiwrite_req_compare(const void *a, const void *b) -{ -    const BlockRequest *req1 = a, *req2 = b; - -    /* -     * Note that we can't simply subtract req2->sector from req1->sector -     * here as that could overflow the return value. -     */ -    if (req1->sector > req2->sector) { -        return 1; -    } else if (req1->sector < req2->sector) { -        return -1; -    } else { -        return 0; -    } -} - -/* - * Takes a bunch of requests and tries to merge them. Returns the number of - * requests that remain after merging. - */ -static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs, -    int num_reqs, MultiwriteCB *mcb) -{ -    int i, outidx; - -    // Sort requests by start sector -    qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare); - -    // Check if adjacent requests touch the same clusters. If so, combine them, -    // filling up gaps with zero sectors. -    outidx = 0; -    for (i = 1; i < num_reqs; i++) { -        int merge = 0; -        int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors; - -        // Handle exactly sequential writes and overlapping writes. -        if (reqs[i].sector <= oldreq_last) { -            merge = 1; -        } - -        if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) { -            merge = 0; -        } - -        if (merge) { -            size_t size; -            QEMUIOVector *qiov = g_malloc0(sizeof(*qiov)); -            qemu_iovec_init(qiov, -                reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1); - -            // Add the first request to the merged one. If the requests are -            // overlapping, drop the last sectors of the first request. -            size = (reqs[i].sector - reqs[outidx].sector) << 9; -            qemu_iovec_concat(qiov, reqs[outidx].qiov, 0, size); - -            // We should need to add any zeros between the two requests -            assert (reqs[i].sector <= oldreq_last); - -            // Add the second request -            qemu_iovec_concat(qiov, reqs[i].qiov, 0, reqs[i].qiov->size); - -            reqs[outidx].nb_sectors = qiov->size >> 9; -            reqs[outidx].qiov = qiov; - -            mcb->callbacks[i].free_qiov = reqs[outidx].qiov; -        } else { -            outidx++; -            reqs[outidx].sector     = reqs[i].sector; -            reqs[outidx].nb_sectors = reqs[i].nb_sectors; -            reqs[outidx].qiov       = reqs[i].qiov; -        } -    } - -    return outidx + 1; -} - -/* - * Submit multiple AIO write requests at once. - * - * On success, the function returns 0 and all requests in the reqs array have - * been submitted. In error case this function returns -1, and any of the - * requests may or may not be submitted yet. In particular, this means that the - * callback will be called for some of the requests, for others it won't. The - * caller must check the error field of the BlockRequest to wait for the right - * callbacks (if error != 0, no callback will be called). - * - * The implementation may modify the contents of the reqs array, e.g. to merge - * requests. However, the fields opaque and error are left unmodified as they - * are used to signal failure for a single request to the caller. - */ -int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) -{ -    MultiwriteCB *mcb; -    int i; - -    /* don't submit writes if we don't have a medium */ -    if (bs->drv == NULL) { -        for (i = 0; i < num_reqs; i++) { -            reqs[i].error = -ENOMEDIUM; -        } -        return -1; -    } - -    if (num_reqs == 0) { -        return 0; -    } - -    // Create MultiwriteCB structure -    mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks)); -    mcb->num_requests = 0; -    mcb->num_callbacks = num_reqs; - -    for (i = 0; i < num_reqs; i++) { -        mcb->callbacks[i].cb = reqs[i].cb; -        mcb->callbacks[i].opaque = reqs[i].opaque; -    } - -    // Check for mergable requests -    num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb); - -    trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs); - -    /* Run the aio requests. */ -    mcb->num_requests = num_reqs; -    for (i = 0; i < num_reqs; i++) { -        bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov, -            reqs[i].nb_sectors, multiwrite_cb, mcb); -    } - -    return 0; -} - -void bdrv_aio_cancel(BlockDriverAIOCB *acb) -{ -    acb->aiocb_info->cancel(acb); -} - -/* block I/O throttling */ -static bool bdrv_exceed_bps_limits(BlockDriverState *bs, int nb_sectors, -                 bool is_write, double elapsed_time, uint64_t *wait) -{ -    uint64_t bps_limit = 0; -    uint64_t extension; -    double   bytes_limit, bytes_base, bytes_res; -    double   slice_time, wait_time; - -    if (bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL]) { -        bps_limit = bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL]; -    } else if (bs->io_limits.bps[is_write]) { -        bps_limit = bs->io_limits.bps[is_write]; -    } else { -        if (wait) { -            *wait = 0; -        } - -        return false; -    } - -    slice_time = bs->slice_end - bs->slice_start; -    slice_time /= (NANOSECONDS_PER_SECOND); -    bytes_limit = bps_limit * slice_time; -    bytes_base  = bs->slice_submitted.bytes[is_write]; -    if (bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL]) { -        bytes_base += bs->slice_submitted.bytes[!is_write]; -    } - -    /* bytes_base: the bytes of data which have been read/written; and -     *             it is obtained from the history statistic info. -     * bytes_res: the remaining bytes of data which need to be read/written. -     * (bytes_base + bytes_res) / bps_limit: used to calcuate -     *             the total time for completing reading/writting all data. -     */ -    bytes_res   = (unsigned) nb_sectors * BDRV_SECTOR_SIZE; - -    if (bytes_base + bytes_res <= bytes_limit) { -        if (wait) { -            *wait = 0; -        } - -        return false; -    } - -    /* Calc approx time to dispatch */ -    wait_time = (bytes_base + bytes_res) / bps_limit - elapsed_time; - -    /* When the I/O rate at runtime exceeds the limits, -     * bs->slice_end need to be extended in order that the current statistic -     * info can be kept until the timer fire, so it is increased and tuned -     * based on the result of experiment. -     */ -    extension = wait_time * NANOSECONDS_PER_SECOND; -    extension = DIV_ROUND_UP(extension, BLOCK_IO_SLICE_TIME) * -                BLOCK_IO_SLICE_TIME; -    bs->slice_end += extension; -    if (wait) { -        *wait = wait_time * NANOSECONDS_PER_SECOND; -    } - -    return true; -} - -static bool bdrv_exceed_iops_limits(BlockDriverState *bs, bool is_write, -                             double elapsed_time, uint64_t *wait) -{ -    uint64_t iops_limit = 0; -    double   ios_limit, ios_base; -    double   slice_time, wait_time; - -    if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) { -        iops_limit = bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]; -    } else if (bs->io_limits.iops[is_write]) { -        iops_limit = bs->io_limits.iops[is_write]; -    } else { -        if (wait) { -            *wait = 0; -        } - -        return false; -    } - -    slice_time = bs->slice_end - bs->slice_start; -    slice_time /= (NANOSECONDS_PER_SECOND); -    ios_limit  = iops_limit * slice_time; -    ios_base   = bs->slice_submitted.ios[is_write]; -    if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) { -        ios_base += bs->slice_submitted.ios[!is_write]; -    } - -    if (ios_base + 1 <= ios_limit) { -        if (wait) { -            *wait = 0; -        } - -        return false; -    } - -    /* Calc approx time to dispatch, in seconds */ -    wait_time = (ios_base + 1) / iops_limit; -    if (wait_time > elapsed_time) { -        wait_time = wait_time - elapsed_time; -    } else { -        wait_time = 0; -    } - -    /* Exceeded current slice, extend it by another slice time */ -    bs->slice_end += BLOCK_IO_SLICE_TIME; -    if (wait) { -        *wait = wait_time * NANOSECONDS_PER_SECOND; -    } - -    return true; -} - -static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors, -                           bool is_write, int64_t *wait) -{ -    int64_t  now, max_wait; -    uint64_t bps_wait = 0, iops_wait = 0; -    double   elapsed_time; -    int      bps_ret, iops_ret; - -    now = qemu_get_clock_ns(vm_clock); -    if (now > bs->slice_end) { -        bs->slice_start = now; -        bs->slice_end   = now + BLOCK_IO_SLICE_TIME; -        memset(&bs->slice_submitted, 0, sizeof(bs->slice_submitted)); -    } - -    elapsed_time  = now - bs->slice_start; -    elapsed_time  /= (NANOSECONDS_PER_SECOND); - -    bps_ret  = bdrv_exceed_bps_limits(bs, nb_sectors, -                                      is_write, elapsed_time, &bps_wait); -    iops_ret = bdrv_exceed_iops_limits(bs, is_write, -                                      elapsed_time, &iops_wait); -    if (bps_ret || iops_ret) { -        max_wait = bps_wait > iops_wait ? bps_wait : iops_wait; -        if (wait) { -            *wait = max_wait; -        } - -        now = qemu_get_clock_ns(vm_clock); -        if (bs->slice_end < now + max_wait) { -            bs->slice_end = now + max_wait; -        } - -        return true; -    } - -    if (wait) { -        *wait = 0; -    } - -    bs->slice_submitted.bytes[is_write] += (int64_t)nb_sectors * -                                           BDRV_SECTOR_SIZE; -    bs->slice_submitted.ios[is_write]++; - -    return false; -} - -/**************************************************************/ -/* async block device emulation */ - -typedef struct BlockDriverAIOCBSync { -    BlockDriverAIOCB common; -    QEMUBH *bh; -    int ret; -    /* vector translation state */ -    QEMUIOVector *qiov; -    uint8_t *bounce; -    int is_write; -} BlockDriverAIOCBSync; - -static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) -{ -    BlockDriverAIOCBSync *acb = -        container_of(blockacb, BlockDriverAIOCBSync, common); -    qemu_bh_delete(acb->bh); -    acb->bh = NULL; -    qemu_aio_release(acb); -} - -static const AIOCBInfo bdrv_em_aiocb_info = { -    .aiocb_size         = sizeof(BlockDriverAIOCBSync), -    .cancel             = bdrv_aio_cancel_em, -}; - -static void bdrv_aio_bh_cb(void *opaque) -{ -    BlockDriverAIOCBSync *acb = opaque; - -    if (!acb->is_write) -        qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size); -    qemu_vfree(acb->bounce); -    acb->common.cb(acb->common.opaque, acb->ret); -    qemu_bh_delete(acb->bh); -    acb->bh = NULL; -    qemu_aio_release(acb); -} - -static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, -                                            int64_t sector_num, -                                            QEMUIOVector *qiov, -                                            int nb_sectors, -                                            BlockDriverCompletionFunc *cb, -                                            void *opaque, -                                            int is_write) - -{ -    BlockDriverAIOCBSync *acb; - -    acb = qemu_aio_get(&bdrv_em_aiocb_info, bs, cb, opaque); -    acb->is_write = is_write; -    acb->qiov = qiov; -    acb->bounce = qemu_blockalign(bs, qiov->size); -    acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); - -    if (is_write) { -        qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size); -        acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors); -    } else { -        acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors); -    } - -    qemu_bh_schedule(acb->bh); - -    return &acb->common; -} - -static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, -        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, -        BlockDriverCompletionFunc *cb, void *opaque) -{ -    return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); -} - -static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, -        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, -        BlockDriverCompletionFunc *cb, void *opaque) -{ -    return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); -} - - -typedef struct BlockDriverAIOCBCoroutine { -    BlockDriverAIOCB common; -    BlockRequest req; -    bool is_write; -    bool *done; -    QEMUBH* bh; -} BlockDriverAIOCBCoroutine; - -static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb) -{ -    BlockDriverAIOCBCoroutine *acb = -        container_of(blockacb, BlockDriverAIOCBCoroutine, common); -    bool done = false; - -    acb->done = &done; -    while (!done) { -        qemu_aio_wait(); -    } -} - -static const AIOCBInfo bdrv_em_co_aiocb_info = { -    .aiocb_size         = sizeof(BlockDriverAIOCBCoroutine), -    .cancel             = bdrv_aio_co_cancel_em, -}; - -static void bdrv_co_em_bh(void *opaque) -{ -    BlockDriverAIOCBCoroutine *acb = opaque; - -    acb->common.cb(acb->common.opaque, acb->req.error); - -    if (acb->done) { -        *acb->done = true; -    } - -    qemu_bh_delete(acb->bh); -    qemu_aio_release(acb); -} - -/* Invoke bdrv_co_do_readv/bdrv_co_do_writev */ -static void coroutine_fn bdrv_co_do_rw(void *opaque) -{ -    BlockDriverAIOCBCoroutine *acb = opaque; -    BlockDriverState *bs = acb->common.bs; - -    if (!acb->is_write) { -        acb->req.error = bdrv_co_do_readv(bs, acb->req.sector, -            acb->req.nb_sectors, acb->req.qiov, 0); -    } else { -        acb->req.error = bdrv_co_do_writev(bs, acb->req.sector, -            acb->req.nb_sectors, acb->req.qiov, 0); -    } - -    acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); -    qemu_bh_schedule(acb->bh); -} - -static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, -                                               int64_t sector_num, -                                               QEMUIOVector *qiov, -                                               int nb_sectors, -                                               BlockDriverCompletionFunc *cb, -                                               void *opaque, -                                               bool is_write) -{ -    Coroutine *co; -    BlockDriverAIOCBCoroutine *acb; - -    acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque); -    acb->req.sector = sector_num; -    acb->req.nb_sectors = nb_sectors; -    acb->req.qiov = qiov; -    acb->is_write = is_write; -    acb->done = NULL; - -    co = qemu_coroutine_create(bdrv_co_do_rw); -    qemu_coroutine_enter(co, acb); - -    return &acb->common; -} - -static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque) -{ -    BlockDriverAIOCBCoroutine *acb = opaque; -    BlockDriverState *bs = acb->common.bs; - -    acb->req.error = bdrv_co_flush(bs); -    acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); -    qemu_bh_schedule(acb->bh); -} - -BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, -        BlockDriverCompletionFunc *cb, void *opaque) -{ -    trace_bdrv_aio_flush(bs, opaque); - -    Coroutine *co; -    BlockDriverAIOCBCoroutine *acb; - -    acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque); -    acb->done = NULL; - -    co = qemu_coroutine_create(bdrv_aio_flush_co_entry); -    qemu_coroutine_enter(co, acb); - -    return &acb->common; -} - -static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque) -{ -    BlockDriverAIOCBCoroutine *acb = opaque; -    BlockDriverState *bs = acb->common.bs; - -    acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors); -    acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); -    qemu_bh_schedule(acb->bh); -} - -BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors, -        BlockDriverCompletionFunc *cb, void *opaque) -{ -    Coroutine *co; -    BlockDriverAIOCBCoroutine *acb; - -    trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque); - -    acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque); -    acb->req.sector = sector_num; -    acb->req.nb_sectors = nb_sectors; -    acb->done = NULL; -    co = qemu_coroutine_create(bdrv_aio_discard_co_entry); -    qemu_coroutine_enter(co, acb); - -    return &acb->common; -} - -void bdrv_init(void) -{ -    module_call_init(MODULE_INIT_BLOCK); -} - -void bdrv_init_with_whitelist(void) -{ -    use_bdrv_whitelist = 1; -    bdrv_init(); -} - -void *qemu_aio_get(const AIOCBInfo *aiocb_info, BlockDriverState *bs, -                   BlockDriverCompletionFunc *cb, void *opaque) -{ -    BlockDriverAIOCB *acb; - -    acb = g_slice_alloc(aiocb_info->aiocb_size); -    acb->aiocb_info = aiocb_info; -    acb->bs = bs; -    acb->cb = cb; -    acb->opaque = opaque; -    return acb; -} - -void qemu_aio_release(void *p) -{ -    BlockDriverAIOCB *acb = p; -    g_slice_free1(acb->aiocb_info->aiocb_size, acb); -} - -/**************************************************************/ -/* Coroutine block device emulation */ - -typedef struct CoroutineIOCompletion { -    Coroutine *coroutine; -    int ret; -} CoroutineIOCompletion; - -static void bdrv_co_io_em_complete(void *opaque, int ret) -{ -    CoroutineIOCompletion *co = opaque; - -    co->ret = ret; -    qemu_coroutine_enter(co->coroutine, NULL); -} - -static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num, -                                      int nb_sectors, QEMUIOVector *iov, -                                      bool is_write) -{ -    CoroutineIOCompletion co = { -        .coroutine = qemu_coroutine_self(), -    }; -    BlockDriverAIOCB *acb; - -    if (is_write) { -        acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors, -                                       bdrv_co_io_em_complete, &co); -    } else { -        acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors, -                                      bdrv_co_io_em_complete, &co); -    } - -    trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb); -    if (!acb) { -        return -EIO; -    } -    qemu_coroutine_yield(); - -    return co.ret; -} - -static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, -                                         int64_t sector_num, int nb_sectors, -                                         QEMUIOVector *iov) -{ -    return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false); -} - -static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, -                                         int64_t sector_num, int nb_sectors, -                                         QEMUIOVector *iov) -{ -    return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true); -} - -static void coroutine_fn bdrv_flush_co_entry(void *opaque) -{ -    RwCo *rwco = opaque; - -    rwco->ret = bdrv_co_flush(rwco->bs); -} - -int coroutine_fn bdrv_co_flush(BlockDriverState *bs) -{ -    int ret; - -    if (!bs || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { -        return 0; -    } - -    /* Write back cached data to the OS even with cache=unsafe */ -    BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_OS); -    if (bs->drv->bdrv_co_flush_to_os) { -        ret = bs->drv->bdrv_co_flush_to_os(bs); -        if (ret < 0) { -            return ret; -        } -    } - -    /* But don't actually force it to the disk with cache=unsafe */ -    if (bs->open_flags & BDRV_O_NO_FLUSH) { -        goto flush_parent; -    } - -    BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_DISK); -    if (bs->drv->bdrv_co_flush_to_disk) { -        ret = bs->drv->bdrv_co_flush_to_disk(bs); -    } else if (bs->drv->bdrv_aio_flush) { -        BlockDriverAIOCB *acb; -        CoroutineIOCompletion co = { -            .coroutine = qemu_coroutine_self(), -        }; - -        acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co); -        if (acb == NULL) { -            ret = -EIO; -        } else { -            qemu_coroutine_yield(); -            ret = co.ret; -        } -    } else { -        /* -         * Some block drivers always operate in either writethrough or unsafe -         * mode and don't support bdrv_flush therefore. Usually qemu doesn't -         * know how the server works (because the behaviour is hardcoded or -         * depends on server-side configuration), so we can't ensure that -         * everything is safe on disk. Returning an error doesn't work because -         * that would break guests even if the server operates in writethrough -         * mode. -         * -         * Let's hope the user knows what he's doing. -         */ -        ret = 0; -    } -    if (ret < 0) { -        return ret; -    } - -    /* Now flush the underlying protocol.  It will also have BDRV_O_NO_FLUSH -     * in the case of cache=unsafe, so there are no useless flushes. -     */ -flush_parent: -    return bdrv_co_flush(bs->file); -} - -void bdrv_invalidate_cache(BlockDriverState *bs) -{ -    if (bs->drv && bs->drv->bdrv_invalidate_cache) { -        bs->drv->bdrv_invalidate_cache(bs); -    } -} - -void bdrv_invalidate_cache_all(void) -{ -    BlockDriverState *bs; - -    QTAILQ_FOREACH(bs, &bdrv_states, list) { -        bdrv_invalidate_cache(bs); -    } -} - -void bdrv_clear_incoming_migration_all(void) -{ -    BlockDriverState *bs; - -    QTAILQ_FOREACH(bs, &bdrv_states, list) { -        bs->open_flags = bs->open_flags & ~(BDRV_O_INCOMING); -    } -} - -int bdrv_flush(BlockDriverState *bs) -{ -    Coroutine *co; -    RwCo rwco = { -        .bs = bs, -        .ret = NOT_DONE, -    }; - -    if (qemu_in_coroutine()) { -        /* Fast-path if already in coroutine context */ -        bdrv_flush_co_entry(&rwco); -    } else { -        co = qemu_coroutine_create(bdrv_flush_co_entry); -        qemu_coroutine_enter(co, &rwco); -        while (rwco.ret == NOT_DONE) { -            qemu_aio_wait(); -        } -    } - -    return rwco.ret; -} - -static void coroutine_fn bdrv_discard_co_entry(void *opaque) -{ -    RwCo *rwco = opaque; - -    rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors); -} - -int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, -                                 int nb_sectors) -{ -    if (!bs->drv) { -        return -ENOMEDIUM; -    } else if (bdrv_check_request(bs, sector_num, nb_sectors)) { -        return -EIO; -    } else if (bs->read_only) { -        return -EROFS; -    } - -    if (bs->dirty_bitmap) { -        bdrv_reset_dirty(bs, sector_num, nb_sectors); -    } - -    /* Do nothing if disabled.  */ -    if (!(bs->open_flags & BDRV_O_UNMAP)) { -        return 0; -    } - -    if (bs->drv->bdrv_co_discard) { -        return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors); -    } else if (bs->drv->bdrv_aio_discard) { -        BlockDriverAIOCB *acb; -        CoroutineIOCompletion co = { -            .coroutine = qemu_coroutine_self(), -        }; - -        acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors, -                                        bdrv_co_io_em_complete, &co); -        if (acb == NULL) { -            return -EIO; -        } else { -            qemu_coroutine_yield(); -            return co.ret; -        } -    } else { -        return 0; -    } -} - -int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) -{ -    Coroutine *co; -    RwCo rwco = { -        .bs = bs, -        .sector_num = sector_num, -        .nb_sectors = nb_sectors, -        .ret = NOT_DONE, -    }; - -    if (qemu_in_coroutine()) { -        /* Fast-path if already in coroutine context */ -        bdrv_discard_co_entry(&rwco); -    } else { -        co = qemu_coroutine_create(bdrv_discard_co_entry); -        qemu_coroutine_enter(co, &rwco); -        while (rwco.ret == NOT_DONE) { -            qemu_aio_wait(); -        } -    } - -    return rwco.ret; -} - -/**************************************************************/ -/* removable device support */ - -/** - * Return TRUE if the media is present - */ -int bdrv_is_inserted(BlockDriverState *bs) -{ -    BlockDriver *drv = bs->drv; - -    if (!drv) -        return 0; -    if (!drv->bdrv_is_inserted) -        return 1; -    return drv->bdrv_is_inserted(bs); -} - -/** - * Return whether the media changed since the last call to this - * function, or -ENOTSUP if we don't know.  Most drivers don't know. - */ -int bdrv_media_changed(BlockDriverState *bs) -{ -    BlockDriver *drv = bs->drv; - -    if (drv && drv->bdrv_media_changed) { -        return drv->bdrv_media_changed(bs); -    } -    return -ENOTSUP; -} - -/** - * If eject_flag is TRUE, eject the media. Otherwise, close the tray - */ -void bdrv_eject(BlockDriverState *bs, bool eject_flag) -{ -    BlockDriver *drv = bs->drv; - -    if (drv && drv->bdrv_eject) { -        drv->bdrv_eject(bs, eject_flag); -    } - -    if (bs->device_name[0] != '\0') { -        bdrv_emit_qmp_eject_event(bs, eject_flag); -    } -} - -/** - * Lock or unlock the media (if it is locked, the user won't be able - * to eject it manually). - */ -void bdrv_lock_medium(BlockDriverState *bs, bool locked) -{ -    BlockDriver *drv = bs->drv; - -    trace_bdrv_lock_medium(bs, locked); - -    if (drv && drv->bdrv_lock_medium) { -        drv->bdrv_lock_medium(bs, locked); -    } -} - -/* needed for generic scsi interface */ - -int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) -{ -    BlockDriver *drv = bs->drv; - -    if (drv && drv->bdrv_ioctl) -        return drv->bdrv_ioctl(bs, req, buf); -    return -ENOTSUP; -} - -BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, -        unsigned long int req, void *buf, -        BlockDriverCompletionFunc *cb, void *opaque) -{ -    BlockDriver *drv = bs->drv; - -    if (drv && drv->bdrv_aio_ioctl) -        return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque); -    return NULL; -} - -void bdrv_set_buffer_alignment(BlockDriverState *bs, int align) -{ -    bs->buffer_alignment = align; -} - -void *qemu_blockalign(BlockDriverState *bs, size_t size) -{ -    return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); -} - -/* - * Check if all memory in this vector is sector aligned. - */ -bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) -{ -    int i; - -    for (i = 0; i < qiov->niov; i++) { -        if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) { -            return false; -        } -    } - -    return true; -} - -void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity) -{ -    int64_t bitmap_size; - -    assert((granularity & (granularity - 1)) == 0); - -    if (granularity) { -        granularity >>= BDRV_SECTOR_BITS; -        assert(!bs->dirty_bitmap); -        bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS); -        bs->dirty_bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1); -    } else { -        if (bs->dirty_bitmap) { -            hbitmap_free(bs->dirty_bitmap); -            bs->dirty_bitmap = NULL; -        } -    } -} - -int bdrv_get_dirty(BlockDriverState *bs, int64_t sector) -{ -    if (bs->dirty_bitmap) { -        return hbitmap_get(bs->dirty_bitmap, sector); -    } else { -        return 0; -    } -} - -void bdrv_dirty_iter_init(BlockDriverState *bs, HBitmapIter *hbi) -{ -    hbitmap_iter_init(hbi, bs->dirty_bitmap, 0); -} - -void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, -                    int nr_sectors) -{ -    hbitmap_set(bs->dirty_bitmap, cur_sector, nr_sectors); -} - -void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, -                      int nr_sectors) -{ -    hbitmap_reset(bs->dirty_bitmap, cur_sector, nr_sectors); -} - -int64_t bdrv_get_dirty_count(BlockDriverState *bs) -{ -    if (bs->dirty_bitmap) { -        return hbitmap_count(bs->dirty_bitmap); -    } else { -        return 0; -    } -} - -void bdrv_set_in_use(BlockDriverState *bs, int in_use) -{ -    assert(bs->in_use != in_use); -    bs->in_use = in_use; -} - -int bdrv_in_use(BlockDriverState *bs) -{ -    return bs->in_use; -} - -void bdrv_iostatus_enable(BlockDriverState *bs) -{ -    bs->iostatus_enabled = true; -    bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK; -} - -/* The I/O status is only enabled if the drive explicitly - * enables it _and_ the VM is configured to stop on errors */ -bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) -{ -    return (bs->iostatus_enabled && -           (bs->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC || -            bs->on_write_error == BLOCKDEV_ON_ERROR_STOP   || -            bs->on_read_error == BLOCKDEV_ON_ERROR_STOP)); -} - -void bdrv_iostatus_disable(BlockDriverState *bs) -{ -    bs->iostatus_enabled = false; -} - -void bdrv_iostatus_reset(BlockDriverState *bs) -{ -    if (bdrv_iostatus_is_enabled(bs)) { -        bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK; -        if (bs->job) { -            block_job_iostatus_reset(bs->job); -        } -    } -} - -void bdrv_iostatus_set_err(BlockDriverState *bs, int error) -{ -    assert(bdrv_iostatus_is_enabled(bs)); -    if (bs->iostatus == BLOCK_DEVICE_IO_STATUS_OK) { -        bs->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE : -                                         BLOCK_DEVICE_IO_STATUS_FAILED; -    } -} - -void -bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, -        enum BlockAcctType type) -{ -    assert(type < BDRV_MAX_IOTYPE); - -    cookie->bytes = bytes; -    cookie->start_time_ns = get_clock(); -    cookie->type = type; -} - -void -bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie) -{ -    assert(cookie->type < BDRV_MAX_IOTYPE); - -    bs->nr_bytes[cookie->type] += cookie->bytes; -    bs->nr_ops[cookie->type]++; -    bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns; -} - -void bdrv_img_create(const char *filename, const char *fmt, -                     const char *base_filename, const char *base_fmt, -                     char *options, uint64_t img_size, int flags, -                     Error **errp, bool quiet) -{ -    QEMUOptionParameter *param = NULL, *create_options = NULL; -    QEMUOptionParameter *backing_fmt, *backing_file, *size; -    BlockDriverState *bs = NULL; -    BlockDriver *drv, *proto_drv; -    BlockDriver *backing_drv = NULL; -    int ret = 0; - -    /* Find driver and parse its options */ -    drv = bdrv_find_format(fmt); -    if (!drv) { -        error_setg(errp, "Unknown file format '%s'", fmt); -        return; -    } - -    proto_drv = bdrv_find_protocol(filename, true); -    if (!proto_drv) { -        error_setg(errp, "Unknown protocol '%s'", filename); -        return; -    } - -    create_options = append_option_parameters(create_options, -                                              drv->create_options); -    create_options = append_option_parameters(create_options, -                                              proto_drv->create_options); - -    /* Create parameter list with default values */ -    param = parse_option_parameters("", create_options, param); - -    set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size); - -    /* Parse -o options */ -    if (options) { -        param = parse_option_parameters(options, create_options, param); -        if (param == NULL) { -            error_setg(errp, "Invalid options for file format '%s'.", fmt); -            goto out; -        } -    } - -    if (base_filename) { -        if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE, -                                 base_filename)) { -            error_setg(errp, "Backing file not supported for file format '%s'", -                       fmt); -            goto out; -        } -    } - -    if (base_fmt) { -        if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) { -            error_setg(errp, "Backing file format not supported for file " -                             "format '%s'", fmt); -            goto out; -        } -    } - -    backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE); -    if (backing_file && backing_file->value.s) { -        if (!strcmp(filename, backing_file->value.s)) { -            error_setg(errp, "Error: Trying to create an image with the " -                             "same filename as the backing file"); -            goto out; -        } -    } - -    backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT); -    if (backing_fmt && backing_fmt->value.s) { -        backing_drv = bdrv_find_format(backing_fmt->value.s); -        if (!backing_drv) { -            error_setg(errp, "Unknown backing file format '%s'", -                       backing_fmt->value.s); -            goto out; -        } -    } - -    // The size for the image must always be specified, with one exception: -    // If we are using a backing file, we can obtain the size from there -    size = get_option_parameter(param, BLOCK_OPT_SIZE); -    if (size && size->value.n == -1) { -        if (backing_file && backing_file->value.s) { -            uint64_t size; -            char buf[32]; -            int back_flags; - -            /* backing files always opened read-only */ -            back_flags = -                flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); - -            bs = bdrv_new(""); - -            ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags, -                            backing_drv); -            if (ret < 0) { -                error_setg_errno(errp, -ret, "Could not open '%s'", -                                 backing_file->value.s); -                goto out; -            } -            bdrv_get_geometry(bs, &size); -            size *= 512; - -            snprintf(buf, sizeof(buf), "%" PRId64, size); -            set_option_parameter(param, BLOCK_OPT_SIZE, buf); -        } else { -            error_setg(errp, "Image creation needs a size parameter"); -            goto out; -        } -    } - -    if (!quiet) { -        printf("Formatting '%s', fmt=%s ", filename, fmt); -        print_option_parameters(param); -        puts(""); -    } -    ret = bdrv_create(drv, filename, param); -    if (ret < 0) { -        if (ret == -ENOTSUP) { -            error_setg(errp,"Formatting or formatting option not supported for " -                            "file format '%s'", fmt); -        } else if (ret == -EFBIG) { -            const char *cluster_size_hint = ""; -            if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) { -                cluster_size_hint = " (try using a larger cluster size)"; -            } -            error_setg(errp, "The image size is too large for file format '%s'%s", -                       fmt, cluster_size_hint); -        } else { -            error_setg(errp, "%s: error while creating %s: %s", filename, fmt, -                       strerror(-ret)); -        } -    } - -out: -    free_option_parameters(create_options); -    free_option_parameters(param); - -    if (bs) { -        bdrv_delete(bs); -    } -} - -AioContext *bdrv_get_aio_context(BlockDriverState *bs) -{ -    /* Currently BlockDriverState always uses the main loop AioContext */ -    return qemu_get_aio_context(); -} - -void bdrv_add_before_write_notifier(BlockDriverState *bs, -                                    NotifierWithReturn *notifier) -{ -    notifier_with_return_list_add(&bs->before_write_notifiers, notifier); -} diff --git a/contrib/qemu/block/qcow.c b/contrib/qemu/block/qcow.c deleted file mode 100644 index 5239bd68f1c..00000000000 --- a/contrib/qemu/block/qcow.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Block driver for the QCOW format - * - * Copyright (c) 2004-2006 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "qemu-common.h" -#include "block/block_int.h" -#include "qemu/module.h" -#include <zlib.h> -#include "qemu/aes.h" -#include "migration/migration.h" - -/**************************************************************/ -/* QEMU COW block driver with compression and encryption support */ - -#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb) -#define QCOW_VERSION 1 - -#define QCOW_CRYPT_NONE 0 -#define QCOW_CRYPT_AES  1 - -#define QCOW_OFLAG_COMPRESSED (1LL << 63) - -typedef struct QCowHeader { -    uint32_t magic; -    uint32_t version; -    uint64_t backing_file_offset; -    uint32_t backing_file_size; -    uint32_t mtime; -    uint64_t size; /* in bytes */ -    uint8_t cluster_bits; -    uint8_t l2_bits; -    uint32_t crypt_method; -    uint64_t l1_table_offset; -} QCowHeader; - -#define L2_CACHE_SIZE 16 - -typedef struct BDRVQcowState { -    int cluster_bits; -    int cluster_size; -    int cluster_sectors; -    int l2_bits; -    int l2_size; -    int l1_size; -    uint64_t cluster_offset_mask; -    uint64_t l1_table_offset; -    uint64_t *l1_table; -    uint64_t *l2_cache; -    uint64_t l2_cache_offsets[L2_CACHE_SIZE]; -    uint32_t l2_cache_counts[L2_CACHE_SIZE]; -    uint8_t *cluster_cache; -    uint8_t *cluster_data; -    uint64_t cluster_cache_offset; -    uint32_t crypt_method; /* current crypt method, 0 if no key yet */ -    uint32_t crypt_method_header; -    AES_KEY aes_encrypt_key; -    AES_KEY aes_decrypt_key; -    CoMutex lock; -    Error *migration_blocker; -} BDRVQcowState; - -static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); - -static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) -{ -    const QCowHeader *cow_header = (const void *)buf; - -    if (buf_size >= sizeof(QCowHeader) && -        be32_to_cpu(cow_header->magic) == QCOW_MAGIC && -        be32_to_cpu(cow_header->version) == QCOW_VERSION) -        return 100; -    else -        return 0; -} - -static int qcow_open(BlockDriverState *bs, QDict *options, int flags) -{ -    BDRVQcowState *s = bs->opaque; -    int len, i, shift, ret; -    QCowHeader header; - -    ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); -    if (ret < 0) { -        goto fail; -    } -    be32_to_cpus(&header.magic); -    be32_to_cpus(&header.version); -    be64_to_cpus(&header.backing_file_offset); -    be32_to_cpus(&header.backing_file_size); -    be32_to_cpus(&header.mtime); -    be64_to_cpus(&header.size); -    be32_to_cpus(&header.crypt_method); -    be64_to_cpus(&header.l1_table_offset); - -    if (header.magic != QCOW_MAGIC) { -        ret = -EMEDIUMTYPE; -        goto fail; -    } -    if (header.version != QCOW_VERSION) { -        char version[64]; -        snprintf(version, sizeof(version), "QCOW version %d", header.version); -        qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, -            bs->device_name, "qcow", version); -        ret = -ENOTSUP; -        goto fail; -    } - -    if (header.size <= 1 || header.cluster_bits < 9) { -        ret = -EINVAL; -        goto fail; -    } -    if (header.crypt_method > QCOW_CRYPT_AES) { -        ret = -EINVAL; -        goto fail; -    } -    s->crypt_method_header = header.crypt_method; -    if (s->crypt_method_header) { -        bs->encrypted = 1; -    } -    s->cluster_bits = header.cluster_bits; -    s->cluster_size = 1 << s->cluster_bits; -    s->cluster_sectors = 1 << (s->cluster_bits - 9); -    s->l2_bits = header.l2_bits; -    s->l2_size = 1 << s->l2_bits; -    bs->total_sectors = header.size / 512; -    s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1; - -    /* read the level 1 table */ -    shift = s->cluster_bits + s->l2_bits; -    s->l1_size = (header.size + (1LL << shift) - 1) >> shift; - -    s->l1_table_offset = header.l1_table_offset; -    s->l1_table = g_malloc(s->l1_size * sizeof(uint64_t)); - -    ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, -               s->l1_size * sizeof(uint64_t)); -    if (ret < 0) { -        goto fail; -    } - -    for(i = 0;i < s->l1_size; i++) { -        be64_to_cpus(&s->l1_table[i]); -    } -    /* alloc L2 cache */ -    s->l2_cache = g_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); -    s->cluster_cache = g_malloc(s->cluster_size); -    s->cluster_data = g_malloc(s->cluster_size); -    s->cluster_cache_offset = -1; - -    /* read the backing file name */ -    if (header.backing_file_offset != 0) { -        len = header.backing_file_size; -        if (len > 1023) { -            len = 1023; -        } -        ret = bdrv_pread(bs->file, header.backing_file_offset, -                   bs->backing_file, len); -        if (ret < 0) { -            goto fail; -        } -        bs->backing_file[len] = '\0'; -    } - -    /* Disable migration when qcow images are used */ -    error_set(&s->migration_blocker, -              QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, -              "qcow", bs->device_name, "live migration"); -    migrate_add_blocker(s->migration_blocker); - -    qemu_co_mutex_init(&s->lock); -    return 0; - - fail: -    g_free(s->l1_table); -    g_free(s->l2_cache); -    g_free(s->cluster_cache); -    g_free(s->cluster_data); -    return ret; -} - - -/* We have nothing to do for QCOW reopen, stubs just return - * success */ -static int qcow_reopen_prepare(BDRVReopenState *state, -                               BlockReopenQueue *queue, Error **errp) -{ -    return 0; -} - -static int qcow_set_key(BlockDriverState *bs, const char *key) -{ -    BDRVQcowState *s = bs->opaque; -    uint8_t keybuf[16]; -    int len, i; - -    memset(keybuf, 0, 16); -    len = strlen(key); -    if (len > 16) -        len = 16; -    /* XXX: we could compress the chars to 7 bits to increase -       entropy */ -    for(i = 0;i < len;i++) { -        keybuf[i] = key[i]; -    } -    s->crypt_method = s->crypt_method_header; - -    if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0) -        return -1; -    if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0) -        return -1; -    return 0; -} - -/* The crypt function is compatible with the linux cryptoloop -   algorithm for < 4 GB images. NOTE: out_buf == in_buf is -   supported */ -static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num, -                            uint8_t *out_buf, const uint8_t *in_buf, -                            int nb_sectors, int enc, -                            const AES_KEY *key) -{ -    union { -        uint64_t ll[2]; -        uint8_t b[16]; -    } ivec; -    int i; - -    for(i = 0; i < nb_sectors; i++) { -        ivec.ll[0] = cpu_to_le64(sector_num); -        ivec.ll[1] = 0; -        AES_cbc_encrypt(in_buf, out_buf, 512, key, -                        ivec.b, enc); -        sector_num++; -        in_buf += 512; -        out_buf += 512; -    } -} - -/* 'allocate' is: - * - * 0 to not allocate. - * - * 1 to allocate a normal cluster (for sector indexes 'n_start' to - * 'n_end') - * - * 2 to allocate a compressed cluster of size - * 'compressed_size'. 'compressed_size' must be > 0 and < - * cluster_size - * - * return 0 if not allocated. - */ -static uint64_t get_cluster_offset(BlockDriverState *bs, -                                   uint64_t offset, int allocate, -                                   int compressed_size, -                                   int n_start, int n_end) -{ -    BDRVQcowState *s = bs->opaque; -    int min_index, i, j, l1_index, l2_index; -    uint64_t l2_offset, *l2_table, cluster_offset, tmp; -    uint32_t min_count; -    int new_l2_table; - -    l1_index = offset >> (s->l2_bits + s->cluster_bits); -    l2_offset = s->l1_table[l1_index]; -    new_l2_table = 0; -    if (!l2_offset) { -        if (!allocate) -            return 0; -        /* allocate a new l2 entry */ -        l2_offset = bdrv_getlength(bs->file); -        /* round to cluster size */ -        l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1); -        /* update the L1 entry */ -        s->l1_table[l1_index] = l2_offset; -        tmp = cpu_to_be64(l2_offset); -        if (bdrv_pwrite_sync(bs->file, -                s->l1_table_offset + l1_index * sizeof(tmp), -                &tmp, sizeof(tmp)) < 0) -            return 0; -        new_l2_table = 1; -    } -    for(i = 0; i < L2_CACHE_SIZE; i++) { -        if (l2_offset == s->l2_cache_offsets[i]) { -            /* increment the hit count */ -            if (++s->l2_cache_counts[i] == 0xffffffff) { -                for(j = 0; j < L2_CACHE_SIZE; j++) { -                    s->l2_cache_counts[j] >>= 1; -                } -            } -            l2_table = s->l2_cache + (i << s->l2_bits); -            goto found; -        } -    } -    /* not found: load a new entry in the least used one */ -    min_index = 0; -    min_count = 0xffffffff; -    for(i = 0; i < L2_CACHE_SIZE; i++) { -        if (s->l2_cache_counts[i] < min_count) { -            min_count = s->l2_cache_counts[i]; -            min_index = i; -        } -    } -    l2_table = s->l2_cache + (min_index << s->l2_bits); -    if (new_l2_table) { -        memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); -        if (bdrv_pwrite_sync(bs->file, l2_offset, l2_table, -                s->l2_size * sizeof(uint64_t)) < 0) -            return 0; -    } else { -        if (bdrv_pread(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) != -            s->l2_size * sizeof(uint64_t)) -            return 0; -    } -    s->l2_cache_offsets[min_index] = l2_offset; -    s->l2_cache_counts[min_index] = 1; - found: -    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1); -    cluster_offset = be64_to_cpu(l2_table[l2_index]); -    if (!cluster_offset || -        ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) { -        if (!allocate) -            return 0; -        /* allocate a new cluster */ -        if ((cluster_offset & QCOW_OFLAG_COMPRESSED) && -            (n_end - n_start) < s->cluster_sectors) { -            /* if the cluster is already compressed, we must -               decompress it in the case it is not completely -               overwritten */ -            if (decompress_cluster(bs, cluster_offset) < 0) -                return 0; -            cluster_offset = bdrv_getlength(bs->file); -            cluster_offset = (cluster_offset + s->cluster_size - 1) & -                ~(s->cluster_size - 1); -            /* write the cluster content */ -            if (bdrv_pwrite(bs->file, cluster_offset, s->cluster_cache, s->cluster_size) != -                s->cluster_size) -                return -1; -        } else { -            cluster_offset = bdrv_getlength(bs->file); -            if (allocate == 1) { -                /* round to cluster size */ -                cluster_offset = (cluster_offset + s->cluster_size - 1) & -                    ~(s->cluster_size - 1); -                bdrv_truncate(bs->file, cluster_offset + s->cluster_size); -                /* if encrypted, we must initialize the cluster -                   content which won't be written */ -                if (s->crypt_method && -                    (n_end - n_start) < s->cluster_sectors) { -                    uint64_t start_sect; -                    start_sect = (offset & ~(s->cluster_size - 1)) >> 9; -                    memset(s->cluster_data + 512, 0x00, 512); -                    for(i = 0; i < s->cluster_sectors; i++) { -                        if (i < n_start || i >= n_end) { -                            encrypt_sectors(s, start_sect + i, -                                            s->cluster_data, -                                            s->cluster_data + 512, 1, 1, -                                            &s->aes_encrypt_key); -                            if (bdrv_pwrite(bs->file, cluster_offset + i * 512, -                                            s->cluster_data, 512) != 512) -                                return -1; -                        } -                    } -                } -            } else if (allocate == 2) { -                cluster_offset |= QCOW_OFLAG_COMPRESSED | -                    (uint64_t)compressed_size << (63 - s->cluster_bits); -            } -        } -        /* update L2 table */ -        tmp = cpu_to_be64(cluster_offset); -        l2_table[l2_index] = tmp; -        if (bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp), -                &tmp, sizeof(tmp)) < 0) -            return 0; -    } -    return cluster_offset; -} - -static int coroutine_fn qcow_co_is_allocated(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors, int *pnum) -{ -    BDRVQcowState *s = bs->opaque; -    int index_in_cluster, n; -    uint64_t cluster_offset; - -    qemu_co_mutex_lock(&s->lock); -    cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0); -    qemu_co_mutex_unlock(&s->lock); -    index_in_cluster = sector_num & (s->cluster_sectors - 1); -    n = s->cluster_sectors - index_in_cluster; -    if (n > nb_sectors) -        n = nb_sectors; -    *pnum = n; -    return (cluster_offset != 0); -} - -static int decompress_buffer(uint8_t *out_buf, int out_buf_size, -                             const uint8_t *buf, int buf_size) -{ -    z_stream strm1, *strm = &strm1; -    int ret, out_len; - -    memset(strm, 0, sizeof(*strm)); - -    strm->next_in = (uint8_t *)buf; -    strm->avail_in = buf_size; -    strm->next_out = out_buf; -    strm->avail_out = out_buf_size; - -    ret = inflateInit2(strm, -12); -    if (ret != Z_OK) -        return -1; -    ret = inflate(strm, Z_FINISH); -    out_len = strm->next_out - out_buf; -    if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || -        out_len != out_buf_size) { -        inflateEnd(strm); -        return -1; -    } -    inflateEnd(strm); -    return 0; -} - -static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) -{ -    BDRVQcowState *s = bs->opaque; -    int ret, csize; -    uint64_t coffset; - -    coffset = cluster_offset & s->cluster_offset_mask; -    if (s->cluster_cache_offset != coffset) { -        csize = cluster_offset >> (63 - s->cluster_bits); -        csize &= (s->cluster_size - 1); -        ret = bdrv_pread(bs->file, coffset, s->cluster_data, csize); -        if (ret != csize) -            return -1; -        if (decompress_buffer(s->cluster_cache, s->cluster_size, -                              s->cluster_data, csize) < 0) { -            return -1; -        } -        s->cluster_cache_offset = coffset; -    } -    return 0; -} - -static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num, -                         int nb_sectors, QEMUIOVector *qiov) -{ -    BDRVQcowState *s = bs->opaque; -    int index_in_cluster; -    int ret = 0, n; -    uint64_t cluster_offset; -    struct iovec hd_iov; -    QEMUIOVector hd_qiov; -    uint8_t *buf; -    void *orig_buf; - -    if (qiov->niov > 1) { -        buf = orig_buf = qemu_blockalign(bs, qiov->size); -    } else { -        orig_buf = NULL; -        buf = (uint8_t *)qiov->iov->iov_base; -    } - -    qemu_co_mutex_lock(&s->lock); - -    while (nb_sectors != 0) { -        /* prepare next request */ -        cluster_offset = get_cluster_offset(bs, sector_num << 9, -                                                 0, 0, 0, 0); -        index_in_cluster = sector_num & (s->cluster_sectors - 1); -        n = s->cluster_sectors - index_in_cluster; -        if (n > nb_sectors) { -            n = nb_sectors; -        } - -        if (!cluster_offset) { -            if (bs->backing_hd) { -                /* read from the base image */ -                hd_iov.iov_base = (void *)buf; -                hd_iov.iov_len = n * 512; -                qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); -                qemu_co_mutex_unlock(&s->lock); -                ret = bdrv_co_readv(bs->backing_hd, sector_num, -                                    n, &hd_qiov); -                qemu_co_mutex_lock(&s->lock); -                if (ret < 0) { -                    goto fail; -                } -            } else { -                /* Note: in this case, no need to wait */ -                memset(buf, 0, 512 * n); -            } -        } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { -            /* add AIO support for compressed blocks ? */ -            if (decompress_cluster(bs, cluster_offset) < 0) { -                goto fail; -            } -            memcpy(buf, -                   s->cluster_cache + index_in_cluster * 512, 512 * n); -        } else { -            if ((cluster_offset & 511) != 0) { -                goto fail; -            } -            hd_iov.iov_base = (void *)buf; -            hd_iov.iov_len = n * 512; -            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); -            qemu_co_mutex_unlock(&s->lock); -            ret = bdrv_co_readv(bs->file, -                                (cluster_offset >> 9) + index_in_cluster, -                                n, &hd_qiov); -            qemu_co_mutex_lock(&s->lock); -            if (ret < 0) { -                break; -            } -            if (s->crypt_method) { -                encrypt_sectors(s, sector_num, buf, buf, -                                n, 0, -                                &s->aes_decrypt_key); -            } -        } -        ret = 0; - -        nb_sectors -= n; -        sector_num += n; -        buf += n * 512; -    } - -done: -    qemu_co_mutex_unlock(&s->lock); - -    if (qiov->niov > 1) { -        qemu_iovec_from_buf(qiov, 0, orig_buf, qiov->size); -        qemu_vfree(orig_buf); -    } - -    return ret; - -fail: -    ret = -EIO; -    goto done; -} - -static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, -                          int nb_sectors, QEMUIOVector *qiov) -{ -    BDRVQcowState *s = bs->opaque; -    int index_in_cluster; -    uint64_t cluster_offset; -    const uint8_t *src_buf; -    int ret = 0, n; -    uint8_t *cluster_data = NULL; -    struct iovec hd_iov; -    QEMUIOVector hd_qiov; -    uint8_t *buf; -    void *orig_buf; - -    s->cluster_cache_offset = -1; /* disable compressed cache */ - -    if (qiov->niov > 1) { -        buf = orig_buf = qemu_blockalign(bs, qiov->size); -        qemu_iovec_to_buf(qiov, 0, buf, qiov->size); -    } else { -        orig_buf = NULL; -        buf = (uint8_t *)qiov->iov->iov_base; -    } - -    qemu_co_mutex_lock(&s->lock); - -    while (nb_sectors != 0) { - -        index_in_cluster = sector_num & (s->cluster_sectors - 1); -        n = s->cluster_sectors - index_in_cluster; -        if (n > nb_sectors) { -            n = nb_sectors; -        } -        cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0, -                                            index_in_cluster, -                                            index_in_cluster + n); -        if (!cluster_offset || (cluster_offset & 511) != 0) { -            ret = -EIO; -            break; -        } -        if (s->crypt_method) { -            if (!cluster_data) { -                cluster_data = g_malloc0(s->cluster_size); -            } -            encrypt_sectors(s, sector_num, cluster_data, buf, -                            n, 1, &s->aes_encrypt_key); -            src_buf = cluster_data; -        } else { -            src_buf = buf; -        } - -        hd_iov.iov_base = (void *)src_buf; -        hd_iov.iov_len = n * 512; -        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); -        qemu_co_mutex_unlock(&s->lock); -        ret = bdrv_co_writev(bs->file, -                             (cluster_offset >> 9) + index_in_cluster, -                             n, &hd_qiov); -        qemu_co_mutex_lock(&s->lock); -        if (ret < 0) { -            break; -        } -        ret = 0; - -        nb_sectors -= n; -        sector_num += n; -        buf += n * 512; -    } -    qemu_co_mutex_unlock(&s->lock); - -    if (qiov->niov > 1) { -        qemu_vfree(orig_buf); -    } -    g_free(cluster_data); - -    return ret; -} - -static void qcow_close(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; - -    g_free(s->l1_table); -    g_free(s->l2_cache); -    g_free(s->cluster_cache); -    g_free(s->cluster_data); - -    migrate_del_blocker(s->migration_blocker); -    error_free(s->migration_blocker); -} - -static int qcow_create(const char *filename, QEMUOptionParameter *options) -{ -    int header_size, backing_filename_len, l1_size, shift, i; -    QCowHeader header; -    uint8_t *tmp; -    int64_t total_size = 0; -    const char *backing_file = NULL; -    int flags = 0; -    int ret; -    BlockDriverState *qcow_bs; - -    /* Read out options */ -    while (options && options->name) { -        if (!strcmp(options->name, BLOCK_OPT_SIZE)) { -            total_size = options->value.n / 512; -        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { -            backing_file = options->value.s; -        } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) { -            flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0; -        } -        options++; -    } - -    ret = bdrv_create_file(filename, options); -    if (ret < 0) { -        return ret; -    } - -    ret = bdrv_file_open(&qcow_bs, filename, NULL, BDRV_O_RDWR); -    if (ret < 0) { -        return ret; -    } - -    ret = bdrv_truncate(qcow_bs, 0); -    if (ret < 0) { -        goto exit; -    } - -    memset(&header, 0, sizeof(header)); -    header.magic = cpu_to_be32(QCOW_MAGIC); -    header.version = cpu_to_be32(QCOW_VERSION); -    header.size = cpu_to_be64(total_size * 512); -    header_size = sizeof(header); -    backing_filename_len = 0; -    if (backing_file) { -        if (strcmp(backing_file, "fat:")) { -            header.backing_file_offset = cpu_to_be64(header_size); -            backing_filename_len = strlen(backing_file); -            header.backing_file_size = cpu_to_be32(backing_filename_len); -            header_size += backing_filename_len; -        } else { -            /* special backing file for vvfat */ -            backing_file = NULL; -        } -        header.cluster_bits = 9; /* 512 byte cluster to avoid copying -                                    unmodifyed sectors */ -        header.l2_bits = 12; /* 32 KB L2 tables */ -    } else { -        header.cluster_bits = 12; /* 4 KB clusters */ -        header.l2_bits = 9; /* 4 KB L2 tables */ -    } -    header_size = (header_size + 7) & ~7; -    shift = header.cluster_bits + header.l2_bits; -    l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift; - -    header.l1_table_offset = cpu_to_be64(header_size); -    if (flags & BLOCK_FLAG_ENCRYPT) { -        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES); -    } else { -        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); -    } - -    /* write all the data */ -    ret = bdrv_pwrite(qcow_bs, 0, &header, sizeof(header)); -    if (ret != sizeof(header)) { -        goto exit; -    } - -    if (backing_file) { -        ret = bdrv_pwrite(qcow_bs, sizeof(header), -            backing_file, backing_filename_len); -        if (ret != backing_filename_len) { -            goto exit; -        } -    } - -    tmp = g_malloc0(BDRV_SECTOR_SIZE); -    for (i = 0; i < ((sizeof(uint64_t)*l1_size + BDRV_SECTOR_SIZE - 1)/ -        BDRV_SECTOR_SIZE); i++) { -        ret = bdrv_pwrite(qcow_bs, header_size + -            BDRV_SECTOR_SIZE*i, tmp, BDRV_SECTOR_SIZE); -        if (ret != BDRV_SECTOR_SIZE) { -            g_free(tmp); -            goto exit; -        } -    } - -    g_free(tmp); -    ret = 0; -exit: -    bdrv_delete(qcow_bs); -    return ret; -} - -static int qcow_make_empty(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    uint32_t l1_length = s->l1_size * sizeof(uint64_t); -    int ret; - -    memset(s->l1_table, 0, l1_length); -    if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table, -            l1_length) < 0) -        return -1; -    ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length); -    if (ret < 0) -        return ret; - -    memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); -    memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t)); -    memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t)); - -    return 0; -} - -/* XXX: put compressed sectors first, then all the cluster aligned -   tables to avoid losing bytes in alignment */ -static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num, -                                 const uint8_t *buf, int nb_sectors) -{ -    BDRVQcowState *s = bs->opaque; -    z_stream strm; -    int ret, out_len; -    uint8_t *out_buf; -    uint64_t cluster_offset; - -    if (nb_sectors != s->cluster_sectors) { -        ret = -EINVAL; - -        /* Zero-pad last write if image size is not cluster aligned */ -        if (sector_num + nb_sectors == bs->total_sectors && -            nb_sectors < s->cluster_sectors) { -            uint8_t *pad_buf = qemu_blockalign(bs, s->cluster_size); -            memset(pad_buf, 0, s->cluster_size); -            memcpy(pad_buf, buf, nb_sectors * BDRV_SECTOR_SIZE); -            ret = qcow_write_compressed(bs, sector_num, -                                        pad_buf, s->cluster_sectors); -            qemu_vfree(pad_buf); -        } -        return ret; -    } - -    out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128); - -    /* best compression, small window, no zlib header */ -    memset(&strm, 0, sizeof(strm)); -    ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, -                       Z_DEFLATED, -12, -                       9, Z_DEFAULT_STRATEGY); -    if (ret != 0) { -        ret = -EINVAL; -        goto fail; -    } - -    strm.avail_in = s->cluster_size; -    strm.next_in = (uint8_t *)buf; -    strm.avail_out = s->cluster_size; -    strm.next_out = out_buf; - -    ret = deflate(&strm, Z_FINISH); -    if (ret != Z_STREAM_END && ret != Z_OK) { -        deflateEnd(&strm); -        ret = -EINVAL; -        goto fail; -    } -    out_len = strm.next_out - out_buf; - -    deflateEnd(&strm); - -    if (ret != Z_STREAM_END || out_len >= s->cluster_size) { -        /* could not compress: write normal cluster */ -        ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors); -        if (ret < 0) { -            goto fail; -        } -    } else { -        cluster_offset = get_cluster_offset(bs, sector_num << 9, 2, -                                            out_len, 0, 0); -        if (cluster_offset == 0) { -            ret = -EIO; -            goto fail; -        } - -        cluster_offset &= s->cluster_offset_mask; -        ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len); -        if (ret < 0) { -            goto fail; -        } -    } - -    ret = 0; -fail: -    g_free(out_buf); -    return ret; -} - -static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) -{ -    BDRVQcowState *s = bs->opaque; -    bdi->cluster_size = s->cluster_size; -    return 0; -} - - -static QEMUOptionParameter qcow_create_options[] = { -    { -        .name = BLOCK_OPT_SIZE, -        .type = OPT_SIZE, -        .help = "Virtual disk size" -    }, -    { -        .name = BLOCK_OPT_BACKING_FILE, -        .type = OPT_STRING, -        .help = "File name of a base image" -    }, -    { -        .name = BLOCK_OPT_ENCRYPT, -        .type = OPT_FLAG, -        .help = "Encrypt the image" -    }, -    { NULL } -}; - -static BlockDriver bdrv_qcow = { -    .format_name	= "qcow", -    .instance_size	= sizeof(BDRVQcowState), -    .bdrv_probe		= qcow_probe, -    .bdrv_open		= qcow_open, -    .bdrv_close		= qcow_close, -    .bdrv_reopen_prepare = qcow_reopen_prepare, -    .bdrv_create	= qcow_create, -    .bdrv_has_zero_init     = bdrv_has_zero_init_1, - -    .bdrv_co_readv          = qcow_co_readv, -    .bdrv_co_writev         = qcow_co_writev, -    .bdrv_co_is_allocated   = qcow_co_is_allocated, - -    .bdrv_set_key           = qcow_set_key, -    .bdrv_make_empty        = qcow_make_empty, -    .bdrv_write_compressed  = qcow_write_compressed, -    .bdrv_get_info          = qcow_get_info, - -    .create_options = qcow_create_options, -}; - -static void bdrv_qcow_init(void) -{ -    bdrv_register(&bdrv_qcow); -} - -block_init(bdrv_qcow_init); diff --git a/contrib/qemu/block/qcow2-cache.c b/contrib/qemu/block/qcow2-cache.c deleted file mode 100644 index 2f3114ecc24..00000000000 --- a/contrib/qemu/block/qcow2-cache.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * L2/refcount table cache for the QCOW2 format - * - * Copyright (c) 2010 Kevin Wolf <kwolf@redhat.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "block/block_int.h" -#include "qemu-common.h" -#include "qcow2.h" -#include "trace.h" - -typedef struct Qcow2CachedTable { -    void*   table; -    int64_t offset; -    bool    dirty; -    int     cache_hits; -    int     ref; -} Qcow2CachedTable; - -struct Qcow2Cache { -    Qcow2CachedTable*       entries; -    struct Qcow2Cache*      depends; -    int                     size; -    bool                    depends_on_flush; -}; - -Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables) -{ -    BDRVQcowState *s = bs->opaque; -    Qcow2Cache *c; -    int i; - -    c = g_malloc0(sizeof(*c)); -    c->size = num_tables; -    c->entries = g_malloc0(sizeof(*c->entries) * num_tables); - -    for (i = 0; i < c->size; i++) { -        c->entries[i].table = qemu_blockalign(bs, s->cluster_size); -    } - -    return c; -} - -int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c) -{ -    int i; - -    for (i = 0; i < c->size; i++) { -        assert(c->entries[i].ref == 0); -        qemu_vfree(c->entries[i].table); -    } - -    g_free(c->entries); -    g_free(c); - -    return 0; -} - -static int qcow2_cache_flush_dependency(BlockDriverState *bs, Qcow2Cache *c) -{ -    int ret; - -    ret = qcow2_cache_flush(bs, c->depends); -    if (ret < 0) { -        return ret; -    } - -    c->depends = NULL; -    c->depends_on_flush = false; - -    return 0; -} - -static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i) -{ -    BDRVQcowState *s = bs->opaque; -    int ret = 0; - -    if (!c->entries[i].dirty || !c->entries[i].offset) { -        return 0; -    } - -    trace_qcow2_cache_entry_flush(qemu_coroutine_self(), -                                  c == s->l2_table_cache, i); - -    if (c->depends) { -        ret = qcow2_cache_flush_dependency(bs, c); -    } else if (c->depends_on_flush) { -        ret = bdrv_flush(bs->file); -        if (ret >= 0) { -            c->depends_on_flush = false; -        } -    } - -    if (ret < 0) { -        return ret; -    } - -    if (c == s->refcount_block_cache) { -        BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART); -    } else if (c == s->l2_table_cache) { -        BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE); -    } - -    ret = bdrv_pwrite(bs->file, c->entries[i].offset, c->entries[i].table, -        s->cluster_size); -    if (ret < 0) { -        return ret; -    } - -    c->entries[i].dirty = false; - -    return 0; -} - -int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c) -{ -    BDRVQcowState *s = bs->opaque; -    int result = 0; -    int ret; -    int i; - -    trace_qcow2_cache_flush(qemu_coroutine_self(), c == s->l2_table_cache); - -    for (i = 0; i < c->size; i++) { -        ret = qcow2_cache_entry_flush(bs, c, i); -        if (ret < 0 && result != -ENOSPC) { -            result = ret; -        } -    } - -    if (result == 0) { -        ret = bdrv_flush(bs->file); -        if (ret < 0) { -            result = ret; -        } -    } - -    return result; -} - -int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c, -    Qcow2Cache *dependency) -{ -    int ret; - -    if (dependency->depends) { -        ret = qcow2_cache_flush_dependency(bs, dependency); -        if (ret < 0) { -            return ret; -        } -    } - -    if (c->depends && (c->depends != dependency)) { -        ret = qcow2_cache_flush_dependency(bs, c); -        if (ret < 0) { -            return ret; -        } -    } - -    c->depends = dependency; -    return 0; -} - -void qcow2_cache_depends_on_flush(Qcow2Cache *c) -{ -    c->depends_on_flush = true; -} - -static int qcow2_cache_find_entry_to_replace(Qcow2Cache *c) -{ -    int i; -    int min_count = INT_MAX; -    int min_index = -1; - - -    for (i = 0; i < c->size; i++) { -        if (c->entries[i].ref) { -            continue; -        } - -        if (c->entries[i].cache_hits < min_count) { -            min_index = i; -            min_count = c->entries[i].cache_hits; -        } - -        /* Give newer hits priority */ -        /* TODO Check how to optimize the replacement strategy */ -        c->entries[i].cache_hits /= 2; -    } - -    if (min_index == -1) { -        /* This can't happen in current synchronous code, but leave the check -         * here as a reminder for whoever starts using AIO with the cache */ -        abort(); -    } -    return min_index; -} - -static int qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c, -    uint64_t offset, void **table, bool read_from_disk) -{ -    BDRVQcowState *s = bs->opaque; -    int i; -    int ret; - -    trace_qcow2_cache_get(qemu_coroutine_self(), c == s->l2_table_cache, -                          offset, read_from_disk); - -    /* Check if the table is already cached */ -    for (i = 0; i < c->size; i++) { -        if (c->entries[i].offset == offset) { -            goto found; -        } -    } - -    /* If not, write a table back and replace it */ -    i = qcow2_cache_find_entry_to_replace(c); -    trace_qcow2_cache_get_replace_entry(qemu_coroutine_self(), -                                        c == s->l2_table_cache, i); -    if (i < 0) { -        return i; -    } - -    ret = qcow2_cache_entry_flush(bs, c, i); -    if (ret < 0) { -        return ret; -    } - -    trace_qcow2_cache_get_read(qemu_coroutine_self(), -                               c == s->l2_table_cache, i); -    c->entries[i].offset = 0; -    if (read_from_disk) { -        if (c == s->l2_table_cache) { -            BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD); -        } - -        ret = bdrv_pread(bs->file, offset, c->entries[i].table, s->cluster_size); -        if (ret < 0) { -            return ret; -        } -    } - -    /* Give the table some hits for the start so that it won't be replaced -     * immediately. The number 32 is completely arbitrary. */ -    c->entries[i].cache_hits = 32; -    c->entries[i].offset = offset; - -    /* And return the right table */ -found: -    c->entries[i].cache_hits++; -    c->entries[i].ref++; -    *table = c->entries[i].table; - -    trace_qcow2_cache_get_done(qemu_coroutine_self(), -                               c == s->l2_table_cache, i); - -    return 0; -} - -int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, -    void **table) -{ -    return qcow2_cache_do_get(bs, c, offset, table, true); -} - -int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, -    void **table) -{ -    return qcow2_cache_do_get(bs, c, offset, table, false); -} - -int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table) -{ -    int i; - -    for (i = 0; i < c->size; i++) { -        if (c->entries[i].table == *table) { -            goto found; -        } -    } -    return -ENOENT; - -found: -    c->entries[i].ref--; -    *table = NULL; - -    assert(c->entries[i].ref >= 0); -    return 0; -} - -void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table) -{ -    int i; - -    for (i = 0; i < c->size; i++) { -        if (c->entries[i].table == table) { -            goto found; -        } -    } -    abort(); - -found: -    c->entries[i].dirty = true; -} diff --git a/contrib/qemu/block/qcow2-cluster.c b/contrib/qemu/block/qcow2-cluster.c deleted file mode 100644 index cca76d4fcdd..00000000000 --- a/contrib/qemu/block/qcow2-cluster.c +++ /dev/null @@ -1,1478 +0,0 @@ -/* - * Block driver for the QCOW version 2 format - * - * Copyright (c) 2004-2006 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include <zlib.h> - -#include "qemu-common.h" -#include "block/block_int.h" -#include "block/qcow2.h" -#include "trace.h" - -int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, -                        bool exact_size) -{ -    BDRVQcowState *s = bs->opaque; -    int new_l1_size2, ret, i; -    uint64_t *new_l1_table; -    int64_t new_l1_table_offset, new_l1_size; -    uint8_t data[12]; - -    if (min_size <= s->l1_size) -        return 0; - -    if (exact_size) { -        new_l1_size = min_size; -    } else { -        /* Bump size up to reduce the number of times we have to grow */ -        new_l1_size = s->l1_size; -        if (new_l1_size == 0) { -            new_l1_size = 1; -        } -        while (min_size > new_l1_size) { -            new_l1_size = (new_l1_size * 3 + 1) / 2; -        } -    } - -    if (new_l1_size > INT_MAX) { -        return -EFBIG; -    } - -#ifdef DEBUG_ALLOC2 -    fprintf(stderr, "grow l1_table from %d to %" PRId64 "\n", -            s->l1_size, new_l1_size); -#endif - -    new_l1_size2 = sizeof(uint64_t) * new_l1_size; -    new_l1_table = g_malloc0(align_offset(new_l1_size2, 512)); -    memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t)); - -    /* write new table (align to cluster) */ -    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE); -    new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2); -    if (new_l1_table_offset < 0) { -        g_free(new_l1_table); -        return new_l1_table_offset; -    } - -    ret = qcow2_cache_flush(bs, s->refcount_block_cache); -    if (ret < 0) { -        goto fail; -    } - -    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE); -    for(i = 0; i < s->l1_size; i++) -        new_l1_table[i] = cpu_to_be64(new_l1_table[i]); -    ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2); -    if (ret < 0) -        goto fail; -    for(i = 0; i < s->l1_size; i++) -        new_l1_table[i] = be64_to_cpu(new_l1_table[i]); - -    /* set new table */ -    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE); -    cpu_to_be32w((uint32_t*)data, new_l1_size); -    cpu_to_be64wu((uint64_t*)(data + 4), new_l1_table_offset); -    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data)); -    if (ret < 0) { -        goto fail; -    } -    g_free(s->l1_table); -    qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t), -                        QCOW2_DISCARD_OTHER); -    s->l1_table_offset = new_l1_table_offset; -    s->l1_table = new_l1_table; -    s->l1_size = new_l1_size; -    return 0; - fail: -    g_free(new_l1_table); -    qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2, -                        QCOW2_DISCARD_OTHER); -    return ret; -} - -/* - * l2_load - * - * Loads a L2 table into memory. If the table is in the cache, the cache - * is used; otherwise the L2 table is loaded from the image file. - * - * Returns a pointer to the L2 table on success, or NULL if the read from - * the image file failed. - */ - -static int l2_load(BlockDriverState *bs, uint64_t l2_offset, -    uint64_t **l2_table) -{ -    BDRVQcowState *s = bs->opaque; -    int ret; - -    ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset, (void**) l2_table); - -    return ret; -} - -/* - * Writes one sector of the L1 table to the disk (can't update single entries - * and we really don't want bdrv_pread to perform a read-modify-write) - */ -#define L1_ENTRIES_PER_SECTOR (512 / 8) -static int write_l1_entry(BlockDriverState *bs, int l1_index) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t buf[L1_ENTRIES_PER_SECTOR]; -    int l1_start_index; -    int i, ret; - -    l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1); -    for (i = 0; i < L1_ENTRIES_PER_SECTOR; i++) { -        buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]); -    } - -    BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE); -    ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index, -        buf, sizeof(buf)); -    if (ret < 0) { -        return ret; -    } - -    return 0; -} - -/* - * l2_allocate - * - * Allocate a new l2 entry in the file. If l1_index points to an already - * used entry in the L2 table (i.e. we are doing a copy on write for the L2 - * table) copy the contents of the old L2 table into the newly allocated one. - * Otherwise the new table is initialized with zeros. - * - */ - -static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t old_l2_offset; -    uint64_t *l2_table; -    int64_t l2_offset; -    int ret; - -    old_l2_offset = s->l1_table[l1_index]; - -    trace_qcow2_l2_allocate(bs, l1_index); - -    /* allocate a new l2 entry */ - -    l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t)); -    if (l2_offset < 0) { -        return l2_offset; -    } - -    ret = qcow2_cache_flush(bs, s->refcount_block_cache); -    if (ret < 0) { -        goto fail; -    } - -    /* allocate a new entry in the l2 cache */ - -    trace_qcow2_l2_allocate_get_empty(bs, l1_index); -    ret = qcow2_cache_get_empty(bs, s->l2_table_cache, l2_offset, (void**) table); -    if (ret < 0) { -        return ret; -    } - -    l2_table = *table; - -    if ((old_l2_offset & L1E_OFFSET_MASK) == 0) { -        /* if there was no old l2 table, clear the new table */ -        memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); -    } else { -        uint64_t* old_table; - -        /* if there was an old l2 table, read it from the disk */ -        BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_COW_READ); -        ret = qcow2_cache_get(bs, s->l2_table_cache, -            old_l2_offset & L1E_OFFSET_MASK, -            (void**) &old_table); -        if (ret < 0) { -            goto fail; -        } - -        memcpy(l2_table, old_table, s->cluster_size); - -        ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &old_table); -        if (ret < 0) { -            goto fail; -        } -    } - -    /* write the l2 table to the file */ -    BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE); - -    trace_qcow2_l2_allocate_write_l2(bs, l1_index); -    qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); -    ret = qcow2_cache_flush(bs, s->l2_table_cache); -    if (ret < 0) { -        goto fail; -    } - -    /* update the L1 entry */ -    trace_qcow2_l2_allocate_write_l1(bs, l1_index); -    s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED; -    ret = write_l1_entry(bs, l1_index); -    if (ret < 0) { -        goto fail; -    } - -    *table = l2_table; -    trace_qcow2_l2_allocate_done(bs, l1_index, 0); -    return 0; - -fail: -    trace_qcow2_l2_allocate_done(bs, l1_index, ret); -    qcow2_cache_put(bs, s->l2_table_cache, (void**) table); -    s->l1_table[l1_index] = old_l2_offset; -    return ret; -} - -/* - * Checks how many clusters in a given L2 table are contiguous in the image - * file. As soon as one of the flags in the bitmask stop_flags changes compared - * to the first cluster, the search is stopped and the cluster is not counted - * as contiguous. (This allows it, for example, to stop at the first compressed - * cluster which may require a different handling) - */ -static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size, -        uint64_t *l2_table, uint64_t start, uint64_t stop_flags) -{ -    int i; -    uint64_t mask = stop_flags | L2E_OFFSET_MASK; -    uint64_t offset = be64_to_cpu(l2_table[0]) & mask; - -    if (!offset) -        return 0; - -    for (i = start; i < start + nb_clusters; i++) { -        uint64_t l2_entry = be64_to_cpu(l2_table[i]) & mask; -        if (offset + (uint64_t) i * cluster_size != l2_entry) { -            break; -        } -    } - -	return (i - start); -} - -static int count_contiguous_free_clusters(uint64_t nb_clusters, uint64_t *l2_table) -{ -    int i; - -    for (i = 0; i < nb_clusters; i++) { -        int type = qcow2_get_cluster_type(be64_to_cpu(l2_table[i])); - -        if (type != QCOW2_CLUSTER_UNALLOCATED) { -            break; -        } -    } - -    return i; -} - -/* The crypt function is compatible with the linux cryptoloop -   algorithm for < 4 GB images. NOTE: out_buf == in_buf is -   supported */ -void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num, -                           uint8_t *out_buf, const uint8_t *in_buf, -                           int nb_sectors, int enc, -                           const AES_KEY *key) -{ -    union { -        uint64_t ll[2]; -        uint8_t b[16]; -    } ivec; -    int i; - -    for(i = 0; i < nb_sectors; i++) { -        ivec.ll[0] = cpu_to_le64(sector_num); -        ivec.ll[1] = 0; -        AES_cbc_encrypt(in_buf, out_buf, 512, key, -                        ivec.b, enc); -        sector_num++; -        in_buf += 512; -        out_buf += 512; -    } -} - -static int coroutine_fn copy_sectors(BlockDriverState *bs, -                                     uint64_t start_sect, -                                     uint64_t cluster_offset, -                                     int n_start, int n_end) -{ -    BDRVQcowState *s = bs->opaque; -    QEMUIOVector qiov; -    struct iovec iov; -    int n, ret; - -    /* -     * If this is the last cluster and it is only partially used, we must only -     * copy until the end of the image, or bdrv_check_request will fail for the -     * bdrv_read/write calls below. -     */ -    if (start_sect + n_end > bs->total_sectors) { -        n_end = bs->total_sectors - start_sect; -    } - -    n = n_end - n_start; -    if (n <= 0) { -        return 0; -    } - -    iov.iov_len = n * BDRV_SECTOR_SIZE; -    iov.iov_base = qemu_blockalign(bs, iov.iov_len); - -    qemu_iovec_init_external(&qiov, &iov, 1); - -    BLKDBG_EVENT(bs->file, BLKDBG_COW_READ); - -    /* Call .bdrv_co_readv() directly instead of using the public block-layer -     * interface.  This avoids double I/O throttling and request tracking, -     * which can lead to deadlock when block layer copy-on-read is enabled. -     */ -    ret = bs->drv->bdrv_co_readv(bs, start_sect + n_start, n, &qiov); -    if (ret < 0) { -        goto out; -    } - -    if (s->crypt_method) { -        qcow2_encrypt_sectors(s, start_sect + n_start, -                        iov.iov_base, iov.iov_base, n, 1, -                        &s->aes_encrypt_key); -    } - -    BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE); -    ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + n_start, n, &qiov); -    if (ret < 0) { -        goto out; -    } - -    ret = 0; -out: -    qemu_vfree(iov.iov_base); -    return ret; -} - - -/* - * get_cluster_offset - * - * For a given offset of the disk image, find the cluster offset in - * qcow2 file. The offset is stored in *cluster_offset. - * - * on entry, *num is the number of contiguous sectors we'd like to - * access following offset. - * - * on exit, *num is the number of contiguous sectors we can read. - * - * Returns the cluster type (QCOW2_CLUSTER_*) on success, -errno in error - * cases. - */ -int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, -    int *num, uint64_t *cluster_offset) -{ -    BDRVQcowState *s = bs->opaque; -    unsigned int l2_index; -    uint64_t l1_index, l2_offset, *l2_table; -    int l1_bits, c; -    unsigned int index_in_cluster, nb_clusters; -    uint64_t nb_available, nb_needed; -    int ret; - -    index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1); -    nb_needed = *num + index_in_cluster; - -    l1_bits = s->l2_bits + s->cluster_bits; - -    /* compute how many bytes there are between the offset and -     * the end of the l1 entry -     */ - -    nb_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1)); - -    /* compute the number of available sectors */ - -    nb_available = (nb_available >> 9) + index_in_cluster; - -    if (nb_needed > nb_available) { -        nb_needed = nb_available; -    } - -    *cluster_offset = 0; - -    /* seek the the l2 offset in the l1 table */ - -    l1_index = offset >> l1_bits; -    if (l1_index >= s->l1_size) { -        ret = QCOW2_CLUSTER_UNALLOCATED; -        goto out; -    } - -    l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK; -    if (!l2_offset) { -        ret = QCOW2_CLUSTER_UNALLOCATED; -        goto out; -    } - -    /* load the l2 table in memory */ - -    ret = l2_load(bs, l2_offset, &l2_table); -    if (ret < 0) { -        return ret; -    } - -    /* find the cluster offset for the given disk offset */ - -    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1); -    *cluster_offset = be64_to_cpu(l2_table[l2_index]); -    nb_clusters = size_to_clusters(s, nb_needed << 9); - -    ret = qcow2_get_cluster_type(*cluster_offset); -    switch (ret) { -    case QCOW2_CLUSTER_COMPRESSED: -        /* Compressed clusters can only be processed one by one */ -        c = 1; -        *cluster_offset &= L2E_COMPRESSED_OFFSET_SIZE_MASK; -        break; -    case QCOW2_CLUSTER_ZERO: -        if (s->qcow_version < 3) { -            return -EIO; -        } -        c = count_contiguous_clusters(nb_clusters, s->cluster_size, -                &l2_table[l2_index], 0, -                QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO); -        *cluster_offset = 0; -        break; -    case QCOW2_CLUSTER_UNALLOCATED: -        /* how many empty clusters ? */ -        c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]); -        *cluster_offset = 0; -        break; -    case QCOW2_CLUSTER_NORMAL: -        /* how many allocated clusters ? */ -        c = count_contiguous_clusters(nb_clusters, s->cluster_size, -                &l2_table[l2_index], 0, -                QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO); -        *cluster_offset &= L2E_OFFSET_MASK; -        break; -    default: -        abort(); -    } - -    qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); - -    nb_available = (c * s->cluster_sectors); - -out: -    if (nb_available > nb_needed) -        nb_available = nb_needed; - -    *num = nb_available - index_in_cluster; - -    return ret; -} - -/* - * get_cluster_table - * - * for a given disk offset, load (and allocate if needed) - * the l2 table. - * - * the l2 table offset in the qcow2 file and the cluster index - * in the l2 table are given to the caller. - * - * Returns 0 on success, -errno in failure case - */ -static int get_cluster_table(BlockDriverState *bs, uint64_t offset, -                             uint64_t **new_l2_table, -                             int *new_l2_index) -{ -    BDRVQcowState *s = bs->opaque; -    unsigned int l2_index; -    uint64_t l1_index, l2_offset; -    uint64_t *l2_table = NULL; -    int ret; - -    /* seek the the l2 offset in the l1 table */ - -    l1_index = offset >> (s->l2_bits + s->cluster_bits); -    if (l1_index >= s->l1_size) { -        ret = qcow2_grow_l1_table(bs, l1_index + 1, false); -        if (ret < 0) { -            return ret; -        } -    } - -    assert(l1_index < s->l1_size); -    l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK; - -    /* seek the l2 table of the given l2 offset */ - -    if (s->l1_table[l1_index] & QCOW_OFLAG_COPIED) { -        /* load the l2 table in memory */ -        ret = l2_load(bs, l2_offset, &l2_table); -        if (ret < 0) { -            return ret; -        } -    } else { -        /* First allocate a new L2 table (and do COW if needed) */ -        ret = l2_allocate(bs, l1_index, &l2_table); -        if (ret < 0) { -            return ret; -        } - -        /* Then decrease the refcount of the old table */ -        if (l2_offset) { -            qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t), -                                QCOW2_DISCARD_OTHER); -        } -    } - -    /* find the cluster offset for the given disk offset */ - -    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1); - -    *new_l2_table = l2_table; -    *new_l2_index = l2_index; - -    return 0; -} - -/* - * alloc_compressed_cluster_offset - * - * For a given offset of the disk image, return cluster offset in - * qcow2 file. - * - * If the offset is not found, allocate a new compressed cluster. - * - * Return the cluster offset if successful, - * Return 0, otherwise. - * - */ - -uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, -                                               uint64_t offset, -                                               int compressed_size) -{ -    BDRVQcowState *s = bs->opaque; -    int l2_index, ret; -    uint64_t *l2_table; -    int64_t cluster_offset; -    int nb_csectors; - -    ret = get_cluster_table(bs, offset, &l2_table, &l2_index); -    if (ret < 0) { -        return 0; -    } - -    /* Compression can't overwrite anything. Fail if the cluster was already -     * allocated. */ -    cluster_offset = be64_to_cpu(l2_table[l2_index]); -    if (cluster_offset & L2E_OFFSET_MASK) { -        qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -        return 0; -    } - -    cluster_offset = qcow2_alloc_bytes(bs, compressed_size); -    if (cluster_offset < 0) { -        qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -        return 0; -    } - -    nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) - -                  (cluster_offset >> 9); - -    cluster_offset |= QCOW_OFLAG_COMPRESSED | -                      ((uint64_t)nb_csectors << s->csize_shift); - -    /* update L2 table */ - -    /* compressed clusters never have the copied flag */ - -    BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED); -    qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); -    l2_table[l2_index] = cpu_to_be64(cluster_offset); -    ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -    if (ret < 0) { -        return 0; -    } - -    return cluster_offset; -} - -static int perform_cow(BlockDriverState *bs, QCowL2Meta *m, Qcow2COWRegion *r) -{ -    BDRVQcowState *s = bs->opaque; -    int ret; - -    if (r->nb_sectors == 0) { -        return 0; -    } - -    qemu_co_mutex_unlock(&s->lock); -    ret = copy_sectors(bs, m->offset / BDRV_SECTOR_SIZE, m->alloc_offset, -                       r->offset / BDRV_SECTOR_SIZE, -                       r->offset / BDRV_SECTOR_SIZE + r->nb_sectors); -    qemu_co_mutex_lock(&s->lock); - -    if (ret < 0) { -        return ret; -    } - -    /* -     * Before we update the L2 table to actually point to the new cluster, we -     * need to be sure that the refcounts have been increased and COW was -     * handled. -     */ -    qcow2_cache_depends_on_flush(s->l2_table_cache); - -    return 0; -} - -int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m) -{ -    BDRVQcowState *s = bs->opaque; -    int i, j = 0, l2_index, ret; -    uint64_t *old_cluster, *l2_table; -    uint64_t cluster_offset = m->alloc_offset; - -    trace_qcow2_cluster_link_l2(qemu_coroutine_self(), m->nb_clusters); -    assert(m->nb_clusters > 0); - -    old_cluster = g_malloc(m->nb_clusters * sizeof(uint64_t)); - -    /* copy content of unmodified sectors */ -    ret = perform_cow(bs, m, &m->cow_start); -    if (ret < 0) { -        goto err; -    } - -    ret = perform_cow(bs, m, &m->cow_end); -    if (ret < 0) { -        goto err; -    } - -    /* Update L2 table. */ -    if (s->use_lazy_refcounts) { -        qcow2_mark_dirty(bs); -    } -    if (qcow2_need_accurate_refcounts(s)) { -        qcow2_cache_set_dependency(bs, s->l2_table_cache, -                                   s->refcount_block_cache); -    } - -    ret = get_cluster_table(bs, m->offset, &l2_table, &l2_index); -    if (ret < 0) { -        goto err; -    } -    qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); - -    for (i = 0; i < m->nb_clusters; i++) { -        /* if two concurrent writes happen to the same unallocated cluster -	 * each write allocates separate cluster and writes data concurrently. -	 * The first one to complete updates l2 table with pointer to its -	 * cluster the second one has to do RMW (which is done above by -	 * copy_sectors()), update l2 table with its cluster pointer and free -	 * old cluster. This is what this loop does */ -        if(l2_table[l2_index + i] != 0) -            old_cluster[j++] = l2_table[l2_index + i]; - -        l2_table[l2_index + i] = cpu_to_be64((cluster_offset + -                    (i << s->cluster_bits)) | QCOW_OFLAG_COPIED); -     } - - -    ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -    if (ret < 0) { -        goto err; -    } - -    /* -     * If this was a COW, we need to decrease the refcount of the old cluster. -     * Also flush bs->file to get the right order for L2 and refcount update. -     * -     * Don't discard clusters that reach a refcount of 0 (e.g. compressed -     * clusters), the next write will reuse them anyway. -     */ -    if (j != 0) { -        for (i = 0; i < j; i++) { -            qcow2_free_any_clusters(bs, be64_to_cpu(old_cluster[i]), 1, -                                    QCOW2_DISCARD_NEVER); -        } -    } - -    ret = 0; -err: -    g_free(old_cluster); -    return ret; - } - -/* - * Returns the number of contiguous clusters that can be used for an allocating - * write, but require COW to be performed (this includes yet unallocated space, - * which must copy from the backing file) - */ -static int count_cow_clusters(BDRVQcowState *s, int nb_clusters, -    uint64_t *l2_table, int l2_index) -{ -    int i; - -    for (i = 0; i < nb_clusters; i++) { -        uint64_t l2_entry = be64_to_cpu(l2_table[l2_index + i]); -        int cluster_type = qcow2_get_cluster_type(l2_entry); - -        switch(cluster_type) { -        case QCOW2_CLUSTER_NORMAL: -            if (l2_entry & QCOW_OFLAG_COPIED) { -                goto out; -            } -            break; -        case QCOW2_CLUSTER_UNALLOCATED: -        case QCOW2_CLUSTER_COMPRESSED: -        case QCOW2_CLUSTER_ZERO: -            break; -        default: -            abort(); -        } -    } - -out: -    assert(i <= nb_clusters); -    return i; -} - -/* - * Check if there already is an AIO write request in flight which allocates - * the same cluster. In this case we need to wait until the previous - * request has completed and updated the L2 table accordingly. - * - * Returns: - *   0       if there was no dependency. *cur_bytes indicates the number of - *           bytes from guest_offset that can be read before the next - *           dependency must be processed (or the request is complete) - * - *   -EAGAIN if we had to wait for another request, previously gathered - *           information on cluster allocation may be invalid now. The caller - *           must start over anyway, so consider *cur_bytes undefined. - */ -static int handle_dependencies(BlockDriverState *bs, uint64_t guest_offset, -    uint64_t *cur_bytes, QCowL2Meta **m) -{ -    BDRVQcowState *s = bs->opaque; -    QCowL2Meta *old_alloc; -    uint64_t bytes = *cur_bytes; - -    QLIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) { - -        uint64_t start = guest_offset; -        uint64_t end = start + bytes; -        uint64_t old_start = l2meta_cow_start(old_alloc); -        uint64_t old_end = l2meta_cow_end(old_alloc); - -        if (end <= old_start || start >= old_end) { -            /* No intersection */ -        } else { -            if (start < old_start) { -                /* Stop at the start of a running allocation */ -                bytes = old_start - start; -            } else { -                bytes = 0; -            } - -            /* Stop if already an l2meta exists. After yielding, it wouldn't -             * be valid any more, so we'd have to clean up the old L2Metas -             * and deal with requests depending on them before starting to -             * gather new ones. Not worth the trouble. */ -            if (bytes == 0 && *m) { -                *cur_bytes = 0; -                return 0; -            } - -            if (bytes == 0) { -                /* Wait for the dependency to complete. We need to recheck -                 * the free/allocated clusters when we continue. */ -                qemu_co_mutex_unlock(&s->lock); -                qemu_co_queue_wait(&old_alloc->dependent_requests); -                qemu_co_mutex_lock(&s->lock); -                return -EAGAIN; -            } -        } -    } - -    /* Make sure that existing clusters and new allocations are only used up to -     * the next dependency if we shortened the request above */ -    *cur_bytes = bytes; - -    return 0; -} - -/* - * Checks how many already allocated clusters that don't require a copy on - * write there are at the given guest_offset (up to *bytes). If - * *host_offset is not zero, only physically contiguous clusters beginning at - * this host offset are counted. - * - * Note that guest_offset may not be cluster aligned. In this case, the - * returned *host_offset points to exact byte referenced by guest_offset and - * therefore isn't cluster aligned as well. - * - * Returns: - *   0:     if no allocated clusters are available at the given offset. - *          *bytes is normally unchanged. It is set to 0 if the cluster - *          is allocated and doesn't need COW, but doesn't have the right - *          physical offset. - * - *   1:     if allocated clusters that don't require a COW are available at - *          the requested offset. *bytes may have decreased and describes - *          the length of the area that can be written to. - * - *  -errno: in error cases - */ -static int handle_copied(BlockDriverState *bs, uint64_t guest_offset, -    uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) -{ -    BDRVQcowState *s = bs->opaque; -    int l2_index; -    uint64_t cluster_offset; -    uint64_t *l2_table; -    unsigned int nb_clusters; -    unsigned int keep_clusters; -    int ret, pret; - -    trace_qcow2_handle_copied(qemu_coroutine_self(), guest_offset, *host_offset, -                              *bytes); - -    assert(*host_offset == 0 ||    offset_into_cluster(s, guest_offset) -                                == offset_into_cluster(s, *host_offset)); - -    /* -     * Calculate the number of clusters to look for. We stop at L2 table -     * boundaries to keep things simple. -     */ -    nb_clusters = -        size_to_clusters(s, offset_into_cluster(s, guest_offset) + *bytes); - -    l2_index = offset_to_l2_index(s, guest_offset); -    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); - -    /* Find L2 entry for the first involved cluster */ -    ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index); -    if (ret < 0) { -        return ret; -    } - -    cluster_offset = be64_to_cpu(l2_table[l2_index]); - -    /* Check how many clusters are already allocated and don't need COW */ -    if (qcow2_get_cluster_type(cluster_offset) == QCOW2_CLUSTER_NORMAL -        && (cluster_offset & QCOW_OFLAG_COPIED)) -    { -        /* If a specific host_offset is required, check it */ -        bool offset_matches = -            (cluster_offset & L2E_OFFSET_MASK) == *host_offset; - -        if (*host_offset != 0 && !offset_matches) { -            *bytes = 0; -            ret = 0; -            goto out; -        } - -        /* We keep all QCOW_OFLAG_COPIED clusters */ -        keep_clusters = -            count_contiguous_clusters(nb_clusters, s->cluster_size, -                                      &l2_table[l2_index], 0, -                                      QCOW_OFLAG_COPIED | QCOW_OFLAG_ZERO); -        assert(keep_clusters <= nb_clusters); - -        *bytes = MIN(*bytes, -                 keep_clusters * s->cluster_size -                 - offset_into_cluster(s, guest_offset)); - -        ret = 1; -    } else { -        ret = 0; -    } - -    /* Cleanup */ -out: -    pret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -    if (pret < 0) { -        return pret; -    } - -    /* Only return a host offset if we actually made progress. Otherwise we -     * would make requirements for handle_alloc() that it can't fulfill */ -    if (ret) { -        *host_offset = (cluster_offset & L2E_OFFSET_MASK) -                     + offset_into_cluster(s, guest_offset); -    } - -    return ret; -} - -/* - * Allocates new clusters for the given guest_offset. - * - * At most *nb_clusters are allocated, and on return *nb_clusters is updated to - * contain the number of clusters that have been allocated and are contiguous - * in the image file. - * - * If *host_offset is non-zero, it specifies the offset in the image file at - * which the new clusters must start. *nb_clusters can be 0 on return in this - * case if the cluster at host_offset is already in use. If *host_offset is - * zero, the clusters can be allocated anywhere in the image file. - * - * *host_offset is updated to contain the offset into the image file at which - * the first allocated cluster starts. - * - * Return 0 on success and -errno in error cases. -EAGAIN means that the - * function has been waiting for another request and the allocation must be - * restarted, but the whole request should not be failed. - */ -static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset, -    uint64_t *host_offset, unsigned int *nb_clusters) -{ -    BDRVQcowState *s = bs->opaque; - -    trace_qcow2_do_alloc_clusters_offset(qemu_coroutine_self(), guest_offset, -                                         *host_offset, *nb_clusters); - -    /* Allocate new clusters */ -    trace_qcow2_cluster_alloc_phys(qemu_coroutine_self()); -    if (*host_offset == 0) { -        int64_t cluster_offset = -            qcow2_alloc_clusters(bs, *nb_clusters * s->cluster_size); -        if (cluster_offset < 0) { -            return cluster_offset; -        } -        *host_offset = cluster_offset; -        return 0; -    } else { -        int ret = qcow2_alloc_clusters_at(bs, *host_offset, *nb_clusters); -        if (ret < 0) { -            return ret; -        } -        *nb_clusters = ret; -        return 0; -    } -} - -/* - * Allocates new clusters for an area that either is yet unallocated or needs a - * copy on write. If *host_offset is non-zero, clusters are only allocated if - * the new allocation can match the specified host offset. - * - * Note that guest_offset may not be cluster aligned. In this case, the - * returned *host_offset points to exact byte referenced by guest_offset and - * therefore isn't cluster aligned as well. - * - * Returns: - *   0:     if no clusters could be allocated. *bytes is set to 0, - *          *host_offset is left unchanged. - * - *   1:     if new clusters were allocated. *bytes may be decreased if the - *          new allocation doesn't cover all of the requested area. - *          *host_offset is updated to contain the host offset of the first - *          newly allocated cluster. - * - *  -errno: in error cases - */ -static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset, -    uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) -{ -    BDRVQcowState *s = bs->opaque; -    int l2_index; -    uint64_t *l2_table; -    uint64_t entry; -    unsigned int nb_clusters; -    int ret; - -    uint64_t alloc_cluster_offset; - -    trace_qcow2_handle_alloc(qemu_coroutine_self(), guest_offset, *host_offset, -                             *bytes); -    assert(*bytes > 0); - -    /* -     * Calculate the number of clusters to look for. We stop at L2 table -     * boundaries to keep things simple. -     */ -    nb_clusters = -        size_to_clusters(s, offset_into_cluster(s, guest_offset) + *bytes); - -    l2_index = offset_to_l2_index(s, guest_offset); -    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); - -    /* Find L2 entry for the first involved cluster */ -    ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index); -    if (ret < 0) { -        return ret; -    } - -    entry = be64_to_cpu(l2_table[l2_index]); - -    /* For the moment, overwrite compressed clusters one by one */ -    if (entry & QCOW_OFLAG_COMPRESSED) { -        nb_clusters = 1; -    } else { -        nb_clusters = count_cow_clusters(s, nb_clusters, l2_table, l2_index); -    } - -    /* This function is only called when there were no non-COW clusters, so if -     * we can't find any unallocated or COW clusters either, something is -     * wrong with our code. */ -    assert(nb_clusters > 0); - -    ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -    if (ret < 0) { -        return ret; -    } - -    /* Allocate, if necessary at a given offset in the image file */ -    alloc_cluster_offset = start_of_cluster(s, *host_offset); -    ret = do_alloc_cluster_offset(bs, guest_offset, &alloc_cluster_offset, -                                  &nb_clusters); -    if (ret < 0) { -        goto fail; -    } - -    /* Can't extend contiguous allocation */ -    if (nb_clusters == 0) { -        *bytes = 0; -        return 0; -    } - -    /* -     * Save info needed for meta data update. -     * -     * requested_sectors: Number of sectors from the start of the first -     * newly allocated cluster to the end of the (possibly shortened -     * before) write request. -     * -     * avail_sectors: Number of sectors from the start of the first -     * newly allocated to the end of the last newly allocated cluster. -     * -     * nb_sectors: The number of sectors from the start of the first -     * newly allocated cluster to the end of the area that the write -     * request actually writes to (excluding COW at the end) -     */ -    int requested_sectors = -        (*bytes + offset_into_cluster(s, guest_offset)) -        >> BDRV_SECTOR_BITS; -    int avail_sectors = nb_clusters -                        << (s->cluster_bits - BDRV_SECTOR_BITS); -    int alloc_n_start = offset_into_cluster(s, guest_offset) -                        >> BDRV_SECTOR_BITS; -    int nb_sectors = MIN(requested_sectors, avail_sectors); -    QCowL2Meta *old_m = *m; - -    *m = g_malloc0(sizeof(**m)); - -    **m = (QCowL2Meta) { -        .next           = old_m, - -        .alloc_offset   = alloc_cluster_offset, -        .offset         = start_of_cluster(s, guest_offset), -        .nb_clusters    = nb_clusters, -        .nb_available   = nb_sectors, - -        .cow_start = { -            .offset     = 0, -            .nb_sectors = alloc_n_start, -        }, -        .cow_end = { -            .offset     = nb_sectors * BDRV_SECTOR_SIZE, -            .nb_sectors = avail_sectors - nb_sectors, -        }, -    }; -    qemu_co_queue_init(&(*m)->dependent_requests); -    QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight); - -    *host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset); -    *bytes = MIN(*bytes, (nb_sectors * BDRV_SECTOR_SIZE) -                         - offset_into_cluster(s, guest_offset)); -    assert(*bytes != 0); - -    return 1; - -fail: -    if (*m && (*m)->nb_clusters > 0) { -        QLIST_REMOVE(*m, next_in_flight); -    } -    return ret; -} - -/* - * alloc_cluster_offset - * - * For a given offset on the virtual disk, find the cluster offset in qcow2 - * file. If the offset is not found, allocate a new cluster. - * - * If the cluster was already allocated, m->nb_clusters is set to 0 and - * other fields in m are meaningless. - * - * If the cluster is newly allocated, m->nb_clusters is set to the number of - * contiguous clusters that have been allocated. In this case, the other - * fields of m are valid and contain information about the first allocated - * cluster. - * - * If the request conflicts with another write request in flight, the coroutine - * is queued and will be reentered when the dependency has completed. - * - * Return 0 on success and -errno in error cases - */ -int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, -    int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t start, remaining; -    uint64_t cluster_offset; -    uint64_t cur_bytes; -    int ret; - -    trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, -                                      n_start, n_end); - -    assert(n_start * BDRV_SECTOR_SIZE == offset_into_cluster(s, offset)); -    offset = start_of_cluster(s, offset); - -again: -    start = offset + (n_start << BDRV_SECTOR_BITS); -    remaining = (n_end - n_start) << BDRV_SECTOR_BITS; -    cluster_offset = 0; -    *host_offset = 0; -    cur_bytes = 0; -    *m = NULL; - -    while (true) { - -        if (!*host_offset) { -            *host_offset = start_of_cluster(s, cluster_offset); -        } - -        assert(remaining >= cur_bytes); - -        start           += cur_bytes; -        remaining       -= cur_bytes; -        cluster_offset  += cur_bytes; - -        if (remaining == 0) { -            break; -        } - -        cur_bytes = remaining; - -        /* -         * Now start gathering as many contiguous clusters as possible: -         * -         * 1. Check for overlaps with in-flight allocations -         * -         *      a) Overlap not in the first cluster -> shorten this request and -         *         let the caller handle the rest in its next loop iteration. -         * -         *      b) Real overlaps of two requests. Yield and restart the search -         *         for contiguous clusters (the situation could have changed -         *         while we were sleeping) -         * -         *      c) TODO: Request starts in the same cluster as the in-flight -         *         allocation ends. Shorten the COW of the in-fight allocation, -         *         set cluster_offset to write to the same cluster and set up -         *         the right synchronisation between the in-flight request and -         *         the new one. -         */ -        ret = handle_dependencies(bs, start, &cur_bytes, m); -        if (ret == -EAGAIN) { -            /* Currently handle_dependencies() doesn't yield if we already had -             * an allocation. If it did, we would have to clean up the L2Meta -             * structs before starting over. */ -            assert(*m == NULL); -            goto again; -        } else if (ret < 0) { -            return ret; -        } else if (cur_bytes == 0) { -            break; -        } else { -            /* handle_dependencies() may have decreased cur_bytes (shortened -             * the allocations below) so that the next dependency is processed -             * correctly during the next loop iteration. */ -        } - -        /* -         * 2. Count contiguous COPIED clusters. -         */ -        ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m); -        if (ret < 0) { -            return ret; -        } else if (ret) { -            continue; -        } else if (cur_bytes == 0) { -            break; -        } - -        /* -         * 3. If the request still hasn't completed, allocate new clusters, -         *    considering any cluster_offset of steps 1c or 2. -         */ -        ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m); -        if (ret < 0) { -            return ret; -        } else if (ret) { -            continue; -        } else { -            assert(cur_bytes == 0); -            break; -        } -    } - -    *num = (n_end - n_start) - (remaining >> BDRV_SECTOR_BITS); -    assert(*num > 0); -    assert(*host_offset != 0); - -    return 0; -} - -static int decompress_buffer(uint8_t *out_buf, int out_buf_size, -                             const uint8_t *buf, int buf_size) -{ -    z_stream strm1, *strm = &strm1; -    int ret, out_len; - -    memset(strm, 0, sizeof(*strm)); - -    strm->next_in = (uint8_t *)buf; -    strm->avail_in = buf_size; -    strm->next_out = out_buf; -    strm->avail_out = out_buf_size; - -    ret = inflateInit2(strm, -12); -    if (ret != Z_OK) -        return -1; -    ret = inflate(strm, Z_FINISH); -    out_len = strm->next_out - out_buf; -    if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || -        out_len != out_buf_size) { -        inflateEnd(strm); -        return -1; -    } -    inflateEnd(strm); -    return 0; -} - -int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) -{ -    BDRVQcowState *s = bs->opaque; -    int ret, csize, nb_csectors, sector_offset; -    uint64_t coffset; - -    coffset = cluster_offset & s->cluster_offset_mask; -    if (s->cluster_cache_offset != coffset) { -        nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1; -        sector_offset = coffset & 511; -        csize = nb_csectors * 512 - sector_offset; -        BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED); -        ret = bdrv_read(bs->file, coffset >> 9, s->cluster_data, nb_csectors); -        if (ret < 0) { -            return ret; -        } -        if (decompress_buffer(s->cluster_cache, s->cluster_size, -                              s->cluster_data + sector_offset, csize) < 0) { -            return -EIO; -        } -        s->cluster_cache_offset = coffset; -    } -    return 0; -} - -/* - * This discards as many clusters of nb_clusters as possible at once (i.e. - * all clusters in the same L2 table) and returns the number of discarded - * clusters. - */ -static int discard_single_l2(BlockDriverState *bs, uint64_t offset, -    unsigned int nb_clusters) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t *l2_table; -    int l2_index; -    int ret; -    int i; - -    ret = get_cluster_table(bs, offset, &l2_table, &l2_index); -    if (ret < 0) { -        return ret; -    } - -    /* Limit nb_clusters to one L2 table */ -    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); - -    for (i = 0; i < nb_clusters; i++) { -        uint64_t old_offset; - -        old_offset = be64_to_cpu(l2_table[l2_index + i]); -        if ((old_offset & L2E_OFFSET_MASK) == 0) { -            continue; -        } - -        /* First remove L2 entries */ -        qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); -        l2_table[l2_index + i] = cpu_to_be64(0); - -        /* Then decrease the refcount */ -        qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST); -    } - -    ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -    if (ret < 0) { -        return ret; -    } - -    return nb_clusters; -} - -int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset, -    int nb_sectors) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t end_offset; -    unsigned int nb_clusters; -    int ret; - -    end_offset = offset + (nb_sectors << BDRV_SECTOR_BITS); - -    /* Round start up and end down */ -    offset = align_offset(offset, s->cluster_size); -    end_offset &= ~(s->cluster_size - 1); - -    if (offset > end_offset) { -        return 0; -    } - -    nb_clusters = size_to_clusters(s, end_offset - offset); - -    s->cache_discards = true; - -    /* Each L2 table is handled by its own loop iteration */ -    while (nb_clusters > 0) { -        ret = discard_single_l2(bs, offset, nb_clusters); -        if (ret < 0) { -            goto fail; -        } - -        nb_clusters -= ret; -        offset += (ret * s->cluster_size); -    } - -    ret = 0; -fail: -    s->cache_discards = false; -    qcow2_process_discards(bs, ret); - -    return ret; -} - -/* - * This zeroes as many clusters of nb_clusters as possible at once (i.e. - * all clusters in the same L2 table) and returns the number of zeroed - * clusters. - */ -static int zero_single_l2(BlockDriverState *bs, uint64_t offset, -    unsigned int nb_clusters) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t *l2_table; -    int l2_index; -    int ret; -    int i; - -    ret = get_cluster_table(bs, offset, &l2_table, &l2_index); -    if (ret < 0) { -        return ret; -    } - -    /* Limit nb_clusters to one L2 table */ -    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); - -    for (i = 0; i < nb_clusters; i++) { -        uint64_t old_offset; - -        old_offset = be64_to_cpu(l2_table[l2_index + i]); - -        /* Update L2 entries */ -        qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); -        if (old_offset & QCOW_OFLAG_COMPRESSED) { -            l2_table[l2_index + i] = cpu_to_be64(QCOW_OFLAG_ZERO); -            qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST); -        } else { -            l2_table[l2_index + i] |= cpu_to_be64(QCOW_OFLAG_ZERO); -        } -    } - -    ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -    if (ret < 0) { -        return ret; -    } - -    return nb_clusters; -} - -int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors) -{ -    BDRVQcowState *s = bs->opaque; -    unsigned int nb_clusters; -    int ret; - -    /* The zero flag is only supported by version 3 and newer */ -    if (s->qcow_version < 3) { -        return -ENOTSUP; -    } - -    /* Each L2 table is handled by its own loop iteration */ -    nb_clusters = size_to_clusters(s, nb_sectors << BDRV_SECTOR_BITS); - -    s->cache_discards = true; - -    while (nb_clusters > 0) { -        ret = zero_single_l2(bs, offset, nb_clusters); -        if (ret < 0) { -            goto fail; -        } - -        nb_clusters -= ret; -        offset += (ret * s->cluster_size); -    } - -    ret = 0; -fail: -    s->cache_discards = false; -    qcow2_process_discards(bs, ret); - -    return ret; -} diff --git a/contrib/qemu/block/qcow2-refcount.c b/contrib/qemu/block/qcow2-refcount.c deleted file mode 100644 index 1244693f39e..00000000000 --- a/contrib/qemu/block/qcow2-refcount.c +++ /dev/null @@ -1,1374 +0,0 @@ -/* - * Block driver for the QCOW version 2 format - * - * Copyright (c) 2004-2006 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "qemu-common.h" -#include "block/block_int.h" -#include "block/qcow2.h" - -static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size); -static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs, -                            int64_t offset, int64_t length, -                            int addend, enum qcow2_discard_type type); - - -/*********************************************************/ -/* refcount handling */ - -int qcow2_refcount_init(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    int ret, refcount_table_size2, i; - -    refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t); -    s->refcount_table = g_malloc(refcount_table_size2); -    if (s->refcount_table_size > 0) { -        BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD); -        ret = bdrv_pread(bs->file, s->refcount_table_offset, -                         s->refcount_table, refcount_table_size2); -        if (ret != refcount_table_size2) -            goto fail; -        for(i = 0; i < s->refcount_table_size; i++) -            be64_to_cpus(&s->refcount_table[i]); -    } -    return 0; - fail: -    return -ENOMEM; -} - -void qcow2_refcount_close(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    g_free(s->refcount_table); -} - - -static int load_refcount_block(BlockDriverState *bs, -                               int64_t refcount_block_offset, -                               void **refcount_block) -{ -    BDRVQcowState *s = bs->opaque; -    int ret; - -    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_LOAD); -    ret = qcow2_cache_get(bs, s->refcount_block_cache, refcount_block_offset, -        refcount_block); - -    return ret; -} - -/* - * Returns the refcount of the cluster given by its index. Any non-negative - * return value is the refcount of the cluster, negative values are -errno - * and indicate an error. - */ -static int get_refcount(BlockDriverState *bs, int64_t cluster_index) -{ -    BDRVQcowState *s = bs->opaque; -    int refcount_table_index, block_index; -    int64_t refcount_block_offset; -    int ret; -    uint16_t *refcount_block; -    uint16_t refcount; - -    refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); -    if (refcount_table_index >= s->refcount_table_size) -        return 0; -    refcount_block_offset = s->refcount_table[refcount_table_index]; -    if (!refcount_block_offset) -        return 0; - -    ret = qcow2_cache_get(bs, s->refcount_block_cache, refcount_block_offset, -        (void**) &refcount_block); -    if (ret < 0) { -        return ret; -    } - -    block_index = cluster_index & -        ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1); -    refcount = be16_to_cpu(refcount_block[block_index]); - -    ret = qcow2_cache_put(bs, s->refcount_block_cache, -        (void**) &refcount_block); -    if (ret < 0) { -        return ret; -    } - -    return refcount; -} - -/* - * Rounds the refcount table size up to avoid growing the table for each single - * refcount block that is allocated. - */ -static unsigned int next_refcount_table_size(BDRVQcowState *s, -    unsigned int min_size) -{ -    unsigned int min_clusters = (min_size >> (s->cluster_bits - 3)) + 1; -    unsigned int refcount_table_clusters = -        MAX(1, s->refcount_table_size >> (s->cluster_bits - 3)); - -    while (min_clusters > refcount_table_clusters) { -        refcount_table_clusters = (refcount_table_clusters * 3 + 1) / 2; -    } - -    return refcount_table_clusters << (s->cluster_bits - 3); -} - - -/* Checks if two offsets are described by the same refcount block */ -static int in_same_refcount_block(BDRVQcowState *s, uint64_t offset_a, -    uint64_t offset_b) -{ -    uint64_t block_a = offset_a >> (2 * s->cluster_bits - REFCOUNT_SHIFT); -    uint64_t block_b = offset_b >> (2 * s->cluster_bits - REFCOUNT_SHIFT); - -    return (block_a == block_b); -} - -/* - * Loads a refcount block. If it doesn't exist yet, it is allocated first - * (including growing the refcount table if needed). - * - * Returns 0 on success or -errno in error case - */ -static int alloc_refcount_block(BlockDriverState *bs, -    int64_t cluster_index, uint16_t **refcount_block) -{ -    BDRVQcowState *s = bs->opaque; -    unsigned int refcount_table_index; -    int ret; - -    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC); - -    /* Find the refcount block for the given cluster */ -    refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); - -    if (refcount_table_index < s->refcount_table_size) { - -        uint64_t refcount_block_offset = -            s->refcount_table[refcount_table_index] & REFT_OFFSET_MASK; - -        /* If it's already there, we're done */ -        if (refcount_block_offset) { -             return load_refcount_block(bs, refcount_block_offset, -                 (void**) refcount_block); -        } -    } - -    /* -     * If we came here, we need to allocate something. Something is at least -     * a cluster for the new refcount block. It may also include a new refcount -     * table if the old refcount table is too small. -     * -     * Note that allocating clusters here needs some special care: -     * -     * - We can't use the normal qcow2_alloc_clusters(), it would try to -     *   increase the refcount and very likely we would end up with an endless -     *   recursion. Instead we must place the refcount blocks in a way that -     *   they can describe them themselves. -     * -     * - We need to consider that at this point we are inside update_refcounts -     *   and doing the initial refcount increase. This means that some clusters -     *   have already been allocated by the caller, but their refcount isn't -     *   accurate yet. free_cluster_index tells us where this allocation ends -     *   as long as we don't overwrite it by freeing clusters. -     * -     * - alloc_clusters_noref and qcow2_free_clusters may load a different -     *   refcount block into the cache -     */ - -    *refcount_block = NULL; - -    /* We write to the refcount table, so we might depend on L2 tables */ -    ret = qcow2_cache_flush(bs, s->l2_table_cache); -    if (ret < 0) { -        return ret; -    } - -    /* Allocate the refcount block itself and mark it as used */ -    int64_t new_block = alloc_clusters_noref(bs, s->cluster_size); -    if (new_block < 0) { -        return new_block; -    } - -#ifdef DEBUG_ALLOC2 -    fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64 -        " at %" PRIx64 "\n", -        refcount_table_index, cluster_index << s->cluster_bits, new_block); -#endif - -    if (in_same_refcount_block(s, new_block, cluster_index << s->cluster_bits)) { -        /* Zero the new refcount block before updating it */ -        ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block, -            (void**) refcount_block); -        if (ret < 0) { -            goto fail_block; -        } - -        memset(*refcount_block, 0, s->cluster_size); - -        /* The block describes itself, need to update the cache */ -        int block_index = (new_block >> s->cluster_bits) & -            ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1); -        (*refcount_block)[block_index] = cpu_to_be16(1); -    } else { -        /* Described somewhere else. This can recurse at most twice before we -         * arrive at a block that describes itself. */ -        ret = update_refcount(bs, new_block, s->cluster_size, 1, -                              QCOW2_DISCARD_NEVER); -        if (ret < 0) { -            goto fail_block; -        } - -        ret = qcow2_cache_flush(bs, s->refcount_block_cache); -        if (ret < 0) { -            goto fail_block; -        } - -        /* Initialize the new refcount block only after updating its refcount, -         * update_refcount uses the refcount cache itself */ -        ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block, -            (void**) refcount_block); -        if (ret < 0) { -            goto fail_block; -        } - -        memset(*refcount_block, 0, s->cluster_size); -    } - -    /* Now the new refcount block needs to be written to disk */ -    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE); -    qcow2_cache_entry_mark_dirty(s->refcount_block_cache, *refcount_block); -    ret = qcow2_cache_flush(bs, s->refcount_block_cache); -    if (ret < 0) { -        goto fail_block; -    } - -    /* If the refcount table is big enough, just hook the block up there */ -    if (refcount_table_index < s->refcount_table_size) { -        uint64_t data64 = cpu_to_be64(new_block); -        BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP); -        ret = bdrv_pwrite_sync(bs->file, -            s->refcount_table_offset + refcount_table_index * sizeof(uint64_t), -            &data64, sizeof(data64)); -        if (ret < 0) { -            goto fail_block; -        } - -        s->refcount_table[refcount_table_index] = new_block; -        return 0; -    } - -    ret = qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block); -    if (ret < 0) { -        goto fail_block; -    } - -    /* -     * If we come here, we need to grow the refcount table. Again, a new -     * refcount table needs some space and we can't simply allocate to avoid -     * endless recursion. -     * -     * Therefore let's grab new refcount blocks at the end of the image, which -     * will describe themselves and the new refcount table. This way we can -     * reference them only in the new table and do the switch to the new -     * refcount table at once without producing an inconsistent state in -     * between. -     */ -    BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_GROW); - -    /* Calculate the number of refcount blocks needed so far */ -    uint64_t refcount_block_clusters = 1 << (s->cluster_bits - REFCOUNT_SHIFT); -    uint64_t blocks_used = (s->free_cluster_index + -        refcount_block_clusters - 1) / refcount_block_clusters; - -    /* And now we need at least one block more for the new metadata */ -    uint64_t table_size = next_refcount_table_size(s, blocks_used + 1); -    uint64_t last_table_size; -    uint64_t blocks_clusters; -    do { -        uint64_t table_clusters = -            size_to_clusters(s, table_size * sizeof(uint64_t)); -        blocks_clusters = 1 + -            ((table_clusters + refcount_block_clusters - 1) -            / refcount_block_clusters); -        uint64_t meta_clusters = table_clusters + blocks_clusters; - -        last_table_size = table_size; -        table_size = next_refcount_table_size(s, blocks_used + -            ((meta_clusters + refcount_block_clusters - 1) -            / refcount_block_clusters)); - -    } while (last_table_size != table_size); - -#ifdef DEBUG_ALLOC2 -    fprintf(stderr, "qcow2: Grow refcount table %" PRId32 " => %" PRId64 "\n", -        s->refcount_table_size, table_size); -#endif - -    /* Create the new refcount table and blocks */ -    uint64_t meta_offset = (blocks_used * refcount_block_clusters) * -        s->cluster_size; -    uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size; -    uint16_t *new_blocks = g_malloc0(blocks_clusters * s->cluster_size); -    uint64_t *new_table = g_malloc0(table_size * sizeof(uint64_t)); - -    assert(meta_offset >= (s->free_cluster_index * s->cluster_size)); - -    /* Fill the new refcount table */ -    memcpy(new_table, s->refcount_table, -        s->refcount_table_size * sizeof(uint64_t)); -    new_table[refcount_table_index] = new_block; - -    int i; -    for (i = 0; i < blocks_clusters; i++) { -        new_table[blocks_used + i] = meta_offset + (i * s->cluster_size); -    } - -    /* Fill the refcount blocks */ -    uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t)); -    int block = 0; -    for (i = 0; i < table_clusters + blocks_clusters; i++) { -        new_blocks[block++] = cpu_to_be16(1); -    } - -    /* Write refcount blocks to disk */ -    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS); -    ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks, -        blocks_clusters * s->cluster_size); -    g_free(new_blocks); -    if (ret < 0) { -        goto fail_table; -    } - -    /* Write refcount table to disk */ -    for(i = 0; i < table_size; i++) { -        cpu_to_be64s(&new_table[i]); -    } - -    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE); -    ret = bdrv_pwrite_sync(bs->file, table_offset, new_table, -        table_size * sizeof(uint64_t)); -    if (ret < 0) { -        goto fail_table; -    } - -    for(i = 0; i < table_size; i++) { -        be64_to_cpus(&new_table[i]); -    } - -    /* Hook up the new refcount table in the qcow2 header */ -    uint8_t data[12]; -    cpu_to_be64w((uint64_t*)data, table_offset); -    cpu_to_be32w((uint32_t*)(data + 8), table_clusters); -    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE); -    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, refcount_table_offset), -        data, sizeof(data)); -    if (ret < 0) { -        goto fail_table; -    } - -    /* And switch it in memory */ -    uint64_t old_table_offset = s->refcount_table_offset; -    uint64_t old_table_size = s->refcount_table_size; - -    g_free(s->refcount_table); -    s->refcount_table = new_table; -    s->refcount_table_size = table_size; -    s->refcount_table_offset = table_offset; - -    /* Free old table. Remember, we must not change free_cluster_index */ -    uint64_t old_free_cluster_index = s->free_cluster_index; -    qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t), -                        QCOW2_DISCARD_OTHER); -    s->free_cluster_index = old_free_cluster_index; - -    ret = load_refcount_block(bs, new_block, (void**) refcount_block); -    if (ret < 0) { -        return ret; -    } - -    return 0; - -fail_table: -    g_free(new_table); -fail_block: -    if (*refcount_block != NULL) { -        qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block); -    } -    return ret; -} - -void qcow2_process_discards(BlockDriverState *bs, int ret) -{ -    BDRVQcowState *s = bs->opaque; -    Qcow2DiscardRegion *d, *next; - -    QTAILQ_FOREACH_SAFE(d, &s->discards, next, next) { -        QTAILQ_REMOVE(&s->discards, d, next); - -        /* Discard is optional, ignore the return value */ -        if (ret >= 0) { -            bdrv_discard(bs->file, -                         d->offset >> BDRV_SECTOR_BITS, -                         d->bytes >> BDRV_SECTOR_BITS); -        } - -        g_free(d); -    } -} - -static void update_refcount_discard(BlockDriverState *bs, -                                    uint64_t offset, uint64_t length) -{ -    BDRVQcowState *s = bs->opaque; -    Qcow2DiscardRegion *d, *p, *next; - -    QTAILQ_FOREACH(d, &s->discards, next) { -        uint64_t new_start = MIN(offset, d->offset); -        uint64_t new_end = MAX(offset + length, d->offset + d->bytes); - -        if (new_end - new_start <= length + d->bytes) { -            /* There can't be any overlap, areas ending up here have no -             * references any more and therefore shouldn't get freed another -             * time. */ -            assert(d->bytes + length == new_end - new_start); -            d->offset = new_start; -            d->bytes = new_end - new_start; -            goto found; -        } -    } - -    d = g_malloc(sizeof(*d)); -    *d = (Qcow2DiscardRegion) { -        .bs     = bs, -        .offset = offset, -        .bytes  = length, -    }; -    QTAILQ_INSERT_TAIL(&s->discards, d, next); - -found: -    /* Merge discard requests if they are adjacent now */ -    QTAILQ_FOREACH_SAFE(p, &s->discards, next, next) { -        if (p == d -            || p->offset > d->offset + d->bytes -            || d->offset > p->offset + p->bytes) -        { -            continue; -        } - -        /* Still no overlap possible */ -        assert(p->offset == d->offset + d->bytes -            || d->offset == p->offset + p->bytes); - -        QTAILQ_REMOVE(&s->discards, p, next); -        d->offset = MIN(d->offset, p->offset); -        d->bytes += p->bytes; -    } -} - -/* XXX: cache several refcount block clusters ? */ -static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs, -    int64_t offset, int64_t length, int addend, enum qcow2_discard_type type) -{ -    BDRVQcowState *s = bs->opaque; -    int64_t start, last, cluster_offset; -    uint16_t *refcount_block = NULL; -    int64_t old_table_index = -1; -    int ret; - -#ifdef DEBUG_ALLOC2 -    fprintf(stderr, "update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n", -           offset, length, addend); -#endif -    if (length < 0) { -        return -EINVAL; -    } else if (length == 0) { -        return 0; -    } - -    if (addend < 0) { -        qcow2_cache_set_dependency(bs, s->refcount_block_cache, -            s->l2_table_cache); -    } - -    start = offset & ~(s->cluster_size - 1); -    last = (offset + length - 1) & ~(s->cluster_size - 1); -    for(cluster_offset = start; cluster_offset <= last; -        cluster_offset += s->cluster_size) -    { -        int block_index, refcount; -        int64_t cluster_index = cluster_offset >> s->cluster_bits; -        int64_t table_index = -            cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); - -        /* Load the refcount block and allocate it if needed */ -        if (table_index != old_table_index) { -            if (refcount_block) { -                ret = qcow2_cache_put(bs, s->refcount_block_cache, -                    (void**) &refcount_block); -                if (ret < 0) { -                    goto fail; -                } -            } - -            ret = alloc_refcount_block(bs, cluster_index, &refcount_block); -            if (ret < 0) { -                goto fail; -            } -        } -        old_table_index = table_index; - -        qcow2_cache_entry_mark_dirty(s->refcount_block_cache, refcount_block); - -        /* we can update the count and save it */ -        block_index = cluster_index & -            ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1); - -        refcount = be16_to_cpu(refcount_block[block_index]); -        refcount += addend; -        if (refcount < 0 || refcount > 0xffff) { -            ret = -EINVAL; -            goto fail; -        } -        if (refcount == 0 && cluster_index < s->free_cluster_index) { -            s->free_cluster_index = cluster_index; -        } -        refcount_block[block_index] = cpu_to_be16(refcount); - -        if (refcount == 0 && s->discard_passthrough[type]) { -            update_refcount_discard(bs, cluster_offset, s->cluster_size); -        } -    } - -    ret = 0; -fail: -    if (!s->cache_discards) { -        qcow2_process_discards(bs, ret); -    } - -    /* Write last changed block to disk */ -    if (refcount_block) { -        int wret; -        wret = qcow2_cache_put(bs, s->refcount_block_cache, -            (void**) &refcount_block); -        if (wret < 0) { -            return ret < 0 ? ret : wret; -        } -    } - -    /* -     * Try do undo any updates if an error is returned (This may succeed in -     * some cases like ENOSPC for allocating a new refcount block) -     */ -    if (ret < 0) { -        int dummy; -        dummy = update_refcount(bs, offset, cluster_offset - offset, -addend, -                                QCOW2_DISCARD_NEVER); -        (void)dummy; -    } - -    return ret; -} - -/* - * Increases or decreases the refcount of a given cluster by one. - * addend must be 1 or -1. - * - * If the return value is non-negative, it is the new refcount of the cluster. - * If it is negative, it is -errno and indicates an error. - */ -static int update_cluster_refcount(BlockDriverState *bs, -                                   int64_t cluster_index, -                                   int addend, -                                   enum qcow2_discard_type type) -{ -    BDRVQcowState *s = bs->opaque; -    int ret; - -    ret = update_refcount(bs, cluster_index << s->cluster_bits, 1, addend, -                          type); -    if (ret < 0) { -        return ret; -    } - -    return get_refcount(bs, cluster_index); -} - - - -/*********************************************************/ -/* cluster allocation functions */ - - - -/* return < 0 if error */ -static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size) -{ -    BDRVQcowState *s = bs->opaque; -    int i, nb_clusters, refcount; - -    nb_clusters = size_to_clusters(s, size); -retry: -    for(i = 0; i < nb_clusters; i++) { -        int64_t next_cluster_index = s->free_cluster_index++; -        refcount = get_refcount(bs, next_cluster_index); - -        if (refcount < 0) { -            return refcount; -        } else if (refcount != 0) { -            goto retry; -        } -    } -#ifdef DEBUG_ALLOC2 -    fprintf(stderr, "alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n", -            size, -            (s->free_cluster_index - nb_clusters) << s->cluster_bits); -#endif -    return (s->free_cluster_index - nb_clusters) << s->cluster_bits; -} - -int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size) -{ -    int64_t offset; -    int ret; - -    BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC); -    offset = alloc_clusters_noref(bs, size); -    if (offset < 0) { -        return offset; -    } - -    ret = update_refcount(bs, offset, size, 1, QCOW2_DISCARD_NEVER); -    if (ret < 0) { -        return ret; -    } - -    return offset; -} - -int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, -    int nb_clusters) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t cluster_index; -    uint64_t old_free_cluster_index; -    int i, refcount, ret; - -    /* Check how many clusters there are free */ -    cluster_index = offset >> s->cluster_bits; -    for(i = 0; i < nb_clusters; i++) { -        refcount = get_refcount(bs, cluster_index++); - -        if (refcount < 0) { -            return refcount; -        } else if (refcount != 0) { -            break; -        } -    } - -    /* And then allocate them */ -    old_free_cluster_index = s->free_cluster_index; -    s->free_cluster_index = cluster_index + i; - -    ret = update_refcount(bs, offset, i << s->cluster_bits, 1, -                          QCOW2_DISCARD_NEVER); -    if (ret < 0) { -        return ret; -    } - -    s->free_cluster_index = old_free_cluster_index; - -    return i; -} - -/* only used to allocate compressed sectors. We try to allocate -   contiguous sectors. size must be <= cluster_size */ -int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size) -{ -    BDRVQcowState *s = bs->opaque; -    int64_t offset, cluster_offset; -    int free_in_cluster; - -    BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_BYTES); -    assert(size > 0 && size <= s->cluster_size); -    if (s->free_byte_offset == 0) { -        offset = qcow2_alloc_clusters(bs, s->cluster_size); -        if (offset < 0) { -            return offset; -        } -        s->free_byte_offset = offset; -    } - redo: -    free_in_cluster = s->cluster_size - -        (s->free_byte_offset & (s->cluster_size - 1)); -    if (size <= free_in_cluster) { -        /* enough space in current cluster */ -        offset = s->free_byte_offset; -        s->free_byte_offset += size; -        free_in_cluster -= size; -        if (free_in_cluster == 0) -            s->free_byte_offset = 0; -        if ((offset & (s->cluster_size - 1)) != 0) -            update_cluster_refcount(bs, offset >> s->cluster_bits, 1, -                                    QCOW2_DISCARD_NEVER); -    } else { -        offset = qcow2_alloc_clusters(bs, s->cluster_size); -        if (offset < 0) { -            return offset; -        } -        cluster_offset = s->free_byte_offset & ~(s->cluster_size - 1); -        if ((cluster_offset + s->cluster_size) == offset) { -            /* we are lucky: contiguous data */ -            offset = s->free_byte_offset; -            update_cluster_refcount(bs, offset >> s->cluster_bits, 1, -                                    QCOW2_DISCARD_NEVER); -            s->free_byte_offset += size; -        } else { -            s->free_byte_offset = offset; -            goto redo; -        } -    } - -    /* The cluster refcount was incremented, either by qcow2_alloc_clusters() -     * or explicitly by update_cluster_refcount().  Refcount blocks must be -     * flushed before the caller's L2 table updates. -     */ -    qcow2_cache_set_dependency(bs, s->l2_table_cache, s->refcount_block_cache); -    return offset; -} - -void qcow2_free_clusters(BlockDriverState *bs, -                          int64_t offset, int64_t size, -                          enum qcow2_discard_type type) -{ -    int ret; - -    BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_FREE); -    ret = update_refcount(bs, offset, size, -1, type); -    if (ret < 0) { -        fprintf(stderr, "qcow2_free_clusters failed: %s\n", strerror(-ret)); -        /* TODO Remember the clusters to free them later and avoid leaking */ -    } -} - -/* - * Free a cluster using its L2 entry (handles clusters of all types, e.g. - * normal cluster, compressed cluster, etc.) - */ -void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t l2_entry, -                             int nb_clusters, enum qcow2_discard_type type) -{ -    BDRVQcowState *s = bs->opaque; - -    switch (qcow2_get_cluster_type(l2_entry)) { -    case QCOW2_CLUSTER_COMPRESSED: -        { -            int nb_csectors; -            nb_csectors = ((l2_entry >> s->csize_shift) & -                           s->csize_mask) + 1; -            qcow2_free_clusters(bs, -                (l2_entry & s->cluster_offset_mask) & ~511, -                nb_csectors * 512, type); -        } -        break; -    case QCOW2_CLUSTER_NORMAL: -        qcow2_free_clusters(bs, l2_entry & L2E_OFFSET_MASK, -                            nb_clusters << s->cluster_bits, type); -        break; -    case QCOW2_CLUSTER_UNALLOCATED: -    case QCOW2_CLUSTER_ZERO: -        break; -    default: -        abort(); -    } -} - - - -/*********************************************************/ -/* snapshots and image creation */ - - - -/* update the refcounts of snapshots and the copied flag */ -int qcow2_update_snapshot_refcount(BlockDriverState *bs, -    int64_t l1_table_offset, int l1_size, int addend) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated; -    int64_t old_offset, old_l2_offset; -    int i, j, l1_modified = 0, nb_csectors, refcount; -    int ret; - -    l2_table = NULL; -    l1_table = NULL; -    l1_size2 = l1_size * sizeof(uint64_t); - -    s->cache_discards = true; - -    /* WARNING: qcow2_snapshot_goto relies on this function not using the -     * l1_table_offset when it is the current s->l1_table_offset! Be careful -     * when changing this! */ -    if (l1_table_offset != s->l1_table_offset) { -        l1_table = g_malloc0(align_offset(l1_size2, 512)); -        l1_allocated = 1; - -        ret = bdrv_pread(bs->file, l1_table_offset, l1_table, l1_size2); -        if (ret < 0) { -            goto fail; -        } - -        for(i = 0;i < l1_size; i++) -            be64_to_cpus(&l1_table[i]); -    } else { -        assert(l1_size == s->l1_size); -        l1_table = s->l1_table; -        l1_allocated = 0; -    } - -    for(i = 0; i < l1_size; i++) { -        l2_offset = l1_table[i]; -        if (l2_offset) { -            old_l2_offset = l2_offset; -            l2_offset &= L1E_OFFSET_MASK; - -            ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset, -                (void**) &l2_table); -            if (ret < 0) { -                goto fail; -            } - -            for(j = 0; j < s->l2_size; j++) { -                offset = be64_to_cpu(l2_table[j]); -                if (offset != 0) { -                    old_offset = offset; -                    offset &= ~QCOW_OFLAG_COPIED; -                    if (offset & QCOW_OFLAG_COMPRESSED) { -                        nb_csectors = ((offset >> s->csize_shift) & -                                       s->csize_mask) + 1; -                        if (addend != 0) { -                            int ret; -                            ret = update_refcount(bs, -                                (offset & s->cluster_offset_mask) & ~511, -                                nb_csectors * 512, addend, -                                QCOW2_DISCARD_SNAPSHOT); -                            if (ret < 0) { -                                goto fail; -                            } -                        } -                        /* compressed clusters are never modified */ -                        refcount = 2; -                    } else { -                        uint64_t cluster_index = (offset & L2E_OFFSET_MASK) >> s->cluster_bits; -                        if (addend != 0) { -                            refcount = update_cluster_refcount(bs, cluster_index, addend, -                                                               QCOW2_DISCARD_SNAPSHOT); -                        } else { -                            refcount = get_refcount(bs, cluster_index); -                        } - -                        if (refcount < 0) { -                            ret = refcount; -                            goto fail; -                        } -                    } - -                    if (refcount == 1) { -                        offset |= QCOW_OFLAG_COPIED; -                    } -                    if (offset != old_offset) { -                        if (addend > 0) { -                            qcow2_cache_set_dependency(bs, s->l2_table_cache, -                                s->refcount_block_cache); -                        } -                        l2_table[j] = cpu_to_be64(offset); -                        qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); -                    } -                } -            } - -            ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -            if (ret < 0) { -                goto fail; -            } - - -            if (addend != 0) { -                refcount = update_cluster_refcount(bs, l2_offset >> s->cluster_bits, addend, -                                                   QCOW2_DISCARD_SNAPSHOT); -            } else { -                refcount = get_refcount(bs, l2_offset >> s->cluster_bits); -            } -            if (refcount < 0) { -                ret = refcount; -                goto fail; -            } else if (refcount == 1) { -                l2_offset |= QCOW_OFLAG_COPIED; -            } -            if (l2_offset != old_l2_offset) { -                l1_table[i] = l2_offset; -                l1_modified = 1; -            } -        } -    } - -    ret = bdrv_flush(bs); -fail: -    if (l2_table) { -        qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); -    } - -    s->cache_discards = false; -    qcow2_process_discards(bs, ret); - -    /* Update L1 only if it isn't deleted anyway (addend = -1) */ -    if (ret == 0 && addend >= 0 && l1_modified) { -        for (i = 0; i < l1_size; i++) { -            cpu_to_be64s(&l1_table[i]); -        } - -        ret = bdrv_pwrite_sync(bs->file, l1_table_offset, l1_table, l1_size2); - -        for (i = 0; i < l1_size; i++) { -            be64_to_cpus(&l1_table[i]); -        } -    } -    if (l1_allocated) -        g_free(l1_table); -    return ret; -} - - - - -/*********************************************************/ -/* refcount checking functions */ - - - -/* - * Increases the refcount for a range of clusters in a given refcount table. - * This is used to construct a temporary refcount table out of L1 and L2 tables - * which can be compared the the refcount table saved in the image. - * - * Modifies the number of errors in res. - */ -static void inc_refcounts(BlockDriverState *bs, -                          BdrvCheckResult *res, -                          uint16_t *refcount_table, -                          int refcount_table_size, -                          int64_t offset, int64_t size) -{ -    BDRVQcowState *s = bs->opaque; -    int64_t start, last, cluster_offset; -    int k; - -    if (size <= 0) -        return; - -    start = offset & ~(s->cluster_size - 1); -    last = (offset + size - 1) & ~(s->cluster_size - 1); -    for(cluster_offset = start; cluster_offset <= last; -        cluster_offset += s->cluster_size) { -        k = cluster_offset >> s->cluster_bits; -        if (k < 0) { -            fprintf(stderr, "ERROR: invalid cluster offset=0x%" PRIx64 "\n", -                cluster_offset); -            res->corruptions++; -        } else if (k >= refcount_table_size) { -            fprintf(stderr, "Warning: cluster offset=0x%" PRIx64 " is after " -                "the end of the image file, can't properly check refcounts.\n", -                cluster_offset); -            res->check_errors++; -        } else { -            if (++refcount_table[k] == 0) { -                fprintf(stderr, "ERROR: overflow cluster offset=0x%" PRIx64 -                    "\n", cluster_offset); -                res->corruptions++; -            } -        } -    } -} - -/* Flags for check_refcounts_l1() and check_refcounts_l2() */ -enum { -    CHECK_OFLAG_COPIED = 0x1,   /* check QCOW_OFLAG_COPIED matches refcount */ -    CHECK_FRAG_INFO = 0x2,      /* update BlockFragInfo counters */ -}; - -/* - * Increases the refcount in the given refcount table for the all clusters - * referenced in the L2 table. While doing so, performs some checks on L2 - * entries. - * - * Returns the number of errors found by the checks or -errno if an internal - * error occurred. - */ -static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, -    uint16_t *refcount_table, int refcount_table_size, int64_t l2_offset, -    int flags) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t *l2_table, l2_entry; -    uint64_t next_contiguous_offset = 0; -    int i, l2_size, nb_csectors, refcount; - -    /* Read L2 table from disk */ -    l2_size = s->l2_size * sizeof(uint64_t); -    l2_table = g_malloc(l2_size); - -    if (bdrv_pread(bs->file, l2_offset, l2_table, l2_size) != l2_size) -        goto fail; - -    /* Do the actual checks */ -    for(i = 0; i < s->l2_size; i++) { -        l2_entry = be64_to_cpu(l2_table[i]); - -        switch (qcow2_get_cluster_type(l2_entry)) { -        case QCOW2_CLUSTER_COMPRESSED: -            /* Compressed clusters don't have QCOW_OFLAG_COPIED */ -            if (l2_entry & QCOW_OFLAG_COPIED) { -                fprintf(stderr, "ERROR: cluster %" PRId64 ": " -                    "copied flag must never be set for compressed " -                    "clusters\n", l2_entry >> s->cluster_bits); -                l2_entry &= ~QCOW_OFLAG_COPIED; -                res->corruptions++; -            } - -            /* Mark cluster as used */ -            nb_csectors = ((l2_entry >> s->csize_shift) & -                           s->csize_mask) + 1; -            l2_entry &= s->cluster_offset_mask; -            inc_refcounts(bs, res, refcount_table, refcount_table_size, -                l2_entry & ~511, nb_csectors * 512); - -            if (flags & CHECK_FRAG_INFO) { -                res->bfi.allocated_clusters++; -                res->bfi.compressed_clusters++; - -                /* Compressed clusters are fragmented by nature.  Since they -                 * take up sub-sector space but we only have sector granularity -                 * I/O we need to re-read the same sectors even for adjacent -                 * compressed clusters. -                 */ -                res->bfi.fragmented_clusters++; -            } -            break; - -        case QCOW2_CLUSTER_ZERO: -            if ((l2_entry & L2E_OFFSET_MASK) == 0) { -                break; -            } -            /* fall through */ - -        case QCOW2_CLUSTER_NORMAL: -        { -            /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */ -            uint64_t offset = l2_entry & L2E_OFFSET_MASK; - -            if (flags & CHECK_OFLAG_COPIED) { -                refcount = get_refcount(bs, offset >> s->cluster_bits); -                if (refcount < 0) { -                    fprintf(stderr, "Can't get refcount for offset %" -                        PRIx64 ": %s\n", l2_entry, strerror(-refcount)); -                    goto fail; -                } -                if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) { -                    fprintf(stderr, "ERROR OFLAG_COPIED: offset=%" -                        PRIx64 " refcount=%d\n", l2_entry, refcount); -                    res->corruptions++; -                } -            } - -            if (flags & CHECK_FRAG_INFO) { -                res->bfi.allocated_clusters++; -                if (next_contiguous_offset && -                    offset != next_contiguous_offset) { -                    res->bfi.fragmented_clusters++; -                } -                next_contiguous_offset = offset + s->cluster_size; -            } - -            /* Mark cluster as used */ -            inc_refcounts(bs, res, refcount_table,refcount_table_size, -                offset, s->cluster_size); - -            /* Correct offsets are cluster aligned */ -            if (offset & (s->cluster_size - 1)) { -                fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not " -                    "properly aligned; L2 entry corrupted.\n", offset); -                res->corruptions++; -            } -            break; -        } - -        case QCOW2_CLUSTER_UNALLOCATED: -            break; - -        default: -            abort(); -        } -    } - -    g_free(l2_table); -    return 0; - -fail: -    fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n"); -    g_free(l2_table); -    return -EIO; -} - -/* - * Increases the refcount for the L1 table, its L2 tables and all referenced - * clusters in the given refcount table. While doing so, performs some checks - * on L1 and L2 entries. - * - * Returns the number of errors found by the checks or -errno if an internal - * error occurred. - */ -static int check_refcounts_l1(BlockDriverState *bs, -                              BdrvCheckResult *res, -                              uint16_t *refcount_table, -                              int refcount_table_size, -                              int64_t l1_table_offset, int l1_size, -                              int flags) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t *l1_table, l2_offset, l1_size2; -    int i, refcount, ret; - -    l1_size2 = l1_size * sizeof(uint64_t); - -    /* Mark L1 table as used */ -    inc_refcounts(bs, res, refcount_table, refcount_table_size, -        l1_table_offset, l1_size2); - -    /* Read L1 table entries from disk */ -    if (l1_size2 == 0) { -        l1_table = NULL; -    } else { -        l1_table = g_malloc(l1_size2); -        if (bdrv_pread(bs->file, l1_table_offset, -                       l1_table, l1_size2) != l1_size2) -            goto fail; -        for(i = 0;i < l1_size; i++) -            be64_to_cpus(&l1_table[i]); -    } - -    /* Do the actual checks */ -    for(i = 0; i < l1_size; i++) { -        l2_offset = l1_table[i]; -        if (l2_offset) { -            /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */ -            if (flags & CHECK_OFLAG_COPIED) { -                refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED) -                    >> s->cluster_bits); -                if (refcount < 0) { -                    fprintf(stderr, "Can't get refcount for l2_offset %" -                        PRIx64 ": %s\n", l2_offset, strerror(-refcount)); -                    goto fail; -                } -                if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) { -                    fprintf(stderr, "ERROR OFLAG_COPIED: l2_offset=%" PRIx64 -                        " refcount=%d\n", l2_offset, refcount); -                    res->corruptions++; -                } -            } - -            /* Mark L2 table as used */ -            l2_offset &= L1E_OFFSET_MASK; -            inc_refcounts(bs, res, refcount_table, refcount_table_size, -                l2_offset, s->cluster_size); - -            /* L2 tables are cluster aligned */ -            if (l2_offset & (s->cluster_size - 1)) { -                fprintf(stderr, "ERROR l2_offset=%" PRIx64 ": Table is not " -                    "cluster aligned; L1 entry corrupted\n", l2_offset); -                res->corruptions++; -            } - -            /* Process and check L2 entries */ -            ret = check_refcounts_l2(bs, res, refcount_table, -                                     refcount_table_size, l2_offset, flags); -            if (ret < 0) { -                goto fail; -            } -        } -    } -    g_free(l1_table); -    return 0; - -fail: -    fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n"); -    res->check_errors++; -    g_free(l1_table); -    return -EIO; -} - -/* - * Checks an image for refcount consistency. - * - * Returns 0 if no errors are found, the number of errors in case the image is - * detected as corrupted, and -errno when an internal error occurred. - */ -int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res, -                          BdrvCheckMode fix) -{ -    BDRVQcowState *s = bs->opaque; -    int64_t size, i, highest_cluster; -    int nb_clusters, refcount1, refcount2; -    QCowSnapshot *sn; -    uint16_t *refcount_table; -    int ret; - -    size = bdrv_getlength(bs->file); -    nb_clusters = size_to_clusters(s, size); -    refcount_table = g_malloc0(nb_clusters * sizeof(uint16_t)); - -    res->bfi.total_clusters = -        size_to_clusters(s, bs->total_sectors * BDRV_SECTOR_SIZE); - -    /* header */ -    inc_refcounts(bs, res, refcount_table, nb_clusters, -        0, s->cluster_size); - -    /* current L1 table */ -    ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, -                             s->l1_table_offset, s->l1_size, -                             CHECK_OFLAG_COPIED | CHECK_FRAG_INFO); -    if (ret < 0) { -        goto fail; -    } - -    /* snapshots */ -    for(i = 0; i < s->nb_snapshots; i++) { -        sn = s->snapshots + i; -        ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, -            sn->l1_table_offset, sn->l1_size, 0); -        if (ret < 0) { -            goto fail; -        } -    } -    inc_refcounts(bs, res, refcount_table, nb_clusters, -        s->snapshots_offset, s->snapshots_size); - -    /* refcount data */ -    inc_refcounts(bs, res, refcount_table, nb_clusters, -        s->refcount_table_offset, -        s->refcount_table_size * sizeof(uint64_t)); - -    for(i = 0; i < s->refcount_table_size; i++) { -        uint64_t offset, cluster; -        offset = s->refcount_table[i]; -        cluster = offset >> s->cluster_bits; - -        /* Refcount blocks are cluster aligned */ -        if (offset & (s->cluster_size - 1)) { -            fprintf(stderr, "ERROR refcount block %" PRId64 " is not " -                "cluster aligned; refcount table entry corrupted\n", i); -            res->corruptions++; -            continue; -        } - -        if (cluster >= nb_clusters) { -            fprintf(stderr, "ERROR refcount block %" PRId64 -                    " is outside image\n", i); -            res->corruptions++; -            continue; -        } - -        if (offset != 0) { -            inc_refcounts(bs, res, refcount_table, nb_clusters, -                offset, s->cluster_size); -            if (refcount_table[cluster] != 1) { -                fprintf(stderr, "ERROR refcount block %" PRId64 -                    " refcount=%d\n", -                    i, refcount_table[cluster]); -                res->corruptions++; -            } -        } -    } - -    /* compare ref counts */ -    for (i = 0, highest_cluster = 0; i < nb_clusters; i++) { -        refcount1 = get_refcount(bs, i); -        if (refcount1 < 0) { -            fprintf(stderr, "Can't get refcount for cluster %" PRId64 ": %s\n", -                i, strerror(-refcount1)); -            res->check_errors++; -            continue; -        } - -        refcount2 = refcount_table[i]; - -        if (refcount1 > 0 || refcount2 > 0) { -            highest_cluster = i; -        } - -        if (refcount1 != refcount2) { - -            /* Check if we're allowed to fix the mismatch */ -            int *num_fixed = NULL; -            if (refcount1 > refcount2 && (fix & BDRV_FIX_LEAKS)) { -                num_fixed = &res->leaks_fixed; -            } else if (refcount1 < refcount2 && (fix & BDRV_FIX_ERRORS)) { -                num_fixed = &res->corruptions_fixed; -            } - -            fprintf(stderr, "%s cluster %" PRId64 " refcount=%d reference=%d\n", -                   num_fixed != NULL     ? "Repairing" : -                   refcount1 < refcount2 ? "ERROR" : -                                           "Leaked", -                   i, refcount1, refcount2); - -            if (num_fixed) { -                ret = update_refcount(bs, i << s->cluster_bits, 1, -                                      refcount2 - refcount1, -                                      QCOW2_DISCARD_ALWAYS); -                if (ret >= 0) { -                    (*num_fixed)++; -                    continue; -                } -            } - -            /* And if we couldn't, print an error */ -            if (refcount1 < refcount2) { -                res->corruptions++; -            } else { -                res->leaks++; -            } -        } -    } - -    res->image_end_offset = (highest_cluster + 1) * s->cluster_size; -    ret = 0; - -fail: -    g_free(refcount_table); - -    return ret; -} - diff --git a/contrib/qemu/block/qcow2-snapshot.c b/contrib/qemu/block/qcow2-snapshot.c deleted file mode 100644 index 0caac9055f8..00000000000 --- a/contrib/qemu/block/qcow2-snapshot.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Block driver for the QCOW version 2 format - * - * Copyright (c) 2004-2006 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "qemu-common.h" -#include "block/block_int.h" -#include "block/qcow2.h" - -typedef struct QEMU_PACKED QCowSnapshotHeader { -    /* header is 8 byte aligned */ -    uint64_t l1_table_offset; - -    uint32_t l1_size; -    uint16_t id_str_size; -    uint16_t name_size; - -    uint32_t date_sec; -    uint32_t date_nsec; - -    uint64_t vm_clock_nsec; - -    uint32_t vm_state_size; -    uint32_t extra_data_size; /* for extension */ -    /* extra data follows */ -    /* id_str follows */ -    /* name follows  */ -} QCowSnapshotHeader; - -typedef struct QEMU_PACKED QCowSnapshotExtraData { -    uint64_t vm_state_size_large; -    uint64_t disk_size; -} QCowSnapshotExtraData; - -void qcow2_free_snapshots(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    int i; - -    for(i = 0; i < s->nb_snapshots; i++) { -        g_free(s->snapshots[i].name); -        g_free(s->snapshots[i].id_str); -    } -    g_free(s->snapshots); -    s->snapshots = NULL; -    s->nb_snapshots = 0; -} - -int qcow2_read_snapshots(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    QCowSnapshotHeader h; -    QCowSnapshotExtraData extra; -    QCowSnapshot *sn; -    int i, id_str_size, name_size; -    int64_t offset; -    uint32_t extra_data_size; -    int ret; - -    if (!s->nb_snapshots) { -        s->snapshots = NULL; -        s->snapshots_size = 0; -        return 0; -    } - -    offset = s->snapshots_offset; -    s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot)); - -    for(i = 0; i < s->nb_snapshots; i++) { -        /* Read statically sized part of the snapshot header */ -        offset = align_offset(offset, 8); -        ret = bdrv_pread(bs->file, offset, &h, sizeof(h)); -        if (ret < 0) { -            goto fail; -        } - -        offset += sizeof(h); -        sn = s->snapshots + i; -        sn->l1_table_offset = be64_to_cpu(h.l1_table_offset); -        sn->l1_size = be32_to_cpu(h.l1_size); -        sn->vm_state_size = be32_to_cpu(h.vm_state_size); -        sn->date_sec = be32_to_cpu(h.date_sec); -        sn->date_nsec = be32_to_cpu(h.date_nsec); -        sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec); -        extra_data_size = be32_to_cpu(h.extra_data_size); - -        id_str_size = be16_to_cpu(h.id_str_size); -        name_size = be16_to_cpu(h.name_size); - -        /* Read extra data */ -        ret = bdrv_pread(bs->file, offset, &extra, -                         MIN(sizeof(extra), extra_data_size)); -        if (ret < 0) { -            goto fail; -        } -        offset += extra_data_size; - -        if (extra_data_size >= 8) { -            sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large); -        } - -        if (extra_data_size >= 16) { -            sn->disk_size = be64_to_cpu(extra.disk_size); -        } else { -            sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; -        } - -        /* Read snapshot ID */ -        sn->id_str = g_malloc(id_str_size + 1); -        ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size); -        if (ret < 0) { -            goto fail; -        } -        offset += id_str_size; -        sn->id_str[id_str_size] = '\0'; - -        /* Read snapshot name */ -        sn->name = g_malloc(name_size + 1); -        ret = bdrv_pread(bs->file, offset, sn->name, name_size); -        if (ret < 0) { -            goto fail; -        } -        offset += name_size; -        sn->name[name_size] = '\0'; -    } - -    s->snapshots_size = offset - s->snapshots_offset; -    return 0; - -fail: -    qcow2_free_snapshots(bs); -    return ret; -} - -/* add at the end of the file a new list of snapshots */ -static int qcow2_write_snapshots(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    QCowSnapshot *sn; -    QCowSnapshotHeader h; -    QCowSnapshotExtraData extra; -    int i, name_size, id_str_size, snapshots_size; -    struct { -        uint32_t nb_snapshots; -        uint64_t snapshots_offset; -    } QEMU_PACKED header_data; -    int64_t offset, snapshots_offset; -    int ret; - -    /* compute the size of the snapshots */ -    offset = 0; -    for(i = 0; i < s->nb_snapshots; i++) { -        sn = s->snapshots + i; -        offset = align_offset(offset, 8); -        offset += sizeof(h); -        offset += sizeof(extra); -        offset += strlen(sn->id_str); -        offset += strlen(sn->name); -    } -    snapshots_size = offset; - -    /* Allocate space for the new snapshot list */ -    snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size); -    offset = snapshots_offset; -    if (offset < 0) { -        return offset; -    } -    ret = bdrv_flush(bs); -    if (ret < 0) { -        return ret; -    } - -    /* Write all snapshots to the new list */ -    for(i = 0; i < s->nb_snapshots; i++) { -        sn = s->snapshots + i; -        memset(&h, 0, sizeof(h)); -        h.l1_table_offset = cpu_to_be64(sn->l1_table_offset); -        h.l1_size = cpu_to_be32(sn->l1_size); -        /* If it doesn't fit in 32 bit, older implementations should treat it -         * as a disk-only snapshot rather than truncate the VM state */ -        if (sn->vm_state_size <= 0xffffffff) { -            h.vm_state_size = cpu_to_be32(sn->vm_state_size); -        } -        h.date_sec = cpu_to_be32(sn->date_sec); -        h.date_nsec = cpu_to_be32(sn->date_nsec); -        h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec); -        h.extra_data_size = cpu_to_be32(sizeof(extra)); - -        memset(&extra, 0, sizeof(extra)); -        extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size); -        extra.disk_size = cpu_to_be64(sn->disk_size); - -        id_str_size = strlen(sn->id_str); -        name_size = strlen(sn->name); -        h.id_str_size = cpu_to_be16(id_str_size); -        h.name_size = cpu_to_be16(name_size); -        offset = align_offset(offset, 8); - -        ret = bdrv_pwrite(bs->file, offset, &h, sizeof(h)); -        if (ret < 0) { -            goto fail; -        } -        offset += sizeof(h); - -        ret = bdrv_pwrite(bs->file, offset, &extra, sizeof(extra)); -        if (ret < 0) { -            goto fail; -        } -        offset += sizeof(extra); - -        ret = bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size); -        if (ret < 0) { -            goto fail; -        } -        offset += id_str_size; - -        ret = bdrv_pwrite(bs->file, offset, sn->name, name_size); -        if (ret < 0) { -            goto fail; -        } -        offset += name_size; -    } - -    /* -     * Update the header to point to the new snapshot table. This requires the -     * new table and its refcounts to be stable on disk. -     */ -    ret = bdrv_flush(bs); -    if (ret < 0) { -        goto fail; -    } - -    QEMU_BUILD_BUG_ON(offsetof(QCowHeader, snapshots_offset) != -        offsetof(QCowHeader, nb_snapshots) + sizeof(header_data.nb_snapshots)); - -    header_data.nb_snapshots        = cpu_to_be32(s->nb_snapshots); -    header_data.snapshots_offset    = cpu_to_be64(snapshots_offset); - -    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots), -                           &header_data, sizeof(header_data)); -    if (ret < 0) { -        goto fail; -    } - -    /* free the old snapshot table */ -    qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size, -                        QCOW2_DISCARD_SNAPSHOT); -    s->snapshots_offset = snapshots_offset; -    s->snapshots_size = snapshots_size; -    return 0; - -fail: -    return ret; -} - -static void find_new_snapshot_id(BlockDriverState *bs, -                                 char *id_str, int id_str_size) -{ -    BDRVQcowState *s = bs->opaque; -    QCowSnapshot *sn; -    int i, id, id_max = 0; - -    for(i = 0; i < s->nb_snapshots; i++) { -        sn = s->snapshots + i; -        id = strtoul(sn->id_str, NULL, 10); -        if (id > id_max) -            id_max = id; -    } -    snprintf(id_str, id_str_size, "%d", id_max + 1); -} - -static int find_snapshot_by_id(BlockDriverState *bs, const char *id_str) -{ -    BDRVQcowState *s = bs->opaque; -    int i; - -    for(i = 0; i < s->nb_snapshots; i++) { -        if (!strcmp(s->snapshots[i].id_str, id_str)) -            return i; -    } -    return -1; -} - -static int find_snapshot_by_id_or_name(BlockDriverState *bs, const char *name) -{ -    BDRVQcowState *s = bs->opaque; -    int i, ret; - -    ret = find_snapshot_by_id(bs, name); -    if (ret >= 0) -        return ret; -    for(i = 0; i < s->nb_snapshots; i++) { -        if (!strcmp(s->snapshots[i].name, name)) -            return i; -    } -    return -1; -} - -/* if no id is provided, a new one is constructed */ -int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) -{ -    BDRVQcowState *s = bs->opaque; -    QCowSnapshot *new_snapshot_list = NULL; -    QCowSnapshot *old_snapshot_list = NULL; -    QCowSnapshot sn1, *sn = &sn1; -    int i, ret; -    uint64_t *l1_table = NULL; -    int64_t l1_table_offset; - -    memset(sn, 0, sizeof(*sn)); - -    /* Generate an ID if it wasn't passed */ -    if (sn_info->id_str[0] == '\0') { -        find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str)); -    } - -    /* Check that the ID is unique */ -    if (find_snapshot_by_id(bs, sn_info->id_str) >= 0) { -        return -EEXIST; -    } - -    /* Populate sn with passed data */ -    sn->id_str = g_strdup(sn_info->id_str); -    sn->name = g_strdup(sn_info->name); - -    sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; -    sn->vm_state_size = sn_info->vm_state_size; -    sn->date_sec = sn_info->date_sec; -    sn->date_nsec = sn_info->date_nsec; -    sn->vm_clock_nsec = sn_info->vm_clock_nsec; - -    /* Allocate the L1 table of the snapshot and copy the current one there. */ -    l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t)); -    if (l1_table_offset < 0) { -        ret = l1_table_offset; -        goto fail; -    } - -    sn->l1_table_offset = l1_table_offset; -    sn->l1_size = s->l1_size; - -    l1_table = g_malloc(s->l1_size * sizeof(uint64_t)); -    for(i = 0; i < s->l1_size; i++) { -        l1_table[i] = cpu_to_be64(s->l1_table[i]); -    } - -    ret = bdrv_pwrite(bs->file, sn->l1_table_offset, l1_table, -                      s->l1_size * sizeof(uint64_t)); -    if (ret < 0) { -        goto fail; -    } - -    g_free(l1_table); -    l1_table = NULL; - -    /* -     * Increase the refcounts of all clusters and make sure everything is -     * stable on disk before updating the snapshot table to contain a pointer -     * to the new L1 table. -     */ -    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1); -    if (ret < 0) { -        goto fail; -    } - -    /* Append the new snapshot to the snapshot list */ -    new_snapshot_list = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot)); -    if (s->snapshots) { -        memcpy(new_snapshot_list, s->snapshots, -               s->nb_snapshots * sizeof(QCowSnapshot)); -        old_snapshot_list = s->snapshots; -    } -    s->snapshots = new_snapshot_list; -    s->snapshots[s->nb_snapshots++] = *sn; - -    ret = qcow2_write_snapshots(bs); -    if (ret < 0) { -        g_free(s->snapshots); -        s->snapshots = old_snapshot_list; -        goto fail; -    } - -    g_free(old_snapshot_list); - -#ifdef DEBUG_ALLOC -    { -      BdrvCheckResult result = {0}; -      qcow2_check_refcounts(bs, &result, 0); -    } -#endif -    return 0; - -fail: -    g_free(sn->id_str); -    g_free(sn->name); -    g_free(l1_table); - -    return ret; -} - -/* copy the snapshot 'snapshot_name' into the current disk image */ -int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) -{ -    BDRVQcowState *s = bs->opaque; -    QCowSnapshot *sn; -    int i, snapshot_index; -    int cur_l1_bytes, sn_l1_bytes; -    int ret; -    uint64_t *sn_l1_table = NULL; - -    /* Search the snapshot */ -    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); -    if (snapshot_index < 0) { -        return -ENOENT; -    } -    sn = &s->snapshots[snapshot_index]; - -    if (sn->disk_size != bs->total_sectors * BDRV_SECTOR_SIZE) { -        error_report("qcow2: Loading snapshots with different disk " -            "size is not implemented"); -        ret = -ENOTSUP; -        goto fail; -    } - -    /* -     * Make sure that the current L1 table is big enough to contain the whole -     * L1 table of the snapshot. If the snapshot L1 table is smaller, the -     * current one must be padded with zeros. -     */ -    ret = qcow2_grow_l1_table(bs, sn->l1_size, true); -    if (ret < 0) { -        goto fail; -    } - -    cur_l1_bytes = s->l1_size * sizeof(uint64_t); -    sn_l1_bytes = sn->l1_size * sizeof(uint64_t); - -    /* -     * Copy the snapshot L1 table to the current L1 table. -     * -     * Before overwriting the old current L1 table on disk, make sure to -     * increase all refcounts for the clusters referenced by the new one. -     * Decrease the refcount referenced by the old one only when the L1 -     * table is overwritten. -     */ -    sn_l1_table = g_malloc0(cur_l1_bytes); - -    ret = bdrv_pread(bs->file, sn->l1_table_offset, sn_l1_table, sn_l1_bytes); -    if (ret < 0) { -        goto fail; -    } - -    ret = qcow2_update_snapshot_refcount(bs, sn->l1_table_offset, -                                         sn->l1_size, 1); -    if (ret < 0) { -        goto fail; -    } - -    ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset, sn_l1_table, -                           cur_l1_bytes); -    if (ret < 0) { -        goto fail; -    } - -    /* -     * Decrease refcount of clusters of current L1 table. -     * -     * At this point, the in-memory s->l1_table points to the old L1 table, -     * whereas on disk we already have the new one. -     * -     * qcow2_update_snapshot_refcount special cases the current L1 table to use -     * the in-memory data instead of really using the offset to load a new one, -     * which is why this works. -     */ -    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, -                                         s->l1_size, -1); - -    /* -     * Now update the in-memory L1 table to be in sync with the on-disk one. We -     * need to do this even if updating refcounts failed. -     */ -    for(i = 0;i < s->l1_size; i++) { -        s->l1_table[i] = be64_to_cpu(sn_l1_table[i]); -    } - -    if (ret < 0) { -        goto fail; -    } - -    g_free(sn_l1_table); -    sn_l1_table = NULL; - -    /* -     * Update QCOW_OFLAG_COPIED in the active L1 table (it may have changed -     * when we decreased the refcount of the old snapshot. -     */ -    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0); -    if (ret < 0) { -        goto fail; -    } - -#ifdef DEBUG_ALLOC -    { -        BdrvCheckResult result = {0}; -        qcow2_check_refcounts(bs, &result, 0); -    } -#endif -    return 0; - -fail: -    g_free(sn_l1_table); -    return ret; -} - -int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) -{ -    BDRVQcowState *s = bs->opaque; -    QCowSnapshot sn; -    int snapshot_index, ret; - -    /* Search the snapshot */ -    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); -    if (snapshot_index < 0) { -        return -ENOENT; -    } -    sn = s->snapshots[snapshot_index]; - -    /* Remove it from the snapshot list */ -    memmove(s->snapshots + snapshot_index, -            s->snapshots + snapshot_index + 1, -            (s->nb_snapshots - snapshot_index - 1) * sizeof(sn)); -    s->nb_snapshots--; -    ret = qcow2_write_snapshots(bs); -    if (ret < 0) { -        return ret; -    } - -    /* -     * The snapshot is now unused, clean up. If we fail after this point, we -     * won't recover but just leak clusters. -     */ -    g_free(sn.id_str); -    g_free(sn.name); - -    /* -     * Now decrease the refcounts of clusters referenced by the snapshot and -     * free the L1 table. -     */ -    ret = qcow2_update_snapshot_refcount(bs, sn.l1_table_offset, -                                         sn.l1_size, -1); -    if (ret < 0) { -        return ret; -    } -    qcow2_free_clusters(bs, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t), -                        QCOW2_DISCARD_SNAPSHOT); - -    /* must update the copied flag on the current cluster offsets */ -    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0); -    if (ret < 0) { -        return ret; -    } - -#ifdef DEBUG_ALLOC -    { -        BdrvCheckResult result = {0}; -        qcow2_check_refcounts(bs, &result, 0); -    } -#endif -    return 0; -} - -int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) -{ -    BDRVQcowState *s = bs->opaque; -    QEMUSnapshotInfo *sn_tab, *sn_info; -    QCowSnapshot *sn; -    int i; - -    if (!s->nb_snapshots) { -        *psn_tab = NULL; -        return s->nb_snapshots; -    } - -    sn_tab = g_malloc0(s->nb_snapshots * sizeof(QEMUSnapshotInfo)); -    for(i = 0; i < s->nb_snapshots; i++) { -        sn_info = sn_tab + i; -        sn = s->snapshots + i; -        pstrcpy(sn_info->id_str, sizeof(sn_info->id_str), -                sn->id_str); -        pstrcpy(sn_info->name, sizeof(sn_info->name), -                sn->name); -        sn_info->vm_state_size = sn->vm_state_size; -        sn_info->date_sec = sn->date_sec; -        sn_info->date_nsec = sn->date_nsec; -        sn_info->vm_clock_nsec = sn->vm_clock_nsec; -    } -    *psn_tab = sn_tab; -    return s->nb_snapshots; -} - -int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name) -{ -    int i, snapshot_index; -    BDRVQcowState *s = bs->opaque; -    QCowSnapshot *sn; -    uint64_t *new_l1_table; -    int new_l1_bytes; -    int ret; - -    assert(bs->read_only); - -    /* Search the snapshot */ -    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_name); -    if (snapshot_index < 0) { -        return -ENOENT; -    } -    sn = &s->snapshots[snapshot_index]; - -    /* Allocate and read in the snapshot's L1 table */ -    new_l1_bytes = s->l1_size * sizeof(uint64_t); -    new_l1_table = g_malloc0(align_offset(new_l1_bytes, 512)); - -    ret = bdrv_pread(bs->file, sn->l1_table_offset, new_l1_table, new_l1_bytes); -    if (ret < 0) { -        g_free(new_l1_table); -        return ret; -    } - -    /* Switch the L1 table */ -    g_free(s->l1_table); - -    s->l1_size = sn->l1_size; -    s->l1_table_offset = sn->l1_table_offset; -    s->l1_table = new_l1_table; - -    for(i = 0;i < s->l1_size; i++) { -        be64_to_cpus(&s->l1_table[i]); -    } - -    return 0; -} diff --git a/contrib/qemu/block/qcow2.c b/contrib/qemu/block/qcow2.c deleted file mode 100644 index 0eceefe2cd9..00000000000 --- a/contrib/qemu/block/qcow2.c +++ /dev/null @@ -1,1825 +0,0 @@ -/* - * Block driver for the QCOW version 2 format - * - * Copyright (c) 2004-2006 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "qemu-common.h" -#include "block/block_int.h" -#include "qemu/module.h" -#include <zlib.h> -#include "qemu/aes.h" -#include "block/qcow2.h" -#include "qemu/error-report.h" -#include "qapi/qmp/qerror.h" -#include "qapi/qmp/qbool.h" -#include "trace.h" - -/* -  Differences with QCOW: - -  - Support for multiple incremental snapshots. -  - Memory management by reference counts. -  - Clusters which have a reference count of one have the bit -    QCOW_OFLAG_COPIED to optimize write performance. -  - Size of compressed clusters is stored in sectors to reduce bit usage -    in the cluster offsets. -  - Support for storing additional data (such as the VM state) in the -    snapshots. -  - If a backing store is used, the cluster size is not constrained -    (could be backported to QCOW). -  - L2 tables have always a size of one cluster. -*/ - - -typedef struct { -    uint32_t magic; -    uint32_t len; -} QCowExtension; - -#define  QCOW2_EXT_MAGIC_END 0 -#define  QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA -#define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857 - -static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename) -{ -    const QCowHeader *cow_header = (const void *)buf; - -    if (buf_size >= sizeof(QCowHeader) && -        be32_to_cpu(cow_header->magic) == QCOW_MAGIC && -        be32_to_cpu(cow_header->version) >= 2) -        return 100; -    else -        return 0; -} - - -/*  - * read qcow2 extension and fill bs - * start reading from start_offset - * finish reading upon magic of value 0 or when end_offset reached - * unknown magic is skipped (future extension this version knows nothing about) - * return 0 upon success, non-0 otherwise - */ -static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, -                                 uint64_t end_offset, void **p_feature_table) -{ -    BDRVQcowState *s = bs->opaque; -    QCowExtension ext; -    uint64_t offset; -    int ret; - -#ifdef DEBUG_EXT -    printf("qcow2_read_extensions: start=%ld end=%ld\n", start_offset, end_offset); -#endif -    offset = start_offset; -    while (offset < end_offset) { - -#ifdef DEBUG_EXT -        /* Sanity check */ -        if (offset > s->cluster_size) -            printf("qcow2_read_extension: suspicious offset %lu\n", offset); - -        printf("attempting to read extended header in offset %lu\n", offset); -#endif - -        if (bdrv_pread(bs->file, offset, &ext, sizeof(ext)) != sizeof(ext)) { -            fprintf(stderr, "qcow2_read_extension: ERROR: " -                    "pread fail from offset %" PRIu64 "\n", -                    offset); -            return 1; -        } -        be32_to_cpus(&ext.magic); -        be32_to_cpus(&ext.len); -        offset += sizeof(ext); -#ifdef DEBUG_EXT -        printf("ext.magic = 0x%x\n", ext.magic); -#endif -        if (ext.len > end_offset - offset) { -            error_report("Header extension too large"); -            return -EINVAL; -        } - -        switch (ext.magic) { -        case QCOW2_EXT_MAGIC_END: -            return 0; - -        case QCOW2_EXT_MAGIC_BACKING_FORMAT: -            if (ext.len >= sizeof(bs->backing_format)) { -                fprintf(stderr, "ERROR: ext_backing_format: len=%u too large" -                        " (>=%zu)\n", -                        ext.len, sizeof(bs->backing_format)); -                return 2; -            } -            if (bdrv_pread(bs->file, offset , bs->backing_format, -                           ext.len) != ext.len) -                return 3; -            bs->backing_format[ext.len] = '\0'; -#ifdef DEBUG_EXT -            printf("Qcow2: Got format extension %s\n", bs->backing_format); -#endif -            break; - -        case QCOW2_EXT_MAGIC_FEATURE_TABLE: -            if (p_feature_table != NULL) { -                void* feature_table = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature)); -                ret = bdrv_pread(bs->file, offset , feature_table, ext.len); -                if (ret < 0) { -                    return ret; -                } - -                *p_feature_table = feature_table; -            } -            break; - -        default: -            /* unknown magic - save it in case we need to rewrite the header */ -            { -                Qcow2UnknownHeaderExtension *uext; - -                uext = g_malloc0(sizeof(*uext)  + ext.len); -                uext->magic = ext.magic; -                uext->len = ext.len; -                QLIST_INSERT_HEAD(&s->unknown_header_ext, uext, next); - -                ret = bdrv_pread(bs->file, offset , uext->data, uext->len); -                if (ret < 0) { -                    return ret; -                } -            } -            break; -        } - -        offset += ((ext.len + 7) & ~7); -    } - -    return 0; -} - -static void cleanup_unknown_header_ext(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    Qcow2UnknownHeaderExtension *uext, *next; - -    QLIST_FOREACH_SAFE(uext, &s->unknown_header_ext, next, next) { -        QLIST_REMOVE(uext, next); -        g_free(uext); -    } -} - -static void GCC_FMT_ATTR(2, 3) report_unsupported(BlockDriverState *bs, -    const char *fmt, ...) -{ -    char msg[64]; -    va_list ap; - -    va_start(ap, fmt); -    vsnprintf(msg, sizeof(msg), fmt, ap); -    va_end(ap); - -    qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, -        bs->device_name, "qcow2", msg); -} - -static void report_unsupported_feature(BlockDriverState *bs, -    Qcow2Feature *table, uint64_t mask) -{ -    while (table && table->name[0] != '\0') { -        if (table->type == QCOW2_FEAT_TYPE_INCOMPATIBLE) { -            if (mask & (1 << table->bit)) { -                report_unsupported(bs, "%.46s",table->name); -                mask &= ~(1 << table->bit); -            } -        } -        table++; -    } - -    if (mask) { -        report_unsupported(bs, "Unknown incompatible feature: %" PRIx64, mask); -    } -} - -/* - * Sets the dirty bit and flushes afterwards if necessary. - * - * The incompatible_features bit is only set if the image file header was - * updated successfully.  Therefore it is not required to check the return - * value of this function. - */ -int qcow2_mark_dirty(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t val; -    int ret; - -    assert(s->qcow_version >= 3); - -    if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) { -        return 0; /* already dirty */ -    } - -    val = cpu_to_be64(s->incompatible_features | QCOW2_INCOMPAT_DIRTY); -    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, incompatible_features), -                      &val, sizeof(val)); -    if (ret < 0) { -        return ret; -    } -    ret = bdrv_flush(bs->file); -    if (ret < 0) { -        return ret; -    } - -    /* Only treat image as dirty if the header was updated successfully */ -    s->incompatible_features |= QCOW2_INCOMPAT_DIRTY; -    return 0; -} - -/* - * Clears the dirty bit and flushes before if necessary.  Only call this - * function when there are no pending requests, it does not guard against - * concurrent requests dirtying the image. - */ -static int qcow2_mark_clean(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; - -    if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) { -        int ret = bdrv_flush(bs); -        if (ret < 0) { -            return ret; -        } - -        s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY; -        return qcow2_update_header(bs); -    } -    return 0; -} - -static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result, -                       BdrvCheckMode fix) -{ -    int ret = qcow2_check_refcounts(bs, result, fix); -    if (ret < 0) { -        return ret; -    } - -    if (fix && result->check_errors == 0 && result->corruptions == 0) { -        return qcow2_mark_clean(bs); -    } -    return ret; -} - -static QemuOptsList qcow2_runtime_opts = { -    .name = "qcow2", -    .head = QTAILQ_HEAD_INITIALIZER(qcow2_runtime_opts.head), -    .desc = { -        { -            .name = "lazy_refcounts", -            .type = QEMU_OPT_BOOL, -            .help = "Postpone refcount updates", -        }, -        { -            .name = QCOW2_OPT_DISCARD_REQUEST, -            .type = QEMU_OPT_BOOL, -            .help = "Pass guest discard requests to the layer below", -        }, -        { -            .name = QCOW2_OPT_DISCARD_SNAPSHOT, -            .type = QEMU_OPT_BOOL, -            .help = "Generate discard requests when snapshot related space " -                    "is freed", -        }, -        { -            .name = QCOW2_OPT_DISCARD_OTHER, -            .type = QEMU_OPT_BOOL, -            .help = "Generate discard requests when other clusters are freed", -        }, -        { /* end of list */ } -    }, -}; - -static int qcow2_open(BlockDriverState *bs, QDict *options, int flags) -{ -    BDRVQcowState *s = bs->opaque; -    int len, i, ret = 0; -    QCowHeader header; -    QemuOpts *opts; -    Error *local_err = NULL; -    uint64_t ext_end; -    uint64_t l1_vm_state_index; - -    ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); -    if (ret < 0) { -        goto fail; -    } -    be32_to_cpus(&header.magic); -    be32_to_cpus(&header.version); -    be64_to_cpus(&header.backing_file_offset); -    be32_to_cpus(&header.backing_file_size); -    be64_to_cpus(&header.size); -    be32_to_cpus(&header.cluster_bits); -    be32_to_cpus(&header.crypt_method); -    be64_to_cpus(&header.l1_table_offset); -    be32_to_cpus(&header.l1_size); -    be64_to_cpus(&header.refcount_table_offset); -    be32_to_cpus(&header.refcount_table_clusters); -    be64_to_cpus(&header.snapshots_offset); -    be32_to_cpus(&header.nb_snapshots); - -    if (header.magic != QCOW_MAGIC) { -        ret = -EMEDIUMTYPE; -        goto fail; -    } -    if (header.version < 2 || header.version > 3) { -        report_unsupported(bs, "QCOW version %d", header.version); -        ret = -ENOTSUP; -        goto fail; -    } - -    s->qcow_version = header.version; - -    /* Initialise version 3 header fields */ -    if (header.version == 2) { -        header.incompatible_features    = 0; -        header.compatible_features      = 0; -        header.autoclear_features       = 0; -        header.refcount_order           = 4; -        header.header_length            = 72; -    } else { -        be64_to_cpus(&header.incompatible_features); -        be64_to_cpus(&header.compatible_features); -        be64_to_cpus(&header.autoclear_features); -        be32_to_cpus(&header.refcount_order); -        be32_to_cpus(&header.header_length); -    } - -    if (header.header_length > sizeof(header)) { -        s->unknown_header_fields_size = header.header_length - sizeof(header); -        s->unknown_header_fields = g_malloc(s->unknown_header_fields_size); -        ret = bdrv_pread(bs->file, sizeof(header), s->unknown_header_fields, -                         s->unknown_header_fields_size); -        if (ret < 0) { -            goto fail; -        } -    } - -    if (header.backing_file_offset) { -        ext_end = header.backing_file_offset; -    } else { -        ext_end = 1 << header.cluster_bits; -    } - -    /* Handle feature bits */ -    s->incompatible_features    = header.incompatible_features; -    s->compatible_features      = header.compatible_features; -    s->autoclear_features       = header.autoclear_features; - -    if (s->incompatible_features & ~QCOW2_INCOMPAT_MASK) { -        void *feature_table = NULL; -        qcow2_read_extensions(bs, header.header_length, ext_end, -                              &feature_table); -        report_unsupported_feature(bs, feature_table, -                                   s->incompatible_features & -                                   ~QCOW2_INCOMPAT_MASK); -        ret = -ENOTSUP; -        goto fail; -    } - -    /* Check support for various header values */ -    if (header.refcount_order != 4) { -        report_unsupported(bs, "%d bit reference counts", -                           1 << header.refcount_order); -        ret = -ENOTSUP; -        goto fail; -    } - -    if (header.cluster_bits < MIN_CLUSTER_BITS || -        header.cluster_bits > MAX_CLUSTER_BITS) { -        ret = -EINVAL; -        goto fail; -    } -    if (header.crypt_method > QCOW_CRYPT_AES) { -        ret = -EINVAL; -        goto fail; -    } -    s->crypt_method_header = header.crypt_method; -    if (s->crypt_method_header) { -        bs->encrypted = 1; -    } -    s->cluster_bits = header.cluster_bits; -    s->cluster_size = 1 << s->cluster_bits; -    s->cluster_sectors = 1 << (s->cluster_bits - 9); -    s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */ -    s->l2_size = 1 << s->l2_bits; -    bs->total_sectors = header.size / 512; -    s->csize_shift = (62 - (s->cluster_bits - 8)); -    s->csize_mask = (1 << (s->cluster_bits - 8)) - 1; -    s->cluster_offset_mask = (1LL << s->csize_shift) - 1; -    s->refcount_table_offset = header.refcount_table_offset; -    s->refcount_table_size = -        header.refcount_table_clusters << (s->cluster_bits - 3); - -    s->snapshots_offset = header.snapshots_offset; -    s->nb_snapshots = header.nb_snapshots; - -    /* read the level 1 table */ -    s->l1_size = header.l1_size; - -    l1_vm_state_index = size_to_l1(s, header.size); -    if (l1_vm_state_index > INT_MAX) { -        ret = -EFBIG; -        goto fail; -    } -    s->l1_vm_state_index = l1_vm_state_index; - -    /* the L1 table must contain at least enough entries to put -       header.size bytes */ -    if (s->l1_size < s->l1_vm_state_index) { -        ret = -EINVAL; -        goto fail; -    } -    s->l1_table_offset = header.l1_table_offset; -    if (s->l1_size > 0) { -        s->l1_table = g_malloc0( -            align_offset(s->l1_size * sizeof(uint64_t), 512)); -        ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, -                         s->l1_size * sizeof(uint64_t)); -        if (ret < 0) { -            goto fail; -        } -        for(i = 0;i < s->l1_size; i++) { -            be64_to_cpus(&s->l1_table[i]); -        } -    } - -    /* alloc L2 table/refcount block cache */ -    s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE); -    s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE); - -    s->cluster_cache = g_malloc(s->cluster_size); -    /* one more sector for decompressed data alignment */ -    s->cluster_data = qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size -                                  + 512); -    s->cluster_cache_offset = -1; -    s->flags = flags; - -    ret = qcow2_refcount_init(bs); -    if (ret != 0) { -        goto fail; -    } - -    QLIST_INIT(&s->cluster_allocs); -    QTAILQ_INIT(&s->discards); - -    /* read qcow2 extensions */ -    if (qcow2_read_extensions(bs, header.header_length, ext_end, NULL)) { -        ret = -EINVAL; -        goto fail; -    } - -    /* read the backing file name */ -    if (header.backing_file_offset != 0) { -        len = header.backing_file_size; -        if (len > 1023) { -            len = 1023; -        } -        ret = bdrv_pread(bs->file, header.backing_file_offset, -                         bs->backing_file, len); -        if (ret < 0) { -            goto fail; -        } -        bs->backing_file[len] = '\0'; -    } - -    ret = qcow2_read_snapshots(bs); -    if (ret < 0) { -        goto fail; -    } - -    /* Clear unknown autoclear feature bits */ -    if (!bs->read_only && s->autoclear_features != 0) { -        s->autoclear_features = 0; -        ret = qcow2_update_header(bs); -        if (ret < 0) { -            goto fail; -        } -    } - -    /* Initialise locks */ -    qemu_co_mutex_init(&s->lock); - -    /* Repair image if dirty */ -    if (!(flags & BDRV_O_CHECK) && !bs->read_only && -        (s->incompatible_features & QCOW2_INCOMPAT_DIRTY)) { -        BdrvCheckResult result = {0}; - -        ret = qcow2_check(bs, &result, BDRV_FIX_ERRORS); -        if (ret < 0) { -            goto fail; -        } -    } - -    /* Enable lazy_refcounts according to image and command line options */ -    opts = qemu_opts_create_nofail(&qcow2_runtime_opts); -    qemu_opts_absorb_qdict(opts, options, &local_err); -    if (error_is_set(&local_err)) { -        qerror_report_err(local_err); -        error_free(local_err); -        ret = -EINVAL; -        goto fail; -    } - -    s->use_lazy_refcounts = qemu_opt_get_bool(opts, QCOW2_OPT_LAZY_REFCOUNTS, -        (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS)); - -    s->discard_passthrough[QCOW2_DISCARD_NEVER] = false; -    s->discard_passthrough[QCOW2_DISCARD_ALWAYS] = true; -    s->discard_passthrough[QCOW2_DISCARD_REQUEST] = -        qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_REQUEST, -                          flags & BDRV_O_UNMAP); -    s->discard_passthrough[QCOW2_DISCARD_SNAPSHOT] = -        qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_SNAPSHOT, true); -    s->discard_passthrough[QCOW2_DISCARD_OTHER] = -        qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_OTHER, false); - -    qemu_opts_del(opts); - -    if (s->use_lazy_refcounts && s->qcow_version < 3) { -        qerror_report(ERROR_CLASS_GENERIC_ERROR, "Lazy refcounts require " -            "a qcow2 image with at least qemu 1.1 compatibility level"); -        ret = -EINVAL; -        goto fail; -    } - -#ifdef DEBUG_ALLOC -    { -        BdrvCheckResult result = {0}; -        qcow2_check_refcounts(bs, &result, 0); -    } -#endif -    return ret; - - fail: -    g_free(s->unknown_header_fields); -    cleanup_unknown_header_ext(bs); -    qcow2_free_snapshots(bs); -    qcow2_refcount_close(bs); -    g_free(s->l1_table); -    if (s->l2_table_cache) { -        qcow2_cache_destroy(bs, s->l2_table_cache); -    } -    g_free(s->cluster_cache); -    qemu_vfree(s->cluster_data); -    return ret; -} - -static int qcow2_set_key(BlockDriverState *bs, const char *key) -{ -    BDRVQcowState *s = bs->opaque; -    uint8_t keybuf[16]; -    int len, i; - -    memset(keybuf, 0, 16); -    len = strlen(key); -    if (len > 16) -        len = 16; -    /* XXX: we could compress the chars to 7 bits to increase -       entropy */ -    for(i = 0;i < len;i++) { -        keybuf[i] = key[i]; -    } -    s->crypt_method = s->crypt_method_header; - -    if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0) -        return -1; -    if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0) -        return -1; -#if 0 -    /* test */ -    { -        uint8_t in[16]; -        uint8_t out[16]; -        uint8_t tmp[16]; -        for(i=0;i<16;i++) -            in[i] = i; -        AES_encrypt(in, tmp, &s->aes_encrypt_key); -        AES_decrypt(tmp, out, &s->aes_decrypt_key); -        for(i = 0; i < 16; i++) -            printf(" %02x", tmp[i]); -        printf("\n"); -        for(i = 0; i < 16; i++) -            printf(" %02x", out[i]); -        printf("\n"); -    } -#endif -    return 0; -} - -/* We have nothing to do for QCOW2 reopen, stubs just return - * success */ -static int qcow2_reopen_prepare(BDRVReopenState *state, -                                BlockReopenQueue *queue, Error **errp) -{ -    return 0; -} - -static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors, int *pnum) -{ -    BDRVQcowState *s = bs->opaque; -    uint64_t cluster_offset; -    int ret; - -    *pnum = nb_sectors; -    /* FIXME We can get errors here, but the bdrv_co_is_allocated interface -     * can't pass them on today */ -    qemu_co_mutex_lock(&s->lock); -    ret = qcow2_get_cluster_offset(bs, sector_num << 9, pnum, &cluster_offset); -    qemu_co_mutex_unlock(&s->lock); -    if (ret < 0) { -        *pnum = 0; -    } - -    return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO); -} - -/* handle reading after the end of the backing file */ -int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, -                  int64_t sector_num, int nb_sectors) -{ -    int n1; -    if ((sector_num + nb_sectors) <= bs->total_sectors) -        return nb_sectors; -    if (sector_num >= bs->total_sectors) -        n1 = 0; -    else -        n1 = bs->total_sectors - sector_num; - -    qemu_iovec_memset(qiov, 512 * n1, 0, 512 * (nb_sectors - n1)); - -    return n1; -} - -static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num, -                          int remaining_sectors, QEMUIOVector *qiov) -{ -    BDRVQcowState *s = bs->opaque; -    int index_in_cluster, n1; -    int ret; -    int cur_nr_sectors; /* number of sectors in current iteration */ -    uint64_t cluster_offset = 0; -    uint64_t bytes_done = 0; -    QEMUIOVector hd_qiov; -    uint8_t *cluster_data = NULL; - -    qemu_iovec_init(&hd_qiov, qiov->niov); - -    qemu_co_mutex_lock(&s->lock); - -    while (remaining_sectors != 0) { - -        /* prepare next request */ -        cur_nr_sectors = remaining_sectors; -        if (s->crypt_method) { -            cur_nr_sectors = MIN(cur_nr_sectors, -                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); -        } - -        ret = qcow2_get_cluster_offset(bs, sector_num << 9, -            &cur_nr_sectors, &cluster_offset); -        if (ret < 0) { -            goto fail; -        } - -        index_in_cluster = sector_num & (s->cluster_sectors - 1); - -        qemu_iovec_reset(&hd_qiov); -        qemu_iovec_concat(&hd_qiov, qiov, bytes_done, -            cur_nr_sectors * 512); - -        switch (ret) { -        case QCOW2_CLUSTER_UNALLOCATED: - -            if (bs->backing_hd) { -                /* read from the base image */ -                n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov, -                    sector_num, cur_nr_sectors); -                if (n1 > 0) { -                    BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); -                    qemu_co_mutex_unlock(&s->lock); -                    ret = bdrv_co_readv(bs->backing_hd, sector_num, -                                        n1, &hd_qiov); -                    qemu_co_mutex_lock(&s->lock); -                    if (ret < 0) { -                        goto fail; -                    } -                } -            } else { -                /* Note: in this case, no need to wait */ -                qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors); -            } -            break; - -        case QCOW2_CLUSTER_ZERO: -            qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors); -            break; - -        case QCOW2_CLUSTER_COMPRESSED: -            /* add AIO support for compressed blocks ? */ -            ret = qcow2_decompress_cluster(bs, cluster_offset); -            if (ret < 0) { -                goto fail; -            } - -            qemu_iovec_from_buf(&hd_qiov, 0, -                s->cluster_cache + index_in_cluster * 512, -                512 * cur_nr_sectors); -            break; - -        case QCOW2_CLUSTER_NORMAL: -            if ((cluster_offset & 511) != 0) { -                ret = -EIO; -                goto fail; -            } - -            if (s->crypt_method) { -                /* -                 * For encrypted images, read everything into a temporary -                 * contiguous buffer on which the AES functions can work. -                 */ -                if (!cluster_data) { -                    cluster_data = -                        qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); -                } - -                assert(cur_nr_sectors <= -                    QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); -                qemu_iovec_reset(&hd_qiov); -                qemu_iovec_add(&hd_qiov, cluster_data, -                    512 * cur_nr_sectors); -            } - -            BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); -            qemu_co_mutex_unlock(&s->lock); -            ret = bdrv_co_readv(bs->file, -                                (cluster_offset >> 9) + index_in_cluster, -                                cur_nr_sectors, &hd_qiov); -            qemu_co_mutex_lock(&s->lock); -            if (ret < 0) { -                goto fail; -            } -            if (s->crypt_method) { -                qcow2_encrypt_sectors(s, sector_num,  cluster_data, -                    cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key); -                qemu_iovec_from_buf(qiov, bytes_done, -                    cluster_data, 512 * cur_nr_sectors); -            } -            break; - -        default: -            g_assert_not_reached(); -            ret = -EIO; -            goto fail; -        } - -        remaining_sectors -= cur_nr_sectors; -        sector_num += cur_nr_sectors; -        bytes_done += cur_nr_sectors * 512; -    } -    ret = 0; - -fail: -    qemu_co_mutex_unlock(&s->lock); - -    qemu_iovec_destroy(&hd_qiov); -    qemu_vfree(cluster_data); - -    return ret; -} - -static coroutine_fn int qcow2_co_writev(BlockDriverState *bs, -                           int64_t sector_num, -                           int remaining_sectors, -                           QEMUIOVector *qiov) -{ -    BDRVQcowState *s = bs->opaque; -    int index_in_cluster; -    int n_end; -    int ret; -    int cur_nr_sectors; /* number of sectors in current iteration */ -    uint64_t cluster_offset; -    QEMUIOVector hd_qiov; -    uint64_t bytes_done = 0; -    uint8_t *cluster_data = NULL; -    QCowL2Meta *l2meta = NULL; - -    trace_qcow2_writev_start_req(qemu_coroutine_self(), sector_num, -                                 remaining_sectors); - -    qemu_iovec_init(&hd_qiov, qiov->niov); - -    s->cluster_cache_offset = -1; /* disable compressed cache */ - -    qemu_co_mutex_lock(&s->lock); - -    while (remaining_sectors != 0) { - -        l2meta = NULL; - -        trace_qcow2_writev_start_part(qemu_coroutine_self()); -        index_in_cluster = sector_num & (s->cluster_sectors - 1); -        n_end = index_in_cluster + remaining_sectors; -        if (s->crypt_method && -            n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) { -            n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; -        } - -        ret = qcow2_alloc_cluster_offset(bs, sector_num << 9, -            index_in_cluster, n_end, &cur_nr_sectors, &cluster_offset, &l2meta); -        if (ret < 0) { -            goto fail; -        } - -        assert((cluster_offset & 511) == 0); - -        qemu_iovec_reset(&hd_qiov); -        qemu_iovec_concat(&hd_qiov, qiov, bytes_done, -            cur_nr_sectors * 512); - -        if (s->crypt_method) { -            if (!cluster_data) { -                cluster_data = qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS * -                                                 s->cluster_size); -            } - -            assert(hd_qiov.size <= -                   QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); -            qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size); - -            qcow2_encrypt_sectors(s, sector_num, cluster_data, -                cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key); - -            qemu_iovec_reset(&hd_qiov); -            qemu_iovec_add(&hd_qiov, cluster_data, -                cur_nr_sectors * 512); -        } - -        qemu_co_mutex_unlock(&s->lock); -        BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); -        trace_qcow2_writev_data(qemu_coroutine_self(), -                                (cluster_offset >> 9) + index_in_cluster); -        ret = bdrv_co_writev(bs->file, -                             (cluster_offset >> 9) + index_in_cluster, -                             cur_nr_sectors, &hd_qiov); -        qemu_co_mutex_lock(&s->lock); -        if (ret < 0) { -            goto fail; -        } - -        while (l2meta != NULL) { -            QCowL2Meta *next; - -            ret = qcow2_alloc_cluster_link_l2(bs, l2meta); -            if (ret < 0) { -                goto fail; -            } - -            /* Take the request off the list of running requests */ -            if (l2meta->nb_clusters != 0) { -                QLIST_REMOVE(l2meta, next_in_flight); -            } - -            qemu_co_queue_restart_all(&l2meta->dependent_requests); - -            next = l2meta->next; -            g_free(l2meta); -            l2meta = next; -        } - -        remaining_sectors -= cur_nr_sectors; -        sector_num += cur_nr_sectors; -        bytes_done += cur_nr_sectors * 512; -        trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_nr_sectors); -    } -    ret = 0; - -fail: -    qemu_co_mutex_unlock(&s->lock); - -    while (l2meta != NULL) { -        QCowL2Meta *next; - -        if (l2meta->nb_clusters != 0) { -            QLIST_REMOVE(l2meta, next_in_flight); -        } -        qemu_co_queue_restart_all(&l2meta->dependent_requests); - -        next = l2meta->next; -        g_free(l2meta); -        l2meta = next; -    } - -    qemu_iovec_destroy(&hd_qiov); -    qemu_vfree(cluster_data); -    trace_qcow2_writev_done_req(qemu_coroutine_self(), ret); - -    return ret; -} - -static void qcow2_close(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    g_free(s->l1_table); - -    qcow2_cache_flush(bs, s->l2_table_cache); -    qcow2_cache_flush(bs, s->refcount_block_cache); - -    qcow2_mark_clean(bs); - -    qcow2_cache_destroy(bs, s->l2_table_cache); -    qcow2_cache_destroy(bs, s->refcount_block_cache); - -    g_free(s->unknown_header_fields); -    cleanup_unknown_header_ext(bs); - -    g_free(s->cluster_cache); -    qemu_vfree(s->cluster_data); -    qcow2_refcount_close(bs); -    qcow2_free_snapshots(bs); -} - -static void qcow2_invalidate_cache(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    int flags = s->flags; -    AES_KEY aes_encrypt_key; -    AES_KEY aes_decrypt_key; -    uint32_t crypt_method = 0; -    QDict *options; - -    /* -     * Backing files are read-only which makes all of their metadata immutable, -     * that means we don't have to worry about reopening them here. -     */ - -    if (s->crypt_method) { -        crypt_method = s->crypt_method; -        memcpy(&aes_encrypt_key, &s->aes_encrypt_key, sizeof(aes_encrypt_key)); -        memcpy(&aes_decrypt_key, &s->aes_decrypt_key, sizeof(aes_decrypt_key)); -    } - -    qcow2_close(bs); - -    options = qdict_new(); -    qdict_put(options, QCOW2_OPT_LAZY_REFCOUNTS, -              qbool_from_int(s->use_lazy_refcounts)); - -    memset(s, 0, sizeof(BDRVQcowState)); -    qcow2_open(bs, options, flags); - -    QDECREF(options); - -    if (crypt_method) { -        s->crypt_method = crypt_method; -        memcpy(&s->aes_encrypt_key, &aes_encrypt_key, sizeof(aes_encrypt_key)); -        memcpy(&s->aes_decrypt_key, &aes_decrypt_key, sizeof(aes_decrypt_key)); -    } -} - -static size_t header_ext_add(char *buf, uint32_t magic, const void *s, -    size_t len, size_t buflen) -{ -    QCowExtension *ext_backing_fmt = (QCowExtension*) buf; -    size_t ext_len = sizeof(QCowExtension) + ((len + 7) & ~7); - -    if (buflen < ext_len) { -        return -ENOSPC; -    } - -    *ext_backing_fmt = (QCowExtension) { -        .magic  = cpu_to_be32(magic), -        .len    = cpu_to_be32(len), -    }; -    memcpy(buf + sizeof(QCowExtension), s, len); - -    return ext_len; -} - -/* - * Updates the qcow2 header, including the variable length parts of it, i.e. - * the backing file name and all extensions. qcow2 was not designed to allow - * such changes, so if we run out of space (we can only use the first cluster) - * this function may fail. - * - * Returns 0 on success, -errno in error cases. - */ -int qcow2_update_header(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    QCowHeader *header; -    char *buf; -    size_t buflen = s->cluster_size; -    int ret; -    uint64_t total_size; -    uint32_t refcount_table_clusters; -    size_t header_length; -    Qcow2UnknownHeaderExtension *uext; - -    buf = qemu_blockalign(bs, buflen); - -    /* Header structure */ -    header = (QCowHeader*) buf; - -    if (buflen < sizeof(*header)) { -        ret = -ENOSPC; -        goto fail; -    } - -    header_length = sizeof(*header) + s->unknown_header_fields_size; -    total_size = bs->total_sectors * BDRV_SECTOR_SIZE; -    refcount_table_clusters = s->refcount_table_size >> (s->cluster_bits - 3); - -    *header = (QCowHeader) { -        /* Version 2 fields */ -        .magic                  = cpu_to_be32(QCOW_MAGIC), -        .version                = cpu_to_be32(s->qcow_version), -        .backing_file_offset    = 0, -        .backing_file_size      = 0, -        .cluster_bits           = cpu_to_be32(s->cluster_bits), -        .size                   = cpu_to_be64(total_size), -        .crypt_method           = cpu_to_be32(s->crypt_method_header), -        .l1_size                = cpu_to_be32(s->l1_size), -        .l1_table_offset        = cpu_to_be64(s->l1_table_offset), -        .refcount_table_offset  = cpu_to_be64(s->refcount_table_offset), -        .refcount_table_clusters = cpu_to_be32(refcount_table_clusters), -        .nb_snapshots           = cpu_to_be32(s->nb_snapshots), -        .snapshots_offset       = cpu_to_be64(s->snapshots_offset), - -        /* Version 3 fields */ -        .incompatible_features  = cpu_to_be64(s->incompatible_features), -        .compatible_features    = cpu_to_be64(s->compatible_features), -        .autoclear_features     = cpu_to_be64(s->autoclear_features), -        .refcount_order         = cpu_to_be32(3 + REFCOUNT_SHIFT), -        .header_length          = cpu_to_be32(header_length), -    }; - -    /* For older versions, write a shorter header */ -    switch (s->qcow_version) { -    case 2: -        ret = offsetof(QCowHeader, incompatible_features); -        break; -    case 3: -        ret = sizeof(*header); -        break; -    default: -        ret = -EINVAL; -        goto fail; -    } - -    buf += ret; -    buflen -= ret; -    memset(buf, 0, buflen); - -    /* Preserve any unknown field in the header */ -    if (s->unknown_header_fields_size) { -        if (buflen < s->unknown_header_fields_size) { -            ret = -ENOSPC; -            goto fail; -        } - -        memcpy(buf, s->unknown_header_fields, s->unknown_header_fields_size); -        buf += s->unknown_header_fields_size; -        buflen -= s->unknown_header_fields_size; -    } - -    /* Backing file format header extension */ -    if (*bs->backing_format) { -        ret = header_ext_add(buf, QCOW2_EXT_MAGIC_BACKING_FORMAT, -                             bs->backing_format, strlen(bs->backing_format), -                             buflen); -        if (ret < 0) { -            goto fail; -        } - -        buf += ret; -        buflen -= ret; -    } - -    /* Feature table */ -    Qcow2Feature features[] = { -        { -            .type = QCOW2_FEAT_TYPE_INCOMPATIBLE, -            .bit  = QCOW2_INCOMPAT_DIRTY_BITNR, -            .name = "dirty bit", -        }, -        { -            .type = QCOW2_FEAT_TYPE_COMPATIBLE, -            .bit  = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR, -            .name = "lazy refcounts", -        }, -    }; - -    ret = header_ext_add(buf, QCOW2_EXT_MAGIC_FEATURE_TABLE, -                         features, sizeof(features), buflen); -    if (ret < 0) { -        goto fail; -    } -    buf += ret; -    buflen -= ret; - -    /* Keep unknown header extensions */ -    QLIST_FOREACH(uext, &s->unknown_header_ext, next) { -        ret = header_ext_add(buf, uext->magic, uext->data, uext->len, buflen); -        if (ret < 0) { -            goto fail; -        } - -        buf += ret; -        buflen -= ret; -    } - -    /* End of header extensions */ -    ret = header_ext_add(buf, QCOW2_EXT_MAGIC_END, NULL, 0, buflen); -    if (ret < 0) { -        goto fail; -    } - -    buf += ret; -    buflen -= ret; - -    /* Backing file name */ -    if (*bs->backing_file) { -        size_t backing_file_len = strlen(bs->backing_file); - -        if (buflen < backing_file_len) { -            ret = -ENOSPC; -            goto fail; -        } - -        /* Using strncpy is ok here, since buf is not NUL-terminated. */ -        strncpy(buf, bs->backing_file, buflen); - -        header->backing_file_offset = cpu_to_be64(buf - ((char*) header)); -        header->backing_file_size   = cpu_to_be32(backing_file_len); -    } - -    /* Write the new header */ -    ret = bdrv_pwrite(bs->file, 0, header, s->cluster_size); -    if (ret < 0) { -        goto fail; -    } - -    ret = 0; -fail: -    qemu_vfree(header); -    return ret; -} - -static int qcow2_change_backing_file(BlockDriverState *bs, -    const char *backing_file, const char *backing_fmt) -{ -    pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_file ?: ""); -    pstrcpy(bs->backing_format, sizeof(bs->backing_format), backing_fmt ?: ""); - -    return qcow2_update_header(bs); -} - -static int preallocate(BlockDriverState *bs) -{ -    uint64_t nb_sectors; -    uint64_t offset; -    uint64_t host_offset = 0; -    int num; -    int ret; -    QCowL2Meta *meta; - -    nb_sectors = bdrv_getlength(bs) >> 9; -    offset = 0; - -    while (nb_sectors) { -        num = MIN(nb_sectors, INT_MAX >> 9); -        ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, -                                         &host_offset, &meta); -        if (ret < 0) { -            return ret; -        } - -        ret = qcow2_alloc_cluster_link_l2(bs, meta); -        if (ret < 0) { -            qcow2_free_any_clusters(bs, meta->alloc_offset, meta->nb_clusters, -                                    QCOW2_DISCARD_NEVER); -            return ret; -        } - -        /* There are no dependent requests, but we need to remove our request -         * from the list of in-flight requests */ -        if (meta != NULL) { -            QLIST_REMOVE(meta, next_in_flight); -        } - -        /* TODO Preallocate data if requested */ - -        nb_sectors -= num; -        offset += num << 9; -    } - -    /* -     * It is expected that the image file is large enough to actually contain -     * all of the allocated clusters (otherwise we get failing reads after -     * EOF). Extend the image to the last allocated sector. -     */ -    if (host_offset != 0) { -        uint8_t buf[512]; -        memset(buf, 0, 512); -        ret = bdrv_write(bs->file, (host_offset >> 9) + num - 1, buf, 1); -        if (ret < 0) { -            return ret; -        } -    } - -    return 0; -} - -static int qcow2_create2(const char *filename, int64_t total_size, -                         const char *backing_file, const char *backing_format, -                         int flags, size_t cluster_size, int prealloc, -                         QEMUOptionParameter *options, int version) -{ -    /* Calculate cluster_bits */ -    int cluster_bits; -    cluster_bits = ffs(cluster_size) - 1; -    if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS || -        (1 << cluster_bits) != cluster_size) -    { -        error_report( -            "Cluster size must be a power of two between %d and %dk", -            1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10)); -        return -EINVAL; -    } - -    /* -     * Open the image file and write a minimal qcow2 header. -     * -     * We keep things simple and start with a zero-sized image. We also -     * do without refcount blocks or a L1 table for now. We'll fix the -     * inconsistency later. -     * -     * We do need a refcount table because growing the refcount table means -     * allocating two new refcount blocks - the seconds of which would be at -     * 2 GB for 64k clusters, and we don't want to have a 2 GB initial file -     * size for any qcow2 image. -     */ -    BlockDriverState* bs; -    QCowHeader header; -    uint8_t* refcount_table; -    int ret; - -    ret = bdrv_create_file(filename, options); -    if (ret < 0) { -        return ret; -    } - -    ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR); -    if (ret < 0) { -        return ret; -    } - -    /* Write the header */ -    memset(&header, 0, sizeof(header)); -    header.magic = cpu_to_be32(QCOW_MAGIC); -    header.version = cpu_to_be32(version); -    header.cluster_bits = cpu_to_be32(cluster_bits); -    header.size = cpu_to_be64(0); -    header.l1_table_offset = cpu_to_be64(0); -    header.l1_size = cpu_to_be32(0); -    header.refcount_table_offset = cpu_to_be64(cluster_size); -    header.refcount_table_clusters = cpu_to_be32(1); -    header.refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT); -    header.header_length = cpu_to_be32(sizeof(header)); - -    if (flags & BLOCK_FLAG_ENCRYPT) { -        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES); -    } else { -        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); -    } - -    if (flags & BLOCK_FLAG_LAZY_REFCOUNTS) { -        header.compatible_features |= -            cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS); -    } - -    ret = bdrv_pwrite(bs, 0, &header, sizeof(header)); -    if (ret < 0) { -        goto out; -    } - -    /* Write an empty refcount table */ -    refcount_table = g_malloc0(cluster_size); -    ret = bdrv_pwrite(bs, cluster_size, refcount_table, cluster_size); -    g_free(refcount_table); - -    if (ret < 0) { -        goto out; -    } - -    bdrv_close(bs); - -    /* -     * And now open the image and make it consistent first (i.e. increase the -     * refcount of the cluster that is occupied by the header and the refcount -     * table) -     */ -    BlockDriver* drv = bdrv_find_format("qcow2"); -    assert(drv != NULL); -    ret = bdrv_open(bs, filename, NULL, -        BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv); -    if (ret < 0) { -        goto out; -    } - -    ret = qcow2_alloc_clusters(bs, 2 * cluster_size); -    if (ret < 0) { -        goto out; - -    } else if (ret != 0) { -        error_report("Huh, first cluster in empty image is already in use?"); -        abort(); -    } - -    /* Okay, now that we have a valid image, let's give it the right size */ -    ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE); -    if (ret < 0) { -        goto out; -    } - -    /* Want a backing file? There you go.*/ -    if (backing_file) { -        ret = bdrv_change_backing_file(bs, backing_file, backing_format); -        if (ret < 0) { -            goto out; -        } -    } - -    /* And if we're supposed to preallocate metadata, do that now */ -    if (prealloc) { -        BDRVQcowState *s = bs->opaque; -        qemu_co_mutex_lock(&s->lock); -        ret = preallocate(bs); -        qemu_co_mutex_unlock(&s->lock); -        if (ret < 0) { -            goto out; -        } -    } - -    ret = 0; -out: -    bdrv_delete(bs); -    return ret; -} - -static int qcow2_create(const char *filename, QEMUOptionParameter *options) -{ -    const char *backing_file = NULL; -    const char *backing_fmt = NULL; -    uint64_t sectors = 0; -    int flags = 0; -    size_t cluster_size = DEFAULT_CLUSTER_SIZE; -    int prealloc = 0; -    int version = 2; - -    /* Read out options */ -    while (options && options->name) { -        if (!strcmp(options->name, BLOCK_OPT_SIZE)) { -            sectors = options->value.n / 512; -        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { -            backing_file = options->value.s; -        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) { -            backing_fmt = options->value.s; -        } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) { -            flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0; -        } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) { -            if (options->value.n) { -                cluster_size = options->value.n; -            } -        } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) { -            if (!options->value.s || !strcmp(options->value.s, "off")) { -                prealloc = 0; -            } else if (!strcmp(options->value.s, "metadata")) { -                prealloc = 1; -            } else { -                fprintf(stderr, "Invalid preallocation mode: '%s'\n", -                    options->value.s); -                return -EINVAL; -            } -        } else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) { -            if (!options->value.s || !strcmp(options->value.s, "0.10")) { -                version = 2; -            } else if (!strcmp(options->value.s, "1.1")) { -                version = 3; -            } else { -                fprintf(stderr, "Invalid compatibility level: '%s'\n", -                    options->value.s); -                return -EINVAL; -            } -        } else if (!strcmp(options->name, BLOCK_OPT_LAZY_REFCOUNTS)) { -            flags |= options->value.n ? BLOCK_FLAG_LAZY_REFCOUNTS : 0; -        } -        options++; -    } - -    if (backing_file && prealloc) { -        fprintf(stderr, "Backing file and preallocation cannot be used at " -            "the same time\n"); -        return -EINVAL; -    } - -    if (version < 3 && (flags & BLOCK_FLAG_LAZY_REFCOUNTS)) { -        fprintf(stderr, "Lazy refcounts only supported with compatibility " -                "level 1.1 and above (use compat=1.1 or greater)\n"); -        return -EINVAL; -    } - -    return qcow2_create2(filename, sectors, backing_file, backing_fmt, flags, -                         cluster_size, prealloc, options, version); -} - -static int qcow2_make_empty(BlockDriverState *bs) -{ -#if 0 -    /* XXX: not correct */ -    BDRVQcowState *s = bs->opaque; -    uint32_t l1_length = s->l1_size * sizeof(uint64_t); -    int ret; - -    memset(s->l1_table, 0, l1_length); -    if (bdrv_pwrite(bs->file, s->l1_table_offset, s->l1_table, l1_length) < 0) -        return -1; -    ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length); -    if (ret < 0) -        return ret; - -    l2_cache_reset(bs); -#endif -    return 0; -} - -static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors) -{ -    int ret; -    BDRVQcowState *s = bs->opaque; - -    /* Emulate misaligned zero writes */ -    if (sector_num % s->cluster_sectors || nb_sectors % s->cluster_sectors) { -        return -ENOTSUP; -    } - -    /* Whatever is left can use real zero clusters */ -    qemu_co_mutex_lock(&s->lock); -    ret = qcow2_zero_clusters(bs, sector_num << BDRV_SECTOR_BITS, -        nb_sectors); -    qemu_co_mutex_unlock(&s->lock); - -    return ret; -} - -static coroutine_fn int qcow2_co_discard(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors) -{ -    int ret; -    BDRVQcowState *s = bs->opaque; - -    qemu_co_mutex_lock(&s->lock); -    ret = qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS, -        nb_sectors); -    qemu_co_mutex_unlock(&s->lock); -    return ret; -} - -static int qcow2_truncate(BlockDriverState *bs, int64_t offset) -{ -    BDRVQcowState *s = bs->opaque; -    int64_t new_l1_size; -    int ret; - -    if (offset & 511) { -        error_report("The new size must be a multiple of 512"); -        return -EINVAL; -    } - -    /* cannot proceed if image has snapshots */ -    if (s->nb_snapshots) { -        error_report("Can't resize an image which has snapshots"); -        return -ENOTSUP; -    } - -    /* shrinking is currently not supported */ -    if (offset < bs->total_sectors * 512) { -        error_report("qcow2 doesn't support shrinking images yet"); -        return -ENOTSUP; -    } - -    new_l1_size = size_to_l1(s, offset); -    ret = qcow2_grow_l1_table(bs, new_l1_size, true); -    if (ret < 0) { -        return ret; -    } - -    /* write updated header.size */ -    offset = cpu_to_be64(offset); -    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size), -                           &offset, sizeof(uint64_t)); -    if (ret < 0) { -        return ret; -    } - -    s->l1_vm_state_index = new_l1_size; -    return 0; -} - -/* XXX: put compressed sectors first, then all the cluster aligned -   tables to avoid losing bytes in alignment */ -static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num, -                                  const uint8_t *buf, int nb_sectors) -{ -    BDRVQcowState *s = bs->opaque; -    z_stream strm; -    int ret, out_len; -    uint8_t *out_buf; -    uint64_t cluster_offset; - -    if (nb_sectors == 0) { -        /* align end of file to a sector boundary to ease reading with -           sector based I/Os */ -        cluster_offset = bdrv_getlength(bs->file); -        cluster_offset = (cluster_offset + 511) & ~511; -        bdrv_truncate(bs->file, cluster_offset); -        return 0; -    } - -    if (nb_sectors != s->cluster_sectors) { -        ret = -EINVAL; - -        /* Zero-pad last write if image size is not cluster aligned */ -        if (sector_num + nb_sectors == bs->total_sectors && -            nb_sectors < s->cluster_sectors) { -            uint8_t *pad_buf = qemu_blockalign(bs, s->cluster_size); -            memset(pad_buf, 0, s->cluster_size); -            memcpy(pad_buf, buf, nb_sectors * BDRV_SECTOR_SIZE); -            ret = qcow2_write_compressed(bs, sector_num, -                                         pad_buf, s->cluster_sectors); -            qemu_vfree(pad_buf); -        } -        return ret; -    } - -    out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128); - -    /* best compression, small window, no zlib header */ -    memset(&strm, 0, sizeof(strm)); -    ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, -                       Z_DEFLATED, -12, -                       9, Z_DEFAULT_STRATEGY); -    if (ret != 0) { -        ret = -EINVAL; -        goto fail; -    } - -    strm.avail_in = s->cluster_size; -    strm.next_in = (uint8_t *)buf; -    strm.avail_out = s->cluster_size; -    strm.next_out = out_buf; - -    ret = deflate(&strm, Z_FINISH); -    if (ret != Z_STREAM_END && ret != Z_OK) { -        deflateEnd(&strm); -        ret = -EINVAL; -        goto fail; -    } -    out_len = strm.next_out - out_buf; - -    deflateEnd(&strm); - -    if (ret != Z_STREAM_END || out_len >= s->cluster_size) { -        /* could not compress: write normal cluster */ -        ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors); -        if (ret < 0) { -            goto fail; -        } -    } else { -        cluster_offset = qcow2_alloc_compressed_cluster_offset(bs, -            sector_num << 9, out_len); -        if (!cluster_offset) { -            ret = -EIO; -            goto fail; -        } -        cluster_offset &= s->cluster_offset_mask; -        BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED); -        ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len); -        if (ret < 0) { -            goto fail; -        } -    } - -    ret = 0; -fail: -    g_free(out_buf); -    return ret; -} - -static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    int ret; - -    qemu_co_mutex_lock(&s->lock); -    ret = qcow2_cache_flush(bs, s->l2_table_cache); -    if (ret < 0) { -        qemu_co_mutex_unlock(&s->lock); -        return ret; -    } - -    if (qcow2_need_accurate_refcounts(s)) { -        ret = qcow2_cache_flush(bs, s->refcount_block_cache); -        if (ret < 0) { -            qemu_co_mutex_unlock(&s->lock); -            return ret; -        } -    } -    qemu_co_mutex_unlock(&s->lock); - -    return 0; -} - -static int64_t qcow2_vm_state_offset(BDRVQcowState *s) -{ -	return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits); -} - -static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) -{ -    BDRVQcowState *s = bs->opaque; -    bdi->cluster_size = s->cluster_size; -    bdi->vm_state_offset = qcow2_vm_state_offset(s); -    return 0; -} - -#if 0 -static void dump_refcounts(BlockDriverState *bs) -{ -    BDRVQcowState *s = bs->opaque; -    int64_t nb_clusters, k, k1, size; -    int refcount; - -    size = bdrv_getlength(bs->file); -    nb_clusters = size_to_clusters(s, size); -    for(k = 0; k < nb_clusters;) { -        k1 = k; -        refcount = get_refcount(bs, k); -        k++; -        while (k < nb_clusters && get_refcount(bs, k) == refcount) -            k++; -        printf("%" PRId64 ": refcount=%d nb=%" PRId64 "\n", k, refcount, -               k - k1); -    } -} -#endif - -static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, -                              int64_t pos) -{ -    BDRVQcowState *s = bs->opaque; -    int growable = bs->growable; -    int ret; - -    BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE); -    bs->growable = 1; -    ret = bdrv_pwritev(bs, qcow2_vm_state_offset(s) + pos, qiov); -    bs->growable = growable; - -    return ret; -} - -static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf, -                              int64_t pos, int size) -{ -    BDRVQcowState *s = bs->opaque; -    int growable = bs->growable; -    int ret; - -    BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD); -    bs->growable = 1; -    ret = bdrv_pread(bs, qcow2_vm_state_offset(s) + pos, buf, size); -    bs->growable = growable; - -    return ret; -} - -static QEMUOptionParameter qcow2_create_options[] = { -    { -        .name = BLOCK_OPT_SIZE, -        .type = OPT_SIZE, -        .help = "Virtual disk size" -    }, -    { -        .name = BLOCK_OPT_COMPAT_LEVEL, -        .type = OPT_STRING, -        .help = "Compatibility level (0.10 or 1.1)" -    }, -    { -        .name = BLOCK_OPT_BACKING_FILE, -        .type = OPT_STRING, -        .help = "File name of a base image" -    }, -    { -        .name = BLOCK_OPT_BACKING_FMT, -        .type = OPT_STRING, -        .help = "Image format of the base image" -    }, -    { -        .name = BLOCK_OPT_ENCRYPT, -        .type = OPT_FLAG, -        .help = "Encrypt the image" -    }, -    { -        .name = BLOCK_OPT_CLUSTER_SIZE, -        .type = OPT_SIZE, -        .help = "qcow2 cluster size", -        .value = { .n = DEFAULT_CLUSTER_SIZE }, -    }, -    { -        .name = BLOCK_OPT_PREALLOC, -        .type = OPT_STRING, -        .help = "Preallocation mode (allowed values: off, metadata)" -    }, -    { -        .name = BLOCK_OPT_LAZY_REFCOUNTS, -        .type = OPT_FLAG, -        .help = "Postpone refcount updates", -    }, -    { NULL } -}; - -static BlockDriver bdrv_qcow2 = { -    .format_name        = "qcow2", -    .instance_size      = sizeof(BDRVQcowState), -    .bdrv_probe         = qcow2_probe, -    .bdrv_open          = qcow2_open, -    .bdrv_close         = qcow2_close, -    .bdrv_reopen_prepare  = qcow2_reopen_prepare, -    .bdrv_create        = qcow2_create, -    .bdrv_has_zero_init = bdrv_has_zero_init_1, -    .bdrv_co_is_allocated = qcow2_co_is_allocated, -    .bdrv_set_key       = qcow2_set_key, -    .bdrv_make_empty    = qcow2_make_empty, - -    .bdrv_co_readv          = qcow2_co_readv, -    .bdrv_co_writev         = qcow2_co_writev, -    .bdrv_co_flush_to_os    = qcow2_co_flush_to_os, - -    .bdrv_co_write_zeroes   = qcow2_co_write_zeroes, -    .bdrv_co_discard        = qcow2_co_discard, -    .bdrv_truncate          = qcow2_truncate, -    .bdrv_write_compressed  = qcow2_write_compressed, - -    .bdrv_snapshot_create   = qcow2_snapshot_create, -    .bdrv_snapshot_goto     = qcow2_snapshot_goto, -    .bdrv_snapshot_delete   = qcow2_snapshot_delete, -    .bdrv_snapshot_list     = qcow2_snapshot_list, -    .bdrv_snapshot_load_tmp     = qcow2_snapshot_load_tmp, -    .bdrv_get_info      = qcow2_get_info, - -    .bdrv_save_vmstate    = qcow2_save_vmstate, -    .bdrv_load_vmstate    = qcow2_load_vmstate, - -    .bdrv_change_backing_file   = qcow2_change_backing_file, - -    .bdrv_invalidate_cache      = qcow2_invalidate_cache, - -    .create_options = qcow2_create_options, -    .bdrv_check = qcow2_check, -}; - -static void bdrv_qcow2_init(void) -{ -    bdrv_register(&bdrv_qcow2); -} - -block_init(bdrv_qcow2_init); diff --git a/contrib/qemu/block/qcow2.h b/contrib/qemu/block/qcow2.h deleted file mode 100644 index 3b2d5cda71f..00000000000 --- a/contrib/qemu/block/qcow2.h +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Block driver for the QCOW version 2 format - * - * Copyright (c) 2004-2006 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef BLOCK_QCOW2_H -#define BLOCK_QCOW2_H - -#include "qemu/aes.h" -#include "block/coroutine.h" - -//#define DEBUG_ALLOC -//#define DEBUG_ALLOC2 -//#define DEBUG_EXT - -#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb) - -#define QCOW_CRYPT_NONE 0 -#define QCOW_CRYPT_AES  1 - -#define QCOW_MAX_CRYPT_CLUSTERS 32 - -/* indicate that the refcount of the referenced cluster is exactly one. */ -#define QCOW_OFLAG_COPIED     (1LL << 63) -/* indicate that the cluster is compressed (they never have the copied flag) */ -#define QCOW_OFLAG_COMPRESSED (1LL << 62) -/* The cluster reads as all zeros */ -#define QCOW_OFLAG_ZERO (1LL << 0) - -#define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */ - -#define MIN_CLUSTER_BITS 9 -#define MAX_CLUSTER_BITS 21 - -#define L2_CACHE_SIZE 16 - -/* Must be at least 4 to cover all cases of refcount table growth */ -#define REFCOUNT_CACHE_SIZE 4 - -#define DEFAULT_CLUSTER_SIZE 65536 - - -#define QCOW2_OPT_LAZY_REFCOUNTS "lazy_refcounts" -#define QCOW2_OPT_DISCARD_REQUEST "pass_discard_request" -#define QCOW2_OPT_DISCARD_SNAPSHOT "pass_discard_snapshot" -#define QCOW2_OPT_DISCARD_OTHER "pass_discard_other" - -typedef struct QCowHeader { -    uint32_t magic; -    uint32_t version; -    uint64_t backing_file_offset; -    uint32_t backing_file_size; -    uint32_t cluster_bits; -    uint64_t size; /* in bytes */ -    uint32_t crypt_method; -    uint32_t l1_size; /* XXX: save number of clusters instead ? */ -    uint64_t l1_table_offset; -    uint64_t refcount_table_offset; -    uint32_t refcount_table_clusters; -    uint32_t nb_snapshots; -    uint64_t snapshots_offset; - -    /* The following fields are only valid for version >= 3 */ -    uint64_t incompatible_features; -    uint64_t compatible_features; -    uint64_t autoclear_features; - -    uint32_t refcount_order; -    uint32_t header_length; -} QCowHeader; - -typedef struct QCowSnapshot { -    uint64_t l1_table_offset; -    uint32_t l1_size; -    char *id_str; -    char *name; -    uint64_t disk_size; -    uint64_t vm_state_size; -    uint32_t date_sec; -    uint32_t date_nsec; -    uint64_t vm_clock_nsec; -} QCowSnapshot; - -struct Qcow2Cache; -typedef struct Qcow2Cache Qcow2Cache; - -typedef struct Qcow2UnknownHeaderExtension { -    uint32_t magic; -    uint32_t len; -    QLIST_ENTRY(Qcow2UnknownHeaderExtension) next; -    uint8_t data[]; -} Qcow2UnknownHeaderExtension; - -enum { -    QCOW2_FEAT_TYPE_INCOMPATIBLE    = 0, -    QCOW2_FEAT_TYPE_COMPATIBLE      = 1, -    QCOW2_FEAT_TYPE_AUTOCLEAR       = 2, -}; - -/* Incompatible feature bits */ -enum { -    QCOW2_INCOMPAT_DIRTY_BITNR   = 0, -    QCOW2_INCOMPAT_DIRTY         = 1 << QCOW2_INCOMPAT_DIRTY_BITNR, - -    QCOW2_INCOMPAT_MASK          = QCOW2_INCOMPAT_DIRTY, -}; - -/* Compatible feature bits */ -enum { -    QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR = 0, -    QCOW2_COMPAT_LAZY_REFCOUNTS       = 1 << QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR, - -    QCOW2_COMPAT_FEAT_MASK            = QCOW2_COMPAT_LAZY_REFCOUNTS, -}; - -enum qcow2_discard_type { -    QCOW2_DISCARD_NEVER = 0, -    QCOW2_DISCARD_ALWAYS, -    QCOW2_DISCARD_REQUEST, -    QCOW2_DISCARD_SNAPSHOT, -    QCOW2_DISCARD_OTHER, -    QCOW2_DISCARD_MAX -}; - -typedef struct Qcow2Feature { -    uint8_t type; -    uint8_t bit; -    char    name[46]; -} QEMU_PACKED Qcow2Feature; - -typedef struct Qcow2DiscardRegion { -    BlockDriverState *bs; -    uint64_t offset; -    uint64_t bytes; -    QTAILQ_ENTRY(Qcow2DiscardRegion) next; -} Qcow2DiscardRegion; - -typedef struct BDRVQcowState { -    int cluster_bits; -    int cluster_size; -    int cluster_sectors; -    int l2_bits; -    int l2_size; -    int l1_size; -    int l1_vm_state_index; -    int csize_shift; -    int csize_mask; -    uint64_t cluster_offset_mask; -    uint64_t l1_table_offset; -    uint64_t *l1_table; - -    Qcow2Cache* l2_table_cache; -    Qcow2Cache* refcount_block_cache; - -    uint8_t *cluster_cache; -    uint8_t *cluster_data; -    uint64_t cluster_cache_offset; -    QLIST_HEAD(QCowClusterAlloc, QCowL2Meta) cluster_allocs; - -    uint64_t *refcount_table; -    uint64_t refcount_table_offset; -    uint32_t refcount_table_size; -    int64_t free_cluster_index; -    int64_t free_byte_offset; - -    CoMutex lock; - -    uint32_t crypt_method; /* current crypt method, 0 if no key yet */ -    uint32_t crypt_method_header; -    AES_KEY aes_encrypt_key; -    AES_KEY aes_decrypt_key; -    uint64_t snapshots_offset; -    int snapshots_size; -    int nb_snapshots; -    QCowSnapshot *snapshots; - -    int flags; -    int qcow_version; -    bool use_lazy_refcounts; - -    bool discard_passthrough[QCOW2_DISCARD_MAX]; - -    uint64_t incompatible_features; -    uint64_t compatible_features; -    uint64_t autoclear_features; - -    size_t unknown_header_fields_size; -    void* unknown_header_fields; -    QLIST_HEAD(, Qcow2UnknownHeaderExtension) unknown_header_ext; -    QTAILQ_HEAD (, Qcow2DiscardRegion) discards; -    bool cache_discards; -} BDRVQcowState; - -/* XXX: use std qcow open function ? */ -typedef struct QCowCreateState { -    int cluster_size; -    int cluster_bits; -    uint16_t *refcount_block; -    uint64_t *refcount_table; -    int64_t l1_table_offset; -    int64_t refcount_table_offset; -    int64_t refcount_block_offset; -} QCowCreateState; - -struct QCowAIOCB; - -typedef struct Qcow2COWRegion { -    /** -     * Offset of the COW region in bytes from the start of the first cluster -     * touched by the request. -     */ -    uint64_t    offset; - -    /** Number of sectors to copy */ -    int         nb_sectors; -} Qcow2COWRegion; - -/** - * Describes an in-flight (part of a) write request that writes to clusters - * that are not referenced in their L2 table yet. - */ -typedef struct QCowL2Meta -{ -    /** Guest offset of the first newly allocated cluster */ -    uint64_t offset; - -    /** Host offset of the first newly allocated cluster */ -    uint64_t alloc_offset; - -    /** -     * Number of sectors from the start of the first allocated cluster to -     * the end of the (possibly shortened) request -     */ -    int nb_available; - -    /** Number of newly allocated clusters */ -    int nb_clusters; - -    /** -     * Requests that overlap with this allocation and wait to be restarted -     * when the allocating request has completed. -     */ -    CoQueue dependent_requests; - -    /** -     * The COW Region between the start of the first allocated cluster and the -     * area the guest actually writes to. -     */ -    Qcow2COWRegion cow_start; - -    /** -     * The COW Region between the area the guest actually writes to and the -     * end of the last allocated cluster. -     */ -    Qcow2COWRegion cow_end; - -    /** Pointer to next L2Meta of the same write request */ -    struct QCowL2Meta *next; - -    QLIST_ENTRY(QCowL2Meta) next_in_flight; -} QCowL2Meta; - -enum { -    QCOW2_CLUSTER_UNALLOCATED, -    QCOW2_CLUSTER_NORMAL, -    QCOW2_CLUSTER_COMPRESSED, -    QCOW2_CLUSTER_ZERO -}; - -#define L1E_OFFSET_MASK 0x00ffffffffffff00ULL -#define L2E_OFFSET_MASK 0x00ffffffffffff00ULL -#define L2E_COMPRESSED_OFFSET_SIZE_MASK 0x3fffffffffffffffULL - -#define REFT_OFFSET_MASK 0xffffffffffffff00ULL - -static inline int64_t start_of_cluster(BDRVQcowState *s, int64_t offset) -{ -    return offset & ~(s->cluster_size - 1); -} - -static inline int64_t offset_into_cluster(BDRVQcowState *s, int64_t offset) -{ -    return offset & (s->cluster_size - 1); -} - -static inline int size_to_clusters(BDRVQcowState *s, int64_t size) -{ -    return (size + (s->cluster_size - 1)) >> s->cluster_bits; -} - -static inline int64_t size_to_l1(BDRVQcowState *s, int64_t size) -{ -    int shift = s->cluster_bits + s->l2_bits; -    return (size + (1ULL << shift) - 1) >> shift; -} - -static inline int offset_to_l2_index(BDRVQcowState *s, int64_t offset) -{ -    return (offset >> s->cluster_bits) & (s->l2_size - 1); -} - -static inline int64_t align_offset(int64_t offset, int n) -{ -    offset = (offset + n - 1) & ~(n - 1); -    return offset; -} - -static inline int qcow2_get_cluster_type(uint64_t l2_entry) -{ -    if (l2_entry & QCOW_OFLAG_COMPRESSED) { -        return QCOW2_CLUSTER_COMPRESSED; -    } else if (l2_entry & QCOW_OFLAG_ZERO) { -        return QCOW2_CLUSTER_ZERO; -    } else if (!(l2_entry & L2E_OFFSET_MASK)) { -        return QCOW2_CLUSTER_UNALLOCATED; -    } else { -        return QCOW2_CLUSTER_NORMAL; -    } -} - -/* Check whether refcounts are eager or lazy */ -static inline bool qcow2_need_accurate_refcounts(BDRVQcowState *s) -{ -    return !(s->incompatible_features & QCOW2_INCOMPAT_DIRTY); -} - -static inline uint64_t l2meta_cow_start(QCowL2Meta *m) -{ -    return m->offset + m->cow_start.offset; -} - -static inline uint64_t l2meta_cow_end(QCowL2Meta *m) -{ -    return m->offset + m->cow_end.offset -        + (m->cow_end.nb_sectors << BDRV_SECTOR_BITS); -} - -// FIXME Need qcow2_ prefix to global functions - -/* qcow2.c functions */ -int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, -                  int64_t sector_num, int nb_sectors); - -int qcow2_mark_dirty(BlockDriverState *bs); -int qcow2_update_header(BlockDriverState *bs); - -/* qcow2-refcount.c functions */ -int qcow2_refcount_init(BlockDriverState *bs); -void qcow2_refcount_close(BlockDriverState *bs); - -int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size); -int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, -    int nb_clusters); -int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size); -void qcow2_free_clusters(BlockDriverState *bs, -                          int64_t offset, int64_t size, -                          enum qcow2_discard_type type); -void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t l2_entry, -                             int nb_clusters, enum qcow2_discard_type type); - -int qcow2_update_snapshot_refcount(BlockDriverState *bs, -    int64_t l1_table_offset, int l1_size, int addend); - -int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res, -                          BdrvCheckMode fix); - -void qcow2_process_discards(BlockDriverState *bs, int ret); - -/* qcow2-cluster.c functions */ -int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, -                        bool exact_size); -void qcow2_l2_cache_reset(BlockDriverState *bs); -int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); -void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num, -                     uint8_t *out_buf, const uint8_t *in_buf, -                     int nb_sectors, int enc, -                     const AES_KEY *key); - -int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, -    int *num, uint64_t *cluster_offset); -int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, -    int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m); -uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, -                                         uint64_t offset, -                                         int compressed_size); - -int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m); -int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset, -    int nb_sectors); -int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors); - -/* qcow2-snapshot.c functions */ -int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info); -int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id); -int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id); -int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab); -int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name); - -void qcow2_free_snapshots(BlockDriverState *bs); -int qcow2_read_snapshots(BlockDriverState *bs); - -/* qcow2-cache.c functions */ -Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables); -int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c); - -void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table); -int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c); -int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c, -    Qcow2Cache *dependency); -void qcow2_cache_depends_on_flush(Qcow2Cache *c); - -int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, -    void **table); -int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, -    void **table); -int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table); - -#endif diff --git a/contrib/qemu/block/qed-check.c b/contrib/qemu/block/qed-check.c deleted file mode 100644 index b473dcd61f6..00000000000 --- a/contrib/qemu/block/qed-check.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * QEMU Enhanced Disk Format Consistency Check - * - * Copyright IBM, Corp. 2010 - * - * Authors: - *  Stefan Hajnoczi   <stefanha@linux.vnet.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qed.h" - -typedef struct { -    BDRVQEDState *s; -    BdrvCheckResult *result; -    bool fix;                           /* whether to fix invalid offsets */ - -    uint64_t nclusters; -    uint32_t *used_clusters;            /* referenced cluster bitmap */ - -    QEDRequest request; -} QEDCheck; - -static bool qed_test_bit(uint32_t *bitmap, uint64_t n) { -    return !!(bitmap[n / 32] & (1 << (n % 32))); -} - -static void qed_set_bit(uint32_t *bitmap, uint64_t n) { -    bitmap[n / 32] |= 1 << (n % 32); -} - -/** - * Set bitmap bits for clusters - * - * @check:          Check structure - * @offset:         Starting offset in bytes - * @n:              Number of clusters - */ -static bool qed_set_used_clusters(QEDCheck *check, uint64_t offset, -                                  unsigned int n) -{ -    uint64_t cluster = qed_bytes_to_clusters(check->s, offset); -    unsigned int corruptions = 0; - -    while (n-- != 0) { -        /* Clusters should only be referenced once */ -        if (qed_test_bit(check->used_clusters, cluster)) { -            corruptions++; -        } - -        qed_set_bit(check->used_clusters, cluster); -        cluster++; -    } - -    check->result->corruptions += corruptions; -    return corruptions == 0; -} - -/** - * Check an L2 table - * - * @ret:            Number of invalid cluster offsets - */ -static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table) -{ -    BDRVQEDState *s = check->s; -    unsigned int i, num_invalid = 0; -    uint64_t last_offset = 0; - -    for (i = 0; i < s->table_nelems; i++) { -        uint64_t offset = table->offsets[i]; - -        if (qed_offset_is_unalloc_cluster(offset) || -            qed_offset_is_zero_cluster(offset)) { -            continue; -        } -        check->result->bfi.allocated_clusters++; -        if (last_offset && (last_offset + s->header.cluster_size != offset)) { -            check->result->bfi.fragmented_clusters++; -        } -        last_offset = offset; - -        /* Detect invalid cluster offset */ -        if (!qed_check_cluster_offset(s, offset)) { -            if (check->fix) { -                table->offsets[i] = 0; -                check->result->corruptions_fixed++; -            } else { -                check->result->corruptions++; -            } - -            num_invalid++; -            continue; -        } - -        qed_set_used_clusters(check, offset, 1); -    } - -    return num_invalid; -} - -/** - * Descend tables and check each cluster is referenced once only - */ -static int qed_check_l1_table(QEDCheck *check, QEDTable *table) -{ -    BDRVQEDState *s = check->s; -    unsigned int i, num_invalid_l1 = 0; -    int ret, last_error = 0; - -    /* Mark L1 table clusters used */ -    qed_set_used_clusters(check, s->header.l1_table_offset, -                          s->header.table_size); - -    for (i = 0; i < s->table_nelems; i++) { -        unsigned int num_invalid_l2; -        uint64_t offset = table->offsets[i]; - -        if (qed_offset_is_unalloc_cluster(offset)) { -            continue; -        } - -        /* Detect invalid L2 offset */ -        if (!qed_check_table_offset(s, offset)) { -            /* Clear invalid offset */ -            if (check->fix) { -                table->offsets[i] = 0; -                check->result->corruptions_fixed++; -            } else { -                check->result->corruptions++; -            } - -            num_invalid_l1++; -            continue; -        } - -        if (!qed_set_used_clusters(check, offset, s->header.table_size)) { -            continue; /* skip an invalid table */ -        } - -        ret = qed_read_l2_table_sync(s, &check->request, offset); -        if (ret) { -            check->result->check_errors++; -            last_error = ret; -            continue; -        } - -        num_invalid_l2 = qed_check_l2_table(check, -                                            check->request.l2_table->table); - -        /* Write out fixed L2 table */ -        if (num_invalid_l2 > 0 && check->fix) { -            ret = qed_write_l2_table_sync(s, &check->request, 0, -                                          s->table_nelems, false); -            if (ret) { -                check->result->check_errors++; -                last_error = ret; -                continue; -            } -        } -    } - -    /* Drop reference to final table */ -    qed_unref_l2_cache_entry(check->request.l2_table); -    check->request.l2_table = NULL; - -    /* Write out fixed L1 table */ -    if (num_invalid_l1 > 0 && check->fix) { -        ret = qed_write_l1_table_sync(s, 0, s->table_nelems); -        if (ret) { -            check->result->check_errors++; -            last_error = ret; -        } -    } - -    return last_error; -} - -/** - * Check for unreferenced (leaked) clusters - */ -static void qed_check_for_leaks(QEDCheck *check) -{ -    BDRVQEDState *s = check->s; -    uint64_t i; - -    for (i = s->header.header_size; i < check->nclusters; i++) { -        if (!qed_test_bit(check->used_clusters, i)) { -            check->result->leaks++; -        } -    } -} - -/** - * Mark an image clean once it passes check or has been repaired - */ -static void qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result) -{ -    /* Skip if there were unfixable corruptions or I/O errors */ -    if (result->corruptions > 0 || result->check_errors > 0) { -        return; -    } - -    /* Skip if image is already marked clean */ -    if (!(s->header.features & QED_F_NEED_CHECK)) { -        return; -    } - -    /* Ensure fixes reach storage before clearing check bit */ -    bdrv_flush(s->bs); - -    s->header.features &= ~QED_F_NEED_CHECK; -    qed_write_header_sync(s); -} - -int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix) -{ -    QEDCheck check = { -        .s = s, -        .result = result, -        .nclusters = qed_bytes_to_clusters(s, s->file_size), -        .request = { .l2_table = NULL }, -        .fix = fix, -    }; -    int ret; - -    check.used_clusters = g_malloc0(((check.nclusters + 31) / 32) * -                                       sizeof(check.used_clusters[0])); - -    check.result->bfi.total_clusters = -        (s->header.image_size + s->header.cluster_size - 1) / -            s->header.cluster_size; -    ret = qed_check_l1_table(&check, s->l1_table); -    if (ret == 0) { -        /* Only check for leaks if entire image was scanned successfully */ -        qed_check_for_leaks(&check); - -        if (fix) { -            qed_check_mark_clean(s, result); -        } -    } - -    g_free(check.used_clusters); -    return ret; -} diff --git a/contrib/qemu/block/qed-cluster.c b/contrib/qemu/block/qed-cluster.c deleted file mode 100644 index f64b2af8f7e..00000000000 --- a/contrib/qemu/block/qed-cluster.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * QEMU Enhanced Disk Format Cluster functions - * - * Copyright IBM, Corp. 2010 - * - * Authors: - *  Stefan Hajnoczi   <stefanha@linux.vnet.ibm.com> - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qed.h" - -/** - * Count the number of contiguous data clusters - * - * @s:              QED state - * @table:          L2 table - * @index:          First cluster index - * @n:              Maximum number of clusters - * @offset:         Set to first cluster offset - * - * This function scans tables for contiguous clusters.  A contiguous run of - * clusters may be allocated, unallocated, or zero. - */ -static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s, -                                                  QEDTable *table, -                                                  unsigned int index, -                                                  unsigned int n, -                                                  uint64_t *offset) -{ -    unsigned int end = MIN(index + n, s->table_nelems); -    uint64_t last = table->offsets[index]; -    unsigned int i; - -    *offset = last; - -    for (i = index + 1; i < end; i++) { -        if (qed_offset_is_unalloc_cluster(last)) { -            /* Counting unallocated clusters */ -            if (!qed_offset_is_unalloc_cluster(table->offsets[i])) { -                break; -            } -        } else if (qed_offset_is_zero_cluster(last)) { -            /* Counting zero clusters */ -            if (!qed_offset_is_zero_cluster(table->offsets[i])) { -                break; -            } -        } else { -            /* Counting allocated clusters */ -            if (table->offsets[i] != last + s->header.cluster_size) { -                break; -            } -            last = table->offsets[i]; -        } -    } -    return i - index; -} - -typedef struct { -    BDRVQEDState *s; -    uint64_t pos; -    size_t len; - -    QEDRequest *request; - -    /* User callback */ -    QEDFindClusterFunc *cb; -    void *opaque; -} QEDFindClusterCB; - -static void qed_find_cluster_cb(void *opaque, int ret) -{ -    QEDFindClusterCB *find_cluster_cb = opaque; -    BDRVQEDState *s = find_cluster_cb->s; -    QEDRequest *request = find_cluster_cb->request; -    uint64_t offset = 0; -    size_t len = 0; -    unsigned int index; -    unsigned int n; - -    if (ret) { -        goto out; -    } - -    index = qed_l2_index(s, find_cluster_cb->pos); -    n = qed_bytes_to_clusters(s, -                              qed_offset_into_cluster(s, find_cluster_cb->pos) + -                              find_cluster_cb->len); -    n = qed_count_contiguous_clusters(s, request->l2_table->table, -                                      index, n, &offset); - -    if (qed_offset_is_unalloc_cluster(offset)) { -        ret = QED_CLUSTER_L2; -    } else if (qed_offset_is_zero_cluster(offset)) { -        ret = QED_CLUSTER_ZERO; -    } else if (qed_check_cluster_offset(s, offset)) { -        ret = QED_CLUSTER_FOUND; -    } else { -        ret = -EINVAL; -    } - -    len = MIN(find_cluster_cb->len, n * s->header.cluster_size - -              qed_offset_into_cluster(s, find_cluster_cb->pos)); - -out: -    find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len); -    g_free(find_cluster_cb); -} - -/** - * Find the offset of a data cluster - * - * @s:          QED state - * @request:    L2 cache entry - * @pos:        Byte position in device - * @len:        Number of bytes - * @cb:         Completion function - * @opaque:     User data for completion function - * - * This function translates a position in the block device to an offset in the - * image file.  It invokes the cb completion callback to report back the - * translated offset or unallocated range in the image file. - * - * If the L2 table exists, request->l2_table points to the L2 table cache entry - * and the caller must free the reference when they are finished.  The cache - * entry is exposed in this way to avoid callers having to read the L2 table - * again later during request processing.  If request->l2_table is non-NULL it - * will be unreferenced before taking on the new cache entry. - */ -void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos, -                      size_t len, QEDFindClusterFunc *cb, void *opaque) -{ -    QEDFindClusterCB *find_cluster_cb; -    uint64_t l2_offset; - -    /* Limit length to L2 boundary.  Requests are broken up at the L2 boundary -     * so that a request acts on one L2 table at a time. -     */ -    len = MIN(len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos); - -    l2_offset = s->l1_table->offsets[qed_l1_index(s, pos)]; -    if (qed_offset_is_unalloc_cluster(l2_offset)) { -        cb(opaque, QED_CLUSTER_L1, 0, len); -        return; -    } -    if (!qed_check_table_offset(s, l2_offset)) { -        cb(opaque, -EINVAL, 0, 0); -        return; -    } - -    find_cluster_cb = g_malloc(sizeof(*find_cluster_cb)); -    find_cluster_cb->s = s; -    find_cluster_cb->pos = pos; -    find_cluster_cb->len = len; -    find_cluster_cb->cb = cb; -    find_cluster_cb->opaque = opaque; -    find_cluster_cb->request = request; - -    qed_read_l2_table(s, request, l2_offset, -                      qed_find_cluster_cb, find_cluster_cb); -} diff --git a/contrib/qemu/block/qed-gencb.c b/contrib/qemu/block/qed-gencb.c deleted file mode 100644 index 7d7ac1ffc8e..00000000000 --- a/contrib/qemu/block/qed-gencb.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * QEMU Enhanced Disk Format - * - * Copyright IBM, Corp. 2010 - * - * Authors: - *  Stefan Hajnoczi   <stefanha@linux.vnet.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qed.h" - -void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque) -{ -    GenericCB *gencb = g_malloc(len); -    gencb->cb = cb; -    gencb->opaque = opaque; -    return gencb; -} - -void gencb_complete(void *opaque, int ret) -{ -    GenericCB *gencb = opaque; -    BlockDriverCompletionFunc *cb = gencb->cb; -    void *user_opaque = gencb->opaque; - -    g_free(gencb); -    cb(user_opaque, ret); -} diff --git a/contrib/qemu/block/qed-l2-cache.c b/contrib/qemu/block/qed-l2-cache.c deleted file mode 100644 index e9b2aae44d9..00000000000 --- a/contrib/qemu/block/qed-l2-cache.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * QEMU Enhanced Disk Format L2 Cache - * - * Copyright IBM, Corp. 2010 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -/* - * L2 table cache usage is as follows: - * - * An open image has one L2 table cache that is used to avoid accessing the - * image file for recently referenced L2 tables. - * - * Cluster offset lookup translates the logical offset within the block device - * to a cluster offset within the image file.  This is done by indexing into - * the L1 and L2 tables which store cluster offsets.  It is here where the L2 - * table cache serves up recently referenced L2 tables. - * - * If there is a cache miss, that L2 table is read from the image file and - * committed to the cache.  Subsequent accesses to that L2 table will be served - * from the cache until the table is evicted from the cache. - * - * L2 tables are also committed to the cache when new L2 tables are allocated - * in the image file.  Since the L2 table cache is write-through, the new L2 - * table is first written out to the image file and then committed to the - * cache. - * - * Multiple I/O requests may be using an L2 table cache entry at any given - * time.  That means an entry may be in use across several requests and - * reference counting is needed to free the entry at the correct time.  In - * particular, an entry evicted from the cache will only be freed once all - * references are dropped. - * - * An in-flight I/O request will hold a reference to a L2 table cache entry for - * the period during which it needs to access the L2 table.  This includes - * cluster offset lookup, L2 table allocation, and L2 table update when a new - * data cluster has been allocated. - * - * An interesting case occurs when two requests need to access an L2 table that - * is not in the cache.  Since the operation to read the table from the image - * file takes some time to complete, both requests may see a cache miss and - * start reading the L2 table from the image file.  The first to finish will - * commit its L2 table into the cache.  When the second tries to commit its - * table will be deleted in favor of the existing cache entry. - */ - -#include "trace.h" -#include "qed.h" - -/* Each L2 holds 2GB so this let's us fully cache a 100GB disk */ -#define MAX_L2_CACHE_SIZE 50 - -/** - * Initialize the L2 cache - */ -void qed_init_l2_cache(L2TableCache *l2_cache) -{ -    QTAILQ_INIT(&l2_cache->entries); -    l2_cache->n_entries = 0; -} - -/** - * Free the L2 cache - */ -void qed_free_l2_cache(L2TableCache *l2_cache) -{ -    CachedL2Table *entry, *next_entry; - -    QTAILQ_FOREACH_SAFE(entry, &l2_cache->entries, node, next_entry) { -        qemu_vfree(entry->table); -        g_free(entry); -    } -} - -/** - * Allocate an uninitialized entry from the cache - * - * The returned entry has a reference count of 1 and is owned by the caller. - * The caller must allocate the actual table field for this entry and it must - * be freeable using qemu_vfree(). - */ -CachedL2Table *qed_alloc_l2_cache_entry(L2TableCache *l2_cache) -{ -    CachedL2Table *entry; - -    entry = g_malloc0(sizeof(*entry)); -    entry->ref++; - -    trace_qed_alloc_l2_cache_entry(l2_cache, entry); - -    return entry; -} - -/** - * Decrease an entry's reference count and free if necessary when the reference - * count drops to zero. - */ -void qed_unref_l2_cache_entry(CachedL2Table *entry) -{ -    if (!entry) { -        return; -    } - -    entry->ref--; -    trace_qed_unref_l2_cache_entry(entry, entry->ref); -    if (entry->ref == 0) { -        qemu_vfree(entry->table); -        g_free(entry); -    } -} - -/** - * Find an entry in the L2 cache.  This may return NULL and it's up to the - * caller to satisfy the cache miss. - * - * For a cached entry, this function increases the reference count and returns - * the entry. - */ -CachedL2Table *qed_find_l2_cache_entry(L2TableCache *l2_cache, uint64_t offset) -{ -    CachedL2Table *entry; - -    QTAILQ_FOREACH(entry, &l2_cache->entries, node) { -        if (entry->offset == offset) { -            trace_qed_find_l2_cache_entry(l2_cache, entry, offset, entry->ref); -            entry->ref++; -            return entry; -        } -    } -    return NULL; -} - -/** - * Commit an L2 cache entry into the cache.  This is meant to be used as part of - * the process to satisfy a cache miss.  A caller would allocate an entry which - * is not actually in the L2 cache and then once the entry was valid and - * present on disk, the entry can be committed into the cache. - * - * Since the cache is write-through, it's important that this function is not - * called until the entry is present on disk and the L1 has been updated to - * point to the entry. - * - * N.B. This function steals a reference to the l2_table from the caller so the - * caller must obtain a new reference by issuing a call to - * qed_find_l2_cache_entry(). - */ -void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table) -{ -    CachedL2Table *entry; - -    entry = qed_find_l2_cache_entry(l2_cache, l2_table->offset); -    if (entry) { -        qed_unref_l2_cache_entry(entry); -        qed_unref_l2_cache_entry(l2_table); -        return; -    } - -    /* Evict an unused cache entry so we have space.  If all entries are in use -     * we can grow the cache temporarily and we try to shrink back down later. -     */ -    if (l2_cache->n_entries >= MAX_L2_CACHE_SIZE) { -        CachedL2Table *next; -        QTAILQ_FOREACH_SAFE(entry, &l2_cache->entries, node, next) { -            if (entry->ref > 1) { -                continue; -            } - -            QTAILQ_REMOVE(&l2_cache->entries, entry, node); -            l2_cache->n_entries--; -            qed_unref_l2_cache_entry(entry); - -            /* Stop evicting when we've shrunk back to max size */ -            if (l2_cache->n_entries < MAX_L2_CACHE_SIZE) { -                break; -            } -        } -    } - -    l2_cache->n_entries++; -    QTAILQ_INSERT_TAIL(&l2_cache->entries, l2_table, node); -} diff --git a/contrib/qemu/block/qed-table.c b/contrib/qemu/block/qed-table.c deleted file mode 100644 index 76d2dcccf81..00000000000 --- a/contrib/qemu/block/qed-table.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * QEMU Enhanced Disk Format Table I/O - * - * Copyright IBM, Corp. 2010 - * - * Authors: - *  Stefan Hajnoczi   <stefanha@linux.vnet.ibm.com> - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "trace.h" -#include "qemu/sockets.h" /* for EINPROGRESS on Windows */ -#include "qed.h" - -typedef struct { -    GenericCB gencb; -    BDRVQEDState *s; -    QEDTable *table; - -    struct iovec iov; -    QEMUIOVector qiov; -} QEDReadTableCB; - -static void qed_read_table_cb(void *opaque, int ret) -{ -    QEDReadTableCB *read_table_cb = opaque; -    QEDTable *table = read_table_cb->table; -    int noffsets = read_table_cb->qiov.size / sizeof(uint64_t); -    int i; - -    /* Handle I/O error */ -    if (ret) { -        goto out; -    } - -    /* Byteswap offsets */ -    for (i = 0; i < noffsets; i++) { -        table->offsets[i] = le64_to_cpu(table->offsets[i]); -    } - -out: -    /* Completion */ -    trace_qed_read_table_cb(read_table_cb->s, read_table_cb->table, ret); -    gencb_complete(&read_table_cb->gencb, ret); -} - -static void qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table, -                           BlockDriverCompletionFunc *cb, void *opaque) -{ -    QEDReadTableCB *read_table_cb = gencb_alloc(sizeof(*read_table_cb), -                                                cb, opaque); -    QEMUIOVector *qiov = &read_table_cb->qiov; - -    trace_qed_read_table(s, offset, table); - -    read_table_cb->s = s; -    read_table_cb->table = table; -    read_table_cb->iov.iov_base = table->offsets, -    read_table_cb->iov.iov_len = s->header.cluster_size * s->header.table_size, - -    qemu_iovec_init_external(qiov, &read_table_cb->iov, 1); -    bdrv_aio_readv(s->bs->file, offset / BDRV_SECTOR_SIZE, qiov, -                   qiov->size / BDRV_SECTOR_SIZE, -                   qed_read_table_cb, read_table_cb); -} - -typedef struct { -    GenericCB gencb; -    BDRVQEDState *s; -    QEDTable *orig_table; -    QEDTable *table; -    bool flush;             /* flush after write? */ - -    struct iovec iov; -    QEMUIOVector qiov; -} QEDWriteTableCB; - -static void qed_write_table_cb(void *opaque, int ret) -{ -    QEDWriteTableCB *write_table_cb = opaque; - -    trace_qed_write_table_cb(write_table_cb->s, -                             write_table_cb->orig_table, -                             write_table_cb->flush, -                             ret); - -    if (ret) { -        goto out; -    } - -    if (write_table_cb->flush) { -        /* We still need to flush first */ -        write_table_cb->flush = false; -        bdrv_aio_flush(write_table_cb->s->bs, qed_write_table_cb, -                       write_table_cb); -        return; -    } - -out: -    qemu_vfree(write_table_cb->table); -    gencb_complete(&write_table_cb->gencb, ret); -} - -/** - * Write out an updated part or all of a table - * - * @s:          QED state - * @offset:     Offset of table in image file, in bytes - * @table:      Table - * @index:      Index of first element - * @n:          Number of elements - * @flush:      Whether or not to sync to disk - * @cb:         Completion function - * @opaque:     Argument for completion function - */ -static void qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table, -                            unsigned int index, unsigned int n, bool flush, -                            BlockDriverCompletionFunc *cb, void *opaque) -{ -    QEDWriteTableCB *write_table_cb; -    unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1; -    unsigned int start, end, i; -    size_t len_bytes; - -    trace_qed_write_table(s, offset, table, index, n); - -    /* Calculate indices of the first and one after last elements */ -    start = index & ~sector_mask; -    end = (index + n + sector_mask) & ~sector_mask; - -    len_bytes = (end - start) * sizeof(uint64_t); - -    write_table_cb = gencb_alloc(sizeof(*write_table_cb), cb, opaque); -    write_table_cb->s = s; -    write_table_cb->orig_table = table; -    write_table_cb->flush = flush; -    write_table_cb->table = qemu_blockalign(s->bs, len_bytes); -    write_table_cb->iov.iov_base = write_table_cb->table->offsets; -    write_table_cb->iov.iov_len = len_bytes; -    qemu_iovec_init_external(&write_table_cb->qiov, &write_table_cb->iov, 1); - -    /* Byteswap table */ -    for (i = start; i < end; i++) { -        uint64_t le_offset = cpu_to_le64(table->offsets[i]); -        write_table_cb->table->offsets[i - start] = le_offset; -    } - -    /* Adjust for offset into table */ -    offset += start * sizeof(uint64_t); - -    bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE, -                    &write_table_cb->qiov, -                    write_table_cb->qiov.size / BDRV_SECTOR_SIZE, -                    qed_write_table_cb, write_table_cb); -} - -/** - * Propagate return value from async callback - */ -static void qed_sync_cb(void *opaque, int ret) -{ -    *(int *)opaque = ret; -} - -int qed_read_l1_table_sync(BDRVQEDState *s) -{ -    int ret = -EINPROGRESS; - -    qed_read_table(s, s->header.l1_table_offset, -                   s->l1_table, qed_sync_cb, &ret); -    while (ret == -EINPROGRESS) { -        qemu_aio_wait(); -    } - -    return ret; -} - -void qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n, -                        BlockDriverCompletionFunc *cb, void *opaque) -{ -    BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE); -    qed_write_table(s, s->header.l1_table_offset, -                    s->l1_table, index, n, false, cb, opaque); -} - -int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, -                            unsigned int n) -{ -    int ret = -EINPROGRESS; - -    qed_write_l1_table(s, index, n, qed_sync_cb, &ret); -    while (ret == -EINPROGRESS) { -        qemu_aio_wait(); -    } - -    return ret; -} - -typedef struct { -    GenericCB gencb; -    BDRVQEDState *s; -    uint64_t l2_offset; -    QEDRequest *request; -} QEDReadL2TableCB; - -static void qed_read_l2_table_cb(void *opaque, int ret) -{ -    QEDReadL2TableCB *read_l2_table_cb = opaque; -    QEDRequest *request = read_l2_table_cb->request; -    BDRVQEDState *s = read_l2_table_cb->s; -    CachedL2Table *l2_table = request->l2_table; -    uint64_t l2_offset = read_l2_table_cb->l2_offset; - -    if (ret) { -        /* can't trust loaded L2 table anymore */ -        qed_unref_l2_cache_entry(l2_table); -        request->l2_table = NULL; -    } else { -        l2_table->offset = l2_offset; - -        qed_commit_l2_cache_entry(&s->l2_cache, l2_table); - -        /* This is guaranteed to succeed because we just committed the entry -         * to the cache. -         */ -        request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset); -        assert(request->l2_table != NULL); -    } - -    gencb_complete(&read_l2_table_cb->gencb, ret); -} - -void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset, -                       BlockDriverCompletionFunc *cb, void *opaque) -{ -    QEDReadL2TableCB *read_l2_table_cb; - -    qed_unref_l2_cache_entry(request->l2_table); - -    /* Check for cached L2 entry */ -    request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, offset); -    if (request->l2_table) { -        cb(opaque, 0); -        return; -    } - -    request->l2_table = qed_alloc_l2_cache_entry(&s->l2_cache); -    request->l2_table->table = qed_alloc_table(s); - -    read_l2_table_cb = gencb_alloc(sizeof(*read_l2_table_cb), cb, opaque); -    read_l2_table_cb->s = s; -    read_l2_table_cb->l2_offset = offset; -    read_l2_table_cb->request = request; - -    BLKDBG_EVENT(s->bs->file, BLKDBG_L2_LOAD); -    qed_read_table(s, offset, request->l2_table->table, -                   qed_read_l2_table_cb, read_l2_table_cb); -} - -int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset) -{ -    int ret = -EINPROGRESS; - -    qed_read_l2_table(s, request, offset, qed_sync_cb, &ret); -    while (ret == -EINPROGRESS) { -        qemu_aio_wait(); -    } - -    return ret; -} - -void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, -                        unsigned int index, unsigned int n, bool flush, -                        BlockDriverCompletionFunc *cb, void *opaque) -{ -    BLKDBG_EVENT(s->bs->file, BLKDBG_L2_UPDATE); -    qed_write_table(s, request->l2_table->offset, -                    request->l2_table->table, index, n, flush, cb, opaque); -} - -int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request, -                            unsigned int index, unsigned int n, bool flush) -{ -    int ret = -EINPROGRESS; - -    qed_write_l2_table(s, request, index, n, flush, qed_sync_cb, &ret); -    while (ret == -EINPROGRESS) { -        qemu_aio_wait(); -    } - -    return ret; -} diff --git a/contrib/qemu/block/qed.c b/contrib/qemu/block/qed.c deleted file mode 100644 index f767b0528ce..00000000000 --- a/contrib/qemu/block/qed.c +++ /dev/null @@ -1,1596 +0,0 @@ -/* - * QEMU Enhanced Disk Format - * - * Copyright IBM, Corp. 2010 - * - * Authors: - *  Stefan Hajnoczi   <stefanha@linux.vnet.ibm.com> - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qemu/timer.h" -#include "trace.h" -#include "qed.h" -#include "qapi/qmp/qerror.h" -#include "migration/migration.h" - -static void qed_aio_cancel(BlockDriverAIOCB *blockacb) -{ -    QEDAIOCB *acb = (QEDAIOCB *)blockacb; -    bool finished = false; - -    /* Wait for the request to finish */ -    acb->finished = &finished; -    while (!finished) { -        qemu_aio_wait(); -    } -} - -static const AIOCBInfo qed_aiocb_info = { -    .aiocb_size         = sizeof(QEDAIOCB), -    .cancel             = qed_aio_cancel, -}; - -static int bdrv_qed_probe(const uint8_t *buf, int buf_size, -                          const char *filename) -{ -    const QEDHeader *header = (const QEDHeader *)buf; - -    if (buf_size < sizeof(*header)) { -        return 0; -    } -    if (le32_to_cpu(header->magic) != QED_MAGIC) { -        return 0; -    } -    return 100; -} - -/** - * Check whether an image format is raw - * - * @fmt:    Backing file format, may be NULL - */ -static bool qed_fmt_is_raw(const char *fmt) -{ -    return fmt && strcmp(fmt, "raw") == 0; -} - -static void qed_header_le_to_cpu(const QEDHeader *le, QEDHeader *cpu) -{ -    cpu->magic = le32_to_cpu(le->magic); -    cpu->cluster_size = le32_to_cpu(le->cluster_size); -    cpu->table_size = le32_to_cpu(le->table_size); -    cpu->header_size = le32_to_cpu(le->header_size); -    cpu->features = le64_to_cpu(le->features); -    cpu->compat_features = le64_to_cpu(le->compat_features); -    cpu->autoclear_features = le64_to_cpu(le->autoclear_features); -    cpu->l1_table_offset = le64_to_cpu(le->l1_table_offset); -    cpu->image_size = le64_to_cpu(le->image_size); -    cpu->backing_filename_offset = le32_to_cpu(le->backing_filename_offset); -    cpu->backing_filename_size = le32_to_cpu(le->backing_filename_size); -} - -static void qed_header_cpu_to_le(const QEDHeader *cpu, QEDHeader *le) -{ -    le->magic = cpu_to_le32(cpu->magic); -    le->cluster_size = cpu_to_le32(cpu->cluster_size); -    le->table_size = cpu_to_le32(cpu->table_size); -    le->header_size = cpu_to_le32(cpu->header_size); -    le->features = cpu_to_le64(cpu->features); -    le->compat_features = cpu_to_le64(cpu->compat_features); -    le->autoclear_features = cpu_to_le64(cpu->autoclear_features); -    le->l1_table_offset = cpu_to_le64(cpu->l1_table_offset); -    le->image_size = cpu_to_le64(cpu->image_size); -    le->backing_filename_offset = cpu_to_le32(cpu->backing_filename_offset); -    le->backing_filename_size = cpu_to_le32(cpu->backing_filename_size); -} - -int qed_write_header_sync(BDRVQEDState *s) -{ -    QEDHeader le; -    int ret; - -    qed_header_cpu_to_le(&s->header, &le); -    ret = bdrv_pwrite(s->bs->file, 0, &le, sizeof(le)); -    if (ret != sizeof(le)) { -        return ret; -    } -    return 0; -} - -typedef struct { -    GenericCB gencb; -    BDRVQEDState *s; -    struct iovec iov; -    QEMUIOVector qiov; -    int nsectors; -    uint8_t *buf; -} QEDWriteHeaderCB; - -static void qed_write_header_cb(void *opaque, int ret) -{ -    QEDWriteHeaderCB *write_header_cb = opaque; - -    qemu_vfree(write_header_cb->buf); -    gencb_complete(write_header_cb, ret); -} - -static void qed_write_header_read_cb(void *opaque, int ret) -{ -    QEDWriteHeaderCB *write_header_cb = opaque; -    BDRVQEDState *s = write_header_cb->s; - -    if (ret) { -        qed_write_header_cb(write_header_cb, ret); -        return; -    } - -    /* Update header */ -    qed_header_cpu_to_le(&s->header, (QEDHeader *)write_header_cb->buf); - -    bdrv_aio_writev(s->bs->file, 0, &write_header_cb->qiov, -                    write_header_cb->nsectors, qed_write_header_cb, -                    write_header_cb); -} - -/** - * Update header in-place (does not rewrite backing filename or other strings) - * - * This function only updates known header fields in-place and does not affect - * extra data after the QED header. - */ -static void qed_write_header(BDRVQEDState *s, BlockDriverCompletionFunc cb, -                             void *opaque) -{ -    /* We must write full sectors for O_DIRECT but cannot necessarily generate -     * the data following the header if an unrecognized compat feature is -     * active.  Therefore, first read the sectors containing the header, update -     * them, and write back. -     */ - -    int nsectors = (sizeof(QEDHeader) + BDRV_SECTOR_SIZE - 1) / -                   BDRV_SECTOR_SIZE; -    size_t len = nsectors * BDRV_SECTOR_SIZE; -    QEDWriteHeaderCB *write_header_cb = gencb_alloc(sizeof(*write_header_cb), -                                                    cb, opaque); - -    write_header_cb->s = s; -    write_header_cb->nsectors = nsectors; -    write_header_cb->buf = qemu_blockalign(s->bs, len); -    write_header_cb->iov.iov_base = write_header_cb->buf; -    write_header_cb->iov.iov_len = len; -    qemu_iovec_init_external(&write_header_cb->qiov, &write_header_cb->iov, 1); - -    bdrv_aio_readv(s->bs->file, 0, &write_header_cb->qiov, nsectors, -                   qed_write_header_read_cb, write_header_cb); -} - -static uint64_t qed_max_image_size(uint32_t cluster_size, uint32_t table_size) -{ -    uint64_t table_entries; -    uint64_t l2_size; - -    table_entries = (table_size * cluster_size) / sizeof(uint64_t); -    l2_size = table_entries * cluster_size; - -    return l2_size * table_entries; -} - -static bool qed_is_cluster_size_valid(uint32_t cluster_size) -{ -    if (cluster_size < QED_MIN_CLUSTER_SIZE || -        cluster_size > QED_MAX_CLUSTER_SIZE) { -        return false; -    } -    if (cluster_size & (cluster_size - 1)) { -        return false; /* not power of 2 */ -    } -    return true; -} - -static bool qed_is_table_size_valid(uint32_t table_size) -{ -    if (table_size < QED_MIN_TABLE_SIZE || -        table_size > QED_MAX_TABLE_SIZE) { -        return false; -    } -    if (table_size & (table_size - 1)) { -        return false; /* not power of 2 */ -    } -    return true; -} - -static bool qed_is_image_size_valid(uint64_t image_size, uint32_t cluster_size, -                                    uint32_t table_size) -{ -    if (image_size % BDRV_SECTOR_SIZE != 0) { -        return false; /* not multiple of sector size */ -    } -    if (image_size > qed_max_image_size(cluster_size, table_size)) { -        return false; /* image is too large */ -    } -    return true; -} - -/** - * Read a string of known length from the image file - * - * @file:       Image file - * @offset:     File offset to start of string, in bytes - * @n:          String length in bytes - * @buf:        Destination buffer - * @buflen:     Destination buffer length in bytes - * @ret:        0 on success, -errno on failure - * - * The string is NUL-terminated. - */ -static int qed_read_string(BlockDriverState *file, uint64_t offset, size_t n, -                           char *buf, size_t buflen) -{ -    int ret; -    if (n >= buflen) { -        return -EINVAL; -    } -    ret = bdrv_pread(file, offset, buf, n); -    if (ret < 0) { -        return ret; -    } -    buf[n] = '\0'; -    return 0; -} - -/** - * Allocate new clusters - * - * @s:          QED state - * @n:          Number of contiguous clusters to allocate - * @ret:        Offset of first allocated cluster - * - * This function only produces the offset where the new clusters should be - * written.  It updates BDRVQEDState but does not make any changes to the image - * file. - */ -static uint64_t qed_alloc_clusters(BDRVQEDState *s, unsigned int n) -{ -    uint64_t offset = s->file_size; -    s->file_size += n * s->header.cluster_size; -    return offset; -} - -QEDTable *qed_alloc_table(BDRVQEDState *s) -{ -    /* Honor O_DIRECT memory alignment requirements */ -    return qemu_blockalign(s->bs, -                           s->header.cluster_size * s->header.table_size); -} - -/** - * Allocate a new zeroed L2 table - */ -static CachedL2Table *qed_new_l2_table(BDRVQEDState *s) -{ -    CachedL2Table *l2_table = qed_alloc_l2_cache_entry(&s->l2_cache); - -    l2_table->table = qed_alloc_table(s); -    l2_table->offset = qed_alloc_clusters(s, s->header.table_size); - -    memset(l2_table->table->offsets, 0, -           s->header.cluster_size * s->header.table_size); -    return l2_table; -} - -static void qed_aio_next_io(void *opaque, int ret); - -static void qed_plug_allocating_write_reqs(BDRVQEDState *s) -{ -    assert(!s->allocating_write_reqs_plugged); - -    s->allocating_write_reqs_plugged = true; -} - -static void qed_unplug_allocating_write_reqs(BDRVQEDState *s) -{ -    QEDAIOCB *acb; - -    assert(s->allocating_write_reqs_plugged); - -    s->allocating_write_reqs_plugged = false; - -    acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs); -    if (acb) { -        qed_aio_next_io(acb, 0); -    } -} - -static void qed_finish_clear_need_check(void *opaque, int ret) -{ -    /* Do nothing */ -} - -static void qed_flush_after_clear_need_check(void *opaque, int ret) -{ -    BDRVQEDState *s = opaque; - -    bdrv_aio_flush(s->bs, qed_finish_clear_need_check, s); - -    /* No need to wait until flush completes */ -    qed_unplug_allocating_write_reqs(s); -} - -static void qed_clear_need_check(void *opaque, int ret) -{ -    BDRVQEDState *s = opaque; - -    if (ret) { -        qed_unplug_allocating_write_reqs(s); -        return; -    } - -    s->header.features &= ~QED_F_NEED_CHECK; -    qed_write_header(s, qed_flush_after_clear_need_check, s); -} - -static void qed_need_check_timer_cb(void *opaque) -{ -    BDRVQEDState *s = opaque; - -    /* The timer should only fire when allocating writes have drained */ -    assert(!QSIMPLEQ_FIRST(&s->allocating_write_reqs)); - -    trace_qed_need_check_timer_cb(s); - -    qed_plug_allocating_write_reqs(s); - -    /* Ensure writes are on disk before clearing flag */ -    bdrv_aio_flush(s->bs, qed_clear_need_check, s); -} - -static void qed_start_need_check_timer(BDRVQEDState *s) -{ -    trace_qed_start_need_check_timer(s); - -    /* Use vm_clock so we don't alter the image file while suspended for -     * migration. -     */ -    qemu_mod_timer(s->need_check_timer, qemu_get_clock_ns(vm_clock) + -                   get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT); -} - -/* It's okay to call this multiple times or when no timer is started */ -static void qed_cancel_need_check_timer(BDRVQEDState *s) -{ -    trace_qed_cancel_need_check_timer(s); -    qemu_del_timer(s->need_check_timer); -} - -static void bdrv_qed_rebind(BlockDriverState *bs) -{ -    BDRVQEDState *s = bs->opaque; -    s->bs = bs; -} - -static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags) -{ -    BDRVQEDState *s = bs->opaque; -    QEDHeader le_header; -    int64_t file_size; -    int ret; - -    s->bs = bs; -    QSIMPLEQ_INIT(&s->allocating_write_reqs); - -    ret = bdrv_pread(bs->file, 0, &le_header, sizeof(le_header)); -    if (ret < 0) { -        return ret; -    } -    qed_header_le_to_cpu(&le_header, &s->header); - -    if (s->header.magic != QED_MAGIC) { -        return -EMEDIUMTYPE; -    } -    if (s->header.features & ~QED_FEATURE_MASK) { -        /* image uses unsupported feature bits */ -        char buf[64]; -        snprintf(buf, sizeof(buf), "%" PRIx64, -            s->header.features & ~QED_FEATURE_MASK); -        qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, -            bs->device_name, "QED", buf); -        return -ENOTSUP; -    } -    if (!qed_is_cluster_size_valid(s->header.cluster_size)) { -        return -EINVAL; -    } - -    /* Round down file size to the last cluster */ -    file_size = bdrv_getlength(bs->file); -    if (file_size < 0) { -        return file_size; -    } -    s->file_size = qed_start_of_cluster(s, file_size); - -    if (!qed_is_table_size_valid(s->header.table_size)) { -        return -EINVAL; -    } -    if (!qed_is_image_size_valid(s->header.image_size, -                                 s->header.cluster_size, -                                 s->header.table_size)) { -        return -EINVAL; -    } -    if (!qed_check_table_offset(s, s->header.l1_table_offset)) { -        return -EINVAL; -    } - -    s->table_nelems = (s->header.cluster_size * s->header.table_size) / -                      sizeof(uint64_t); -    s->l2_shift = ffs(s->header.cluster_size) - 1; -    s->l2_mask = s->table_nelems - 1; -    s->l1_shift = s->l2_shift + ffs(s->table_nelems) - 1; - -    if ((s->header.features & QED_F_BACKING_FILE)) { -        if ((uint64_t)s->header.backing_filename_offset + -            s->header.backing_filename_size > -            s->header.cluster_size * s->header.header_size) { -            return -EINVAL; -        } - -        ret = qed_read_string(bs->file, s->header.backing_filename_offset, -                              s->header.backing_filename_size, bs->backing_file, -                              sizeof(bs->backing_file)); -        if (ret < 0) { -            return ret; -        } - -        if (s->header.features & QED_F_BACKING_FORMAT_NO_PROBE) { -            pstrcpy(bs->backing_format, sizeof(bs->backing_format), "raw"); -        } -    } - -    /* Reset unknown autoclear feature bits.  This is a backwards -     * compatibility mechanism that allows images to be opened by older -     * programs, which "knock out" unknown feature bits.  When an image is -     * opened by a newer program again it can detect that the autoclear -     * feature is no longer valid. -     */ -    if ((s->header.autoclear_features & ~QED_AUTOCLEAR_FEATURE_MASK) != 0 && -        !bdrv_is_read_only(bs->file) && !(flags & BDRV_O_INCOMING)) { -        s->header.autoclear_features &= QED_AUTOCLEAR_FEATURE_MASK; - -        ret = qed_write_header_sync(s); -        if (ret) { -            return ret; -        } - -        /* From here on only known autoclear feature bits are valid */ -        bdrv_flush(bs->file); -    } - -    s->l1_table = qed_alloc_table(s); -    qed_init_l2_cache(&s->l2_cache); - -    ret = qed_read_l1_table_sync(s); -    if (ret) { -        goto out; -    } - -    /* If image was not closed cleanly, check consistency */ -    if (!(flags & BDRV_O_CHECK) && (s->header.features & QED_F_NEED_CHECK)) { -        /* Read-only images cannot be fixed.  There is no risk of corruption -         * since write operations are not possible.  Therefore, allow -         * potentially inconsistent images to be opened read-only.  This can -         * aid data recovery from an otherwise inconsistent image. -         */ -        if (!bdrv_is_read_only(bs->file) && -            !(flags & BDRV_O_INCOMING)) { -            BdrvCheckResult result = {0}; - -            ret = qed_check(s, &result, true); -            if (ret) { -                goto out; -            } -        } -    } - -    s->need_check_timer = qemu_new_timer_ns(vm_clock, -                                            qed_need_check_timer_cb, s); - -out: -    if (ret) { -        qed_free_l2_cache(&s->l2_cache); -        qemu_vfree(s->l1_table); -    } -    return ret; -} - -/* We have nothing to do for QED reopen, stubs just return - * success */ -static int bdrv_qed_reopen_prepare(BDRVReopenState *state, -                                   BlockReopenQueue *queue, Error **errp) -{ -    return 0; -} - -static void bdrv_qed_close(BlockDriverState *bs) -{ -    BDRVQEDState *s = bs->opaque; - -    qed_cancel_need_check_timer(s); -    qemu_free_timer(s->need_check_timer); - -    /* Ensure writes reach stable storage */ -    bdrv_flush(bs->file); - -    /* Clean shutdown, no check required on next open */ -    if (s->header.features & QED_F_NEED_CHECK) { -        s->header.features &= ~QED_F_NEED_CHECK; -        qed_write_header_sync(s); -    } - -    qed_free_l2_cache(&s->l2_cache); -    qemu_vfree(s->l1_table); -} - -static int qed_create(const char *filename, uint32_t cluster_size, -                      uint64_t image_size, uint32_t table_size, -                      const char *backing_file, const char *backing_fmt) -{ -    QEDHeader header = { -        .magic = QED_MAGIC, -        .cluster_size = cluster_size, -        .table_size = table_size, -        .header_size = 1, -        .features = 0, -        .compat_features = 0, -        .l1_table_offset = cluster_size, -        .image_size = image_size, -    }; -    QEDHeader le_header; -    uint8_t *l1_table = NULL; -    size_t l1_size = header.cluster_size * header.table_size; -    int ret = 0; -    BlockDriverState *bs = NULL; - -    ret = bdrv_create_file(filename, NULL); -    if (ret < 0) { -        return ret; -    } - -    ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB); -    if (ret < 0) { -        return ret; -    } - -    /* File must start empty and grow, check truncate is supported */ -    ret = bdrv_truncate(bs, 0); -    if (ret < 0) { -        goto out; -    } - -    if (backing_file) { -        header.features |= QED_F_BACKING_FILE; -        header.backing_filename_offset = sizeof(le_header); -        header.backing_filename_size = strlen(backing_file); - -        if (qed_fmt_is_raw(backing_fmt)) { -            header.features |= QED_F_BACKING_FORMAT_NO_PROBE; -        } -    } - -    qed_header_cpu_to_le(&header, &le_header); -    ret = bdrv_pwrite(bs, 0, &le_header, sizeof(le_header)); -    if (ret < 0) { -        goto out; -    } -    ret = bdrv_pwrite(bs, sizeof(le_header), backing_file, -                      header.backing_filename_size); -    if (ret < 0) { -        goto out; -    } - -    l1_table = g_malloc0(l1_size); -    ret = bdrv_pwrite(bs, header.l1_table_offset, l1_table, l1_size); -    if (ret < 0) { -        goto out; -    } - -    ret = 0; /* success */ -out: -    g_free(l1_table); -    bdrv_delete(bs); -    return ret; -} - -static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options) -{ -    uint64_t image_size = 0; -    uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE; -    uint32_t table_size = QED_DEFAULT_TABLE_SIZE; -    const char *backing_file = NULL; -    const char *backing_fmt = NULL; - -    while (options && options->name) { -        if (!strcmp(options->name, BLOCK_OPT_SIZE)) { -            image_size = options->value.n; -        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { -            backing_file = options->value.s; -        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) { -            backing_fmt = options->value.s; -        } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) { -            if (options->value.n) { -                cluster_size = options->value.n; -            } -        } else if (!strcmp(options->name, BLOCK_OPT_TABLE_SIZE)) { -            if (options->value.n) { -                table_size = options->value.n; -            } -        } -        options++; -    } - -    if (!qed_is_cluster_size_valid(cluster_size)) { -        fprintf(stderr, "QED cluster size must be within range [%u, %u] and power of 2\n", -                QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE); -        return -EINVAL; -    } -    if (!qed_is_table_size_valid(table_size)) { -        fprintf(stderr, "QED table size must be within range [%u, %u] and power of 2\n", -                QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE); -        return -EINVAL; -    } -    if (!qed_is_image_size_valid(image_size, cluster_size, table_size)) { -        fprintf(stderr, "QED image size must be a non-zero multiple of " -                        "cluster size and less than %" PRIu64 " bytes\n", -                qed_max_image_size(cluster_size, table_size)); -        return -EINVAL; -    } - -    return qed_create(filename, cluster_size, image_size, table_size, -                      backing_file, backing_fmt); -} - -typedef struct { -    Coroutine *co; -    int is_allocated; -    int *pnum; -} QEDIsAllocatedCB; - -static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t len) -{ -    QEDIsAllocatedCB *cb = opaque; -    *cb->pnum = len / BDRV_SECTOR_SIZE; -    cb->is_allocated = (ret == QED_CLUSTER_FOUND || ret == QED_CLUSTER_ZERO); -    if (cb->co) { -        qemu_coroutine_enter(cb->co, NULL); -    } -} - -static int coroutine_fn bdrv_qed_co_is_allocated(BlockDriverState *bs, -                                                 int64_t sector_num, -                                                 int nb_sectors, int *pnum) -{ -    BDRVQEDState *s = bs->opaque; -    uint64_t pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE; -    size_t len = (size_t)nb_sectors * BDRV_SECTOR_SIZE; -    QEDIsAllocatedCB cb = { -        .is_allocated = -1, -        .pnum = pnum, -    }; -    QEDRequest request = { .l2_table = NULL }; - -    qed_find_cluster(s, &request, pos, len, qed_is_allocated_cb, &cb); - -    /* Now sleep if the callback wasn't invoked immediately */ -    while (cb.is_allocated == -1) { -        cb.co = qemu_coroutine_self(); -        qemu_coroutine_yield(); -    } - -    qed_unref_l2_cache_entry(request.l2_table); - -    return cb.is_allocated; -} - -static int bdrv_qed_make_empty(BlockDriverState *bs) -{ -    return -ENOTSUP; -} - -static BDRVQEDState *acb_to_s(QEDAIOCB *acb) -{ -    return acb->common.bs->opaque; -} - -/** - * Read from the backing file or zero-fill if no backing file - * - * @s:          QED state - * @pos:        Byte position in device - * @qiov:       Destination I/O vector - * @cb:         Completion function - * @opaque:     User data for completion function - * - * This function reads qiov->size bytes starting at pos from the backing file. - * If there is no backing file then zeroes are read. - */ -static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos, -                                  QEMUIOVector *qiov, -                                  BlockDriverCompletionFunc *cb, void *opaque) -{ -    uint64_t backing_length = 0; -    size_t size; - -    /* If there is a backing file, get its length.  Treat the absence of a -     * backing file like a zero length backing file. -     */ -    if (s->bs->backing_hd) { -        int64_t l = bdrv_getlength(s->bs->backing_hd); -        if (l < 0) { -            cb(opaque, l); -            return; -        } -        backing_length = l; -    } - -    /* Zero all sectors if reading beyond the end of the backing file */ -    if (pos >= backing_length || -        pos + qiov->size > backing_length) { -        qemu_iovec_memset(qiov, 0, 0, qiov->size); -    } - -    /* Complete now if there are no backing file sectors to read */ -    if (pos >= backing_length) { -        cb(opaque, 0); -        return; -    } - -    /* If the read straddles the end of the backing file, shorten it */ -    size = MIN((uint64_t)backing_length - pos, qiov->size); - -    BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO); -    bdrv_aio_readv(s->bs->backing_hd, pos / BDRV_SECTOR_SIZE, -                   qiov, size / BDRV_SECTOR_SIZE, cb, opaque); -} - -typedef struct { -    GenericCB gencb; -    BDRVQEDState *s; -    QEMUIOVector qiov; -    struct iovec iov; -    uint64_t offset; -} CopyFromBackingFileCB; - -static void qed_copy_from_backing_file_cb(void *opaque, int ret) -{ -    CopyFromBackingFileCB *copy_cb = opaque; -    qemu_vfree(copy_cb->iov.iov_base); -    gencb_complete(©_cb->gencb, ret); -} - -static void qed_copy_from_backing_file_write(void *opaque, int ret) -{ -    CopyFromBackingFileCB *copy_cb = opaque; -    BDRVQEDState *s = copy_cb->s; - -    if (ret) { -        qed_copy_from_backing_file_cb(copy_cb, ret); -        return; -    } - -    BLKDBG_EVENT(s->bs->file, BLKDBG_COW_WRITE); -    bdrv_aio_writev(s->bs->file, copy_cb->offset / BDRV_SECTOR_SIZE, -                    ©_cb->qiov, copy_cb->qiov.size / BDRV_SECTOR_SIZE, -                    qed_copy_from_backing_file_cb, copy_cb); -} - -/** - * Copy data from backing file into the image - * - * @s:          QED state - * @pos:        Byte position in device - * @len:        Number of bytes - * @offset:     Byte offset in image file - * @cb:         Completion function - * @opaque:     User data for completion function - */ -static void qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos, -                                       uint64_t len, uint64_t offset, -                                       BlockDriverCompletionFunc *cb, -                                       void *opaque) -{ -    CopyFromBackingFileCB *copy_cb; - -    /* Skip copy entirely if there is no work to do */ -    if (len == 0) { -        cb(opaque, 0); -        return; -    } - -    copy_cb = gencb_alloc(sizeof(*copy_cb), cb, opaque); -    copy_cb->s = s; -    copy_cb->offset = offset; -    copy_cb->iov.iov_base = qemu_blockalign(s->bs, len); -    copy_cb->iov.iov_len = len; -    qemu_iovec_init_external(©_cb->qiov, ©_cb->iov, 1); - -    qed_read_backing_file(s, pos, ©_cb->qiov, -                          qed_copy_from_backing_file_write, copy_cb); -} - -/** - * Link one or more contiguous clusters into a table - * - * @s:              QED state - * @table:          L2 table - * @index:          First cluster index - * @n:              Number of contiguous clusters - * @cluster:        First cluster offset - * - * The cluster offset may be an allocated byte offset in the image file, the - * zero cluster marker, or the unallocated cluster marker. - */ -static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index, -                                unsigned int n, uint64_t cluster) -{ -    int i; -    for (i = index; i < index + n; i++) { -        table->offsets[i] = cluster; -        if (!qed_offset_is_unalloc_cluster(cluster) && -            !qed_offset_is_zero_cluster(cluster)) { -            cluster += s->header.cluster_size; -        } -    } -} - -static void qed_aio_complete_bh(void *opaque) -{ -    QEDAIOCB *acb = opaque; -    BlockDriverCompletionFunc *cb = acb->common.cb; -    void *user_opaque = acb->common.opaque; -    int ret = acb->bh_ret; -    bool *finished = acb->finished; - -    qemu_bh_delete(acb->bh); -    qemu_aio_release(acb); - -    /* Invoke callback */ -    cb(user_opaque, ret); - -    /* Signal cancel completion */ -    if (finished) { -        *finished = true; -    } -} - -static void qed_aio_complete(QEDAIOCB *acb, int ret) -{ -    BDRVQEDState *s = acb_to_s(acb); - -    trace_qed_aio_complete(s, acb, ret); - -    /* Free resources */ -    qemu_iovec_destroy(&acb->cur_qiov); -    qed_unref_l2_cache_entry(acb->request.l2_table); - -    /* Free the buffer we may have allocated for zero writes */ -    if (acb->flags & QED_AIOCB_ZERO) { -        qemu_vfree(acb->qiov->iov[0].iov_base); -        acb->qiov->iov[0].iov_base = NULL; -    } - -    /* Arrange for a bh to invoke the completion function */ -    acb->bh_ret = ret; -    acb->bh = qemu_bh_new(qed_aio_complete_bh, acb); -    qemu_bh_schedule(acb->bh); - -    /* Start next allocating write request waiting behind this one.  Note that -     * requests enqueue themselves when they first hit an unallocated cluster -     * but they wait until the entire request is finished before waking up the -     * next request in the queue.  This ensures that we don't cycle through -     * requests multiple times but rather finish one at a time completely. -     */ -    if (acb == QSIMPLEQ_FIRST(&s->allocating_write_reqs)) { -        QSIMPLEQ_REMOVE_HEAD(&s->allocating_write_reqs, next); -        acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs); -        if (acb) { -            qed_aio_next_io(acb, 0); -        } else if (s->header.features & QED_F_NEED_CHECK) { -            qed_start_need_check_timer(s); -        } -    } -} - -/** - * Commit the current L2 table to the cache - */ -static void qed_commit_l2_update(void *opaque, int ret) -{ -    QEDAIOCB *acb = opaque; -    BDRVQEDState *s = acb_to_s(acb); -    CachedL2Table *l2_table = acb->request.l2_table; -    uint64_t l2_offset = l2_table->offset; - -    qed_commit_l2_cache_entry(&s->l2_cache, l2_table); - -    /* This is guaranteed to succeed because we just committed the entry to the -     * cache. -     */ -    acb->request.l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset); -    assert(acb->request.l2_table != NULL); - -    qed_aio_next_io(opaque, ret); -} - -/** - * Update L1 table with new L2 table offset and write it out - */ -static void qed_aio_write_l1_update(void *opaque, int ret) -{ -    QEDAIOCB *acb = opaque; -    BDRVQEDState *s = acb_to_s(acb); -    int index; - -    if (ret) { -        qed_aio_complete(acb, ret); -        return; -    } - -    index = qed_l1_index(s, acb->cur_pos); -    s->l1_table->offsets[index] = acb->request.l2_table->offset; - -    qed_write_l1_table(s, index, 1, qed_commit_l2_update, acb); -} - -/** - * Update L2 table with new cluster offsets and write them out - */ -static void qed_aio_write_l2_update(QEDAIOCB *acb, int ret, uint64_t offset) -{ -    BDRVQEDState *s = acb_to_s(acb); -    bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1; -    int index; - -    if (ret) { -        goto err; -    } - -    if (need_alloc) { -        qed_unref_l2_cache_entry(acb->request.l2_table); -        acb->request.l2_table = qed_new_l2_table(s); -    } - -    index = qed_l2_index(s, acb->cur_pos); -    qed_update_l2_table(s, acb->request.l2_table->table, index, acb->cur_nclusters, -                         offset); - -    if (need_alloc) { -        /* Write out the whole new L2 table */ -        qed_write_l2_table(s, &acb->request, 0, s->table_nelems, true, -                            qed_aio_write_l1_update, acb); -    } else { -        /* Write out only the updated part of the L2 table */ -        qed_write_l2_table(s, &acb->request, index, acb->cur_nclusters, false, -                            qed_aio_next_io, acb); -    } -    return; - -err: -    qed_aio_complete(acb, ret); -} - -static void qed_aio_write_l2_update_cb(void *opaque, int ret) -{ -    QEDAIOCB *acb = opaque; -    qed_aio_write_l2_update(acb, ret, acb->cur_cluster); -} - -/** - * Flush new data clusters before updating the L2 table - * - * This flush is necessary when a backing file is in use.  A crash during an - * allocating write could result in empty clusters in the image.  If the write - * only touched a subregion of the cluster, then backing image sectors have - * been lost in the untouched region.  The solution is to flush after writing a - * new data cluster and before updating the L2 table. - */ -static void qed_aio_write_flush_before_l2_update(void *opaque, int ret) -{ -    QEDAIOCB *acb = opaque; -    BDRVQEDState *s = acb_to_s(acb); - -    if (!bdrv_aio_flush(s->bs->file, qed_aio_write_l2_update_cb, opaque)) { -        qed_aio_complete(acb, -EIO); -    } -} - -/** - * Write data to the image file - */ -static void qed_aio_write_main(void *opaque, int ret) -{ -    QEDAIOCB *acb = opaque; -    BDRVQEDState *s = acb_to_s(acb); -    uint64_t offset = acb->cur_cluster + -                      qed_offset_into_cluster(s, acb->cur_pos); -    BlockDriverCompletionFunc *next_fn; - -    trace_qed_aio_write_main(s, acb, ret, offset, acb->cur_qiov.size); - -    if (ret) { -        qed_aio_complete(acb, ret); -        return; -    } - -    if (acb->find_cluster_ret == QED_CLUSTER_FOUND) { -        next_fn = qed_aio_next_io; -    } else { -        if (s->bs->backing_hd) { -            next_fn = qed_aio_write_flush_before_l2_update; -        } else { -            next_fn = qed_aio_write_l2_update_cb; -        } -    } - -    BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO); -    bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE, -                    &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE, -                    next_fn, acb); -} - -/** - * Populate back untouched region of new data cluster - */ -static void qed_aio_write_postfill(void *opaque, int ret) -{ -    QEDAIOCB *acb = opaque; -    BDRVQEDState *s = acb_to_s(acb); -    uint64_t start = acb->cur_pos + acb->cur_qiov.size; -    uint64_t len = -        qed_start_of_cluster(s, start + s->header.cluster_size - 1) - start; -    uint64_t offset = acb->cur_cluster + -                      qed_offset_into_cluster(s, acb->cur_pos) + -                      acb->cur_qiov.size; - -    if (ret) { -        qed_aio_complete(acb, ret); -        return; -    } - -    trace_qed_aio_write_postfill(s, acb, start, len, offset); -    qed_copy_from_backing_file(s, start, len, offset, -                                qed_aio_write_main, acb); -} - -/** - * Populate front untouched region of new data cluster - */ -static void qed_aio_write_prefill(void *opaque, int ret) -{ -    QEDAIOCB *acb = opaque; -    BDRVQEDState *s = acb_to_s(acb); -    uint64_t start = qed_start_of_cluster(s, acb->cur_pos); -    uint64_t len = qed_offset_into_cluster(s, acb->cur_pos); - -    trace_qed_aio_write_prefill(s, acb, start, len, acb->cur_cluster); -    qed_copy_from_backing_file(s, start, len, acb->cur_cluster, -                                qed_aio_write_postfill, acb); -} - -/** - * Check if the QED_F_NEED_CHECK bit should be set during allocating write - */ -static bool qed_should_set_need_check(BDRVQEDState *s) -{ -    /* The flush before L2 update path ensures consistency */ -    if (s->bs->backing_hd) { -        return false; -    } - -    return !(s->header.features & QED_F_NEED_CHECK); -} - -static void qed_aio_write_zero_cluster(void *opaque, int ret) -{ -    QEDAIOCB *acb = opaque; - -    if (ret) { -        qed_aio_complete(acb, ret); -        return; -    } - -    qed_aio_write_l2_update(acb, 0, 1); -} - -/** - * Write new data cluster - * - * @acb:        Write request - * @len:        Length in bytes - * - * This path is taken when writing to previously unallocated clusters. - */ -static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len) -{ -    BDRVQEDState *s = acb_to_s(acb); -    BlockDriverCompletionFunc *cb; - -    /* Cancel timer when the first allocating request comes in */ -    if (QSIMPLEQ_EMPTY(&s->allocating_write_reqs)) { -        qed_cancel_need_check_timer(s); -    } - -    /* Freeze this request if another allocating write is in progress */ -    if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) { -        QSIMPLEQ_INSERT_TAIL(&s->allocating_write_reqs, acb, next); -    } -    if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs) || -        s->allocating_write_reqs_plugged) { -        return; /* wait for existing request to finish */ -    } - -    acb->cur_nclusters = qed_bytes_to_clusters(s, -            qed_offset_into_cluster(s, acb->cur_pos) + len); -    qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len); - -    if (acb->flags & QED_AIOCB_ZERO) { -        /* Skip ahead if the clusters are already zero */ -        if (acb->find_cluster_ret == QED_CLUSTER_ZERO) { -            qed_aio_next_io(acb, 0); -            return; -        } - -        cb = qed_aio_write_zero_cluster; -    } else { -        cb = qed_aio_write_prefill; -        acb->cur_cluster = qed_alloc_clusters(s, acb->cur_nclusters); -    } - -    if (qed_should_set_need_check(s)) { -        s->header.features |= QED_F_NEED_CHECK; -        qed_write_header(s, cb, acb); -    } else { -        cb(acb, 0); -    } -} - -/** - * Write data cluster in place - * - * @acb:        Write request - * @offset:     Cluster offset in bytes - * @len:        Length in bytes - * - * This path is taken when writing to already allocated clusters. - */ -static void qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len) -{ -    /* Allocate buffer for zero writes */ -    if (acb->flags & QED_AIOCB_ZERO) { -        struct iovec *iov = acb->qiov->iov; - -        if (!iov->iov_base) { -            iov->iov_base = qemu_blockalign(acb->common.bs, iov->iov_len); -            memset(iov->iov_base, 0, iov->iov_len); -        } -    } - -    /* Calculate the I/O vector */ -    acb->cur_cluster = offset; -    qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len); - -    /* Do the actual write */ -    qed_aio_write_main(acb, 0); -} - -/** - * Write data cluster - * - * @opaque:     Write request - * @ret:        QED_CLUSTER_FOUND, QED_CLUSTER_L2, QED_CLUSTER_L1, - *              or -errno - * @offset:     Cluster offset in bytes - * @len:        Length in bytes - * - * Callback from qed_find_cluster(). - */ -static void qed_aio_write_data(void *opaque, int ret, -                               uint64_t offset, size_t len) -{ -    QEDAIOCB *acb = opaque; - -    trace_qed_aio_write_data(acb_to_s(acb), acb, ret, offset, len); - -    acb->find_cluster_ret = ret; - -    switch (ret) { -    case QED_CLUSTER_FOUND: -        qed_aio_write_inplace(acb, offset, len); -        break; - -    case QED_CLUSTER_L2: -    case QED_CLUSTER_L1: -    case QED_CLUSTER_ZERO: -        qed_aio_write_alloc(acb, len); -        break; - -    default: -        qed_aio_complete(acb, ret); -        break; -    } -} - -/** - * Read data cluster - * - * @opaque:     Read request - * @ret:        QED_CLUSTER_FOUND, QED_CLUSTER_L2, QED_CLUSTER_L1, - *              or -errno - * @offset:     Cluster offset in bytes - * @len:        Length in bytes - * - * Callback from qed_find_cluster(). - */ -static void qed_aio_read_data(void *opaque, int ret, -                              uint64_t offset, size_t len) -{ -    QEDAIOCB *acb = opaque; -    BDRVQEDState *s = acb_to_s(acb); -    BlockDriverState *bs = acb->common.bs; - -    /* Adjust offset into cluster */ -    offset += qed_offset_into_cluster(s, acb->cur_pos); - -    trace_qed_aio_read_data(s, acb, ret, offset, len); - -    if (ret < 0) { -        goto err; -    } - -    qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len); - -    /* Handle zero cluster and backing file reads */ -    if (ret == QED_CLUSTER_ZERO) { -        qemu_iovec_memset(&acb->cur_qiov, 0, 0, acb->cur_qiov.size); -        qed_aio_next_io(acb, 0); -        return; -    } else if (ret != QED_CLUSTER_FOUND) { -        qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov, -                              qed_aio_next_io, acb); -        return; -    } - -    BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); -    bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE, -                   &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE, -                   qed_aio_next_io, acb); -    return; - -err: -    qed_aio_complete(acb, ret); -} - -/** - * Begin next I/O or complete the request - */ -static void qed_aio_next_io(void *opaque, int ret) -{ -    QEDAIOCB *acb = opaque; -    BDRVQEDState *s = acb_to_s(acb); -    QEDFindClusterFunc *io_fn = (acb->flags & QED_AIOCB_WRITE) ? -                                qed_aio_write_data : qed_aio_read_data; - -    trace_qed_aio_next_io(s, acb, ret, acb->cur_pos + acb->cur_qiov.size); - -    /* Handle I/O error */ -    if (ret) { -        qed_aio_complete(acb, ret); -        return; -    } - -    acb->qiov_offset += acb->cur_qiov.size; -    acb->cur_pos += acb->cur_qiov.size; -    qemu_iovec_reset(&acb->cur_qiov); - -    /* Complete request */ -    if (acb->cur_pos >= acb->end_pos) { -        qed_aio_complete(acb, 0); -        return; -    } - -    /* Find next cluster and start I/O */ -    qed_find_cluster(s, &acb->request, -                      acb->cur_pos, acb->end_pos - acb->cur_pos, -                      io_fn, acb); -} - -static BlockDriverAIOCB *qed_aio_setup(BlockDriverState *bs, -                                       int64_t sector_num, -                                       QEMUIOVector *qiov, int nb_sectors, -                                       BlockDriverCompletionFunc *cb, -                                       void *opaque, int flags) -{ -    QEDAIOCB *acb = qemu_aio_get(&qed_aiocb_info, bs, cb, opaque); - -    trace_qed_aio_setup(bs->opaque, acb, sector_num, nb_sectors, -                        opaque, flags); - -    acb->flags = flags; -    acb->finished = NULL; -    acb->qiov = qiov; -    acb->qiov_offset = 0; -    acb->cur_pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE; -    acb->end_pos = acb->cur_pos + nb_sectors * BDRV_SECTOR_SIZE; -    acb->request.l2_table = NULL; -    qemu_iovec_init(&acb->cur_qiov, qiov->niov); - -    /* Start request */ -    qed_aio_next_io(acb, 0); -    return &acb->common; -} - -static BlockDriverAIOCB *bdrv_qed_aio_readv(BlockDriverState *bs, -                                            int64_t sector_num, -                                            QEMUIOVector *qiov, int nb_sectors, -                                            BlockDriverCompletionFunc *cb, -                                            void *opaque) -{ -    return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); -} - -static BlockDriverAIOCB *bdrv_qed_aio_writev(BlockDriverState *bs, -                                             int64_t sector_num, -                                             QEMUIOVector *qiov, int nb_sectors, -                                             BlockDriverCompletionFunc *cb, -                                             void *opaque) -{ -    return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, -                         opaque, QED_AIOCB_WRITE); -} - -typedef struct { -    Coroutine *co; -    int ret; -    bool done; -} QEDWriteZeroesCB; - -static void coroutine_fn qed_co_write_zeroes_cb(void *opaque, int ret) -{ -    QEDWriteZeroesCB *cb = opaque; - -    cb->done = true; -    cb->ret = ret; -    if (cb->co) { -        qemu_coroutine_enter(cb->co, NULL); -    } -} - -static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs, -                                                 int64_t sector_num, -                                                 int nb_sectors) -{ -    BlockDriverAIOCB *blockacb; -    BDRVQEDState *s = bs->opaque; -    QEDWriteZeroesCB cb = { .done = false }; -    QEMUIOVector qiov; -    struct iovec iov; - -    /* Refuse if there are untouched backing file sectors */ -    if (bs->backing_hd) { -        if (qed_offset_into_cluster(s, sector_num * BDRV_SECTOR_SIZE) != 0) { -            return -ENOTSUP; -        } -        if (qed_offset_into_cluster(s, nb_sectors * BDRV_SECTOR_SIZE) != 0) { -            return -ENOTSUP; -        } -    } - -    /* Zero writes start without an I/O buffer.  If a buffer becomes necessary -     * then it will be allocated during request processing. -     */ -    iov.iov_base = NULL, -    iov.iov_len  = nb_sectors * BDRV_SECTOR_SIZE, - -    qemu_iovec_init_external(&qiov, &iov, 1); -    blockacb = qed_aio_setup(bs, sector_num, &qiov, nb_sectors, -                             qed_co_write_zeroes_cb, &cb, -                             QED_AIOCB_WRITE | QED_AIOCB_ZERO); -    if (!blockacb) { -        return -EIO; -    } -    if (!cb.done) { -        cb.co = qemu_coroutine_self(); -        qemu_coroutine_yield(); -    } -    assert(cb.done); -    return cb.ret; -} - -static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset) -{ -    BDRVQEDState *s = bs->opaque; -    uint64_t old_image_size; -    int ret; - -    if (!qed_is_image_size_valid(offset, s->header.cluster_size, -                                 s->header.table_size)) { -        return -EINVAL; -    } - -    /* Shrinking is currently not supported */ -    if ((uint64_t)offset < s->header.image_size) { -        return -ENOTSUP; -    } - -    old_image_size = s->header.image_size; -    s->header.image_size = offset; -    ret = qed_write_header_sync(s); -    if (ret < 0) { -        s->header.image_size = old_image_size; -    } -    return ret; -} - -static int64_t bdrv_qed_getlength(BlockDriverState *bs) -{ -    BDRVQEDState *s = bs->opaque; -    return s->header.image_size; -} - -static int bdrv_qed_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) -{ -    BDRVQEDState *s = bs->opaque; - -    memset(bdi, 0, sizeof(*bdi)); -    bdi->cluster_size = s->header.cluster_size; -    bdi->is_dirty = s->header.features & QED_F_NEED_CHECK; -    return 0; -} - -static int bdrv_qed_change_backing_file(BlockDriverState *bs, -                                        const char *backing_file, -                                        const char *backing_fmt) -{ -    BDRVQEDState *s = bs->opaque; -    QEDHeader new_header, le_header; -    void *buffer; -    size_t buffer_len, backing_file_len; -    int ret; - -    /* Refuse to set backing filename if unknown compat feature bits are -     * active.  If the image uses an unknown compat feature then we may not -     * know the layout of data following the header structure and cannot safely -     * add a new string. -     */ -    if (backing_file && (s->header.compat_features & -                         ~QED_COMPAT_FEATURE_MASK)) { -        return -ENOTSUP; -    } - -    memcpy(&new_header, &s->header, sizeof(new_header)); - -    new_header.features &= ~(QED_F_BACKING_FILE | -                             QED_F_BACKING_FORMAT_NO_PROBE); - -    /* Adjust feature flags */ -    if (backing_file) { -        new_header.features |= QED_F_BACKING_FILE; - -        if (qed_fmt_is_raw(backing_fmt)) { -            new_header.features |= QED_F_BACKING_FORMAT_NO_PROBE; -        } -    } - -    /* Calculate new header size */ -    backing_file_len = 0; - -    if (backing_file) { -        backing_file_len = strlen(backing_file); -    } - -    buffer_len = sizeof(new_header); -    new_header.backing_filename_offset = buffer_len; -    new_header.backing_filename_size = backing_file_len; -    buffer_len += backing_file_len; - -    /* Make sure we can rewrite header without failing */ -    if (buffer_len > new_header.header_size * new_header.cluster_size) { -        return -ENOSPC; -    } - -    /* Prepare new header */ -    buffer = g_malloc(buffer_len); - -    qed_header_cpu_to_le(&new_header, &le_header); -    memcpy(buffer, &le_header, sizeof(le_header)); -    buffer_len = sizeof(le_header); - -    if (backing_file) { -        memcpy(buffer + buffer_len, backing_file, backing_file_len); -        buffer_len += backing_file_len; -    } - -    /* Write new header */ -    ret = bdrv_pwrite_sync(bs->file, 0, buffer, buffer_len); -    g_free(buffer); -    if (ret == 0) { -        memcpy(&s->header, &new_header, sizeof(new_header)); -    } -    return ret; -} - -static void bdrv_qed_invalidate_cache(BlockDriverState *bs) -{ -    BDRVQEDState *s = bs->opaque; - -    bdrv_qed_close(bs); -    memset(s, 0, sizeof(BDRVQEDState)); -    bdrv_qed_open(bs, NULL, bs->open_flags); -} - -static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result, -                          BdrvCheckMode fix) -{ -    BDRVQEDState *s = bs->opaque; - -    return qed_check(s, result, !!fix); -} - -static QEMUOptionParameter qed_create_options[] = { -    { -        .name = BLOCK_OPT_SIZE, -        .type = OPT_SIZE, -        .help = "Virtual disk size (in bytes)" -    }, { -        .name = BLOCK_OPT_BACKING_FILE, -        .type = OPT_STRING, -        .help = "File name of a base image" -    }, { -        .name = BLOCK_OPT_BACKING_FMT, -        .type = OPT_STRING, -        .help = "Image format of the base image" -    }, { -        .name = BLOCK_OPT_CLUSTER_SIZE, -        .type = OPT_SIZE, -        .help = "Cluster size (in bytes)", -        .value = { .n = QED_DEFAULT_CLUSTER_SIZE }, -    }, { -        .name = BLOCK_OPT_TABLE_SIZE, -        .type = OPT_SIZE, -        .help = "L1/L2 table size (in clusters)" -    }, -    { /* end of list */ } -}; - -static BlockDriver bdrv_qed = { -    .format_name              = "qed", -    .instance_size            = sizeof(BDRVQEDState), -    .create_options           = qed_create_options, - -    .bdrv_probe               = bdrv_qed_probe, -    .bdrv_rebind              = bdrv_qed_rebind, -    .bdrv_open                = bdrv_qed_open, -    .bdrv_close               = bdrv_qed_close, -    .bdrv_reopen_prepare      = bdrv_qed_reopen_prepare, -    .bdrv_create              = bdrv_qed_create, -    .bdrv_has_zero_init       = bdrv_has_zero_init_1, -    .bdrv_co_is_allocated     = bdrv_qed_co_is_allocated, -    .bdrv_make_empty          = bdrv_qed_make_empty, -    .bdrv_aio_readv           = bdrv_qed_aio_readv, -    .bdrv_aio_writev          = bdrv_qed_aio_writev, -    .bdrv_co_write_zeroes     = bdrv_qed_co_write_zeroes, -    .bdrv_truncate            = bdrv_qed_truncate, -    .bdrv_getlength           = bdrv_qed_getlength, -    .bdrv_get_info            = bdrv_qed_get_info, -    .bdrv_change_backing_file = bdrv_qed_change_backing_file, -    .bdrv_invalidate_cache    = bdrv_qed_invalidate_cache, -    .bdrv_check               = bdrv_qed_check, -}; - -static void bdrv_qed_init(void) -{ -    bdrv_register(&bdrv_qed); -} - -block_init(bdrv_qed_init); diff --git a/contrib/qemu/block/qed.h b/contrib/qemu/block/qed.h deleted file mode 100644 index 2b4ddedf313..00000000000 --- a/contrib/qemu/block/qed.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * QEMU Enhanced Disk Format - * - * Copyright IBM, Corp. 2010 - * - * Authors: - *  Stefan Hajnoczi   <stefanha@linux.vnet.ibm.com> - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef BLOCK_QED_H -#define BLOCK_QED_H - -#include "block/block_int.h" - -/* The layout of a QED file is as follows: - * - * +--------+----------+----------+----------+-----+ - * | header | L1 table | cluster0 | cluster1 | ... | - * +--------+----------+----------+----------+-----+ - * - * There is a 2-level pagetable for cluster allocation: - * - *                     +----------+ - *                     | L1 table | - *                     +----------+ - *                ,------'  |  '------. - *           +----------+   |    +----------+ - *           | L2 table |  ...   | L2 table | - *           +----------+        +----------+ - *       ,------'  |  '------. - *  +----------+   |    +----------+ - *  |   Data   |  ...   |   Data   | - *  +----------+        +----------+ - * - * The L1 table is fixed size and always present.  L2 tables are allocated on - * demand.  The L1 table size determines the maximum possible image size; it - * can be influenced using the cluster_size and table_size values. - * - * All fields are little-endian on disk. - */ - -enum { -    QED_MAGIC = 'Q' | 'E' << 8 | 'D' << 16 | '\0' << 24, - -    /* The image supports a backing file */ -    QED_F_BACKING_FILE = 0x01, - -    /* The image needs a consistency check before use */ -    QED_F_NEED_CHECK = 0x02, - -    /* The backing file format must not be probed, treat as raw image */ -    QED_F_BACKING_FORMAT_NO_PROBE = 0x04, - -    /* Feature bits must be used when the on-disk format changes */ -    QED_FEATURE_MASK = QED_F_BACKING_FILE | /* supported feature bits */ -                       QED_F_NEED_CHECK | -                       QED_F_BACKING_FORMAT_NO_PROBE, -    QED_COMPAT_FEATURE_MASK = 0,            /* supported compat feature bits */ -    QED_AUTOCLEAR_FEATURE_MASK = 0,         /* supported autoclear feature bits */ - -    /* Data is stored in groups of sectors called clusters.  Cluster size must -     * be large to avoid keeping too much metadata.  I/O requests that have -     * sub-cluster size will require read-modify-write. -     */ -    QED_MIN_CLUSTER_SIZE = 4 * 1024, /* in bytes */ -    QED_MAX_CLUSTER_SIZE = 64 * 1024 * 1024, -    QED_DEFAULT_CLUSTER_SIZE = 64 * 1024, - -    /* Allocated clusters are tracked using a 2-level pagetable.  Table size is -     * a multiple of clusters so large maximum image sizes can be supported -     * without jacking up the cluster size too much. -     */ -    QED_MIN_TABLE_SIZE = 1,        /* in clusters */ -    QED_MAX_TABLE_SIZE = 16, -    QED_DEFAULT_TABLE_SIZE = 4, - -    /* Delay to flush and clean image after last allocating write completes */ -    QED_NEED_CHECK_TIMEOUT = 5,    /* in seconds */ -}; - -typedef struct { -    uint32_t magic;                 /* QED\0 */ - -    uint32_t cluster_size;          /* in bytes */ -    uint32_t table_size;            /* for L1 and L2 tables, in clusters */ -    uint32_t header_size;           /* in clusters */ - -    uint64_t features;              /* format feature bits */ -    uint64_t compat_features;       /* compatible feature bits */ -    uint64_t autoclear_features;    /* self-resetting feature bits */ - -    uint64_t l1_table_offset;       /* in bytes */ -    uint64_t image_size;            /* total logical image size, in bytes */ - -    /* if (features & QED_F_BACKING_FILE) */ -    uint32_t backing_filename_offset; /* in bytes from start of header */ -    uint32_t backing_filename_size;   /* in bytes */ -} QEDHeader; - -typedef struct { -    uint64_t offsets[0];            /* in bytes */ -} QEDTable; - -/* The L2 cache is a simple write-through cache for L2 structures */ -typedef struct CachedL2Table { -    QEDTable *table; -    uint64_t offset;    /* offset=0 indicates an invalidate entry */ -    QTAILQ_ENTRY(CachedL2Table) node; -    int ref; -} CachedL2Table; - -typedef struct { -    QTAILQ_HEAD(, CachedL2Table) entries; -    unsigned int n_entries; -} L2TableCache; - -typedef struct QEDRequest { -    CachedL2Table *l2_table; -} QEDRequest; - -enum { -    QED_AIOCB_WRITE = 0x0001,       /* read or write? */ -    QED_AIOCB_ZERO  = 0x0002,       /* zero write, used with QED_AIOCB_WRITE */ -}; - -typedef struct QEDAIOCB { -    BlockDriverAIOCB common; -    QEMUBH *bh; -    int bh_ret;                     /* final return status for completion bh */ -    QSIMPLEQ_ENTRY(QEDAIOCB) next;  /* next request */ -    int flags;                      /* QED_AIOCB_* bits ORed together */ -    bool *finished;                 /* signal for cancel completion */ -    uint64_t end_pos;               /* request end on block device, in bytes */ - -    /* User scatter-gather list */ -    QEMUIOVector *qiov; -    size_t qiov_offset;             /* byte count already processed */ - -    /* Current cluster scatter-gather list */ -    QEMUIOVector cur_qiov; -    uint64_t cur_pos;               /* position on block device, in bytes */ -    uint64_t cur_cluster;           /* cluster offset in image file */ -    unsigned int cur_nclusters;     /* number of clusters being accessed */ -    int find_cluster_ret;           /* used for L1/L2 update */ - -    QEDRequest request; -} QEDAIOCB; - -typedef struct { -    BlockDriverState *bs;           /* device */ -    uint64_t file_size;             /* length of image file, in bytes */ - -    QEDHeader header;               /* always cpu-endian */ -    QEDTable *l1_table; -    L2TableCache l2_cache;          /* l2 table cache */ -    uint32_t table_nelems; -    uint32_t l1_shift; -    uint32_t l2_shift; -    uint32_t l2_mask; - -    /* Allocating write request queue */ -    QSIMPLEQ_HEAD(, QEDAIOCB) allocating_write_reqs; -    bool allocating_write_reqs_plugged; - -    /* Periodic flush and clear need check flag */ -    QEMUTimer *need_check_timer; -} BDRVQEDState; - -enum { -    QED_CLUSTER_FOUND,         /* cluster found */ -    QED_CLUSTER_ZERO,          /* zero cluster found */ -    QED_CLUSTER_L2,            /* cluster missing in L2 */ -    QED_CLUSTER_L1,            /* cluster missing in L1 */ -}; - -/** - * qed_find_cluster() completion callback - * - * @opaque:     User data for completion callback - * @ret:        QED_CLUSTER_FOUND   Success - *              QED_CLUSTER_L2      Data cluster unallocated in L2 - *              QED_CLUSTER_L1      L2 unallocated in L1 - *              -errno              POSIX error occurred - * @offset:     Data cluster offset - * @len:        Contiguous bytes starting from cluster offset - * - * This function is invoked when qed_find_cluster() completes. - * - * On success ret is QED_CLUSTER_FOUND and offset/len are a contiguous range - * in the image file. - * - * On failure ret is QED_CLUSTER_L2 or QED_CLUSTER_L1 for missing L2 or L1 - * table offset, respectively.  len is number of contiguous unallocated bytes. - */ -typedef void QEDFindClusterFunc(void *opaque, int ret, uint64_t offset, size_t len); - -/** - * Generic callback for chaining async callbacks - */ -typedef struct { -    BlockDriverCompletionFunc *cb; -    void *opaque; -} GenericCB; - -void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque); -void gencb_complete(void *opaque, int ret); - -/** - * Header functions - */ -int qed_write_header_sync(BDRVQEDState *s); - -/** - * L2 cache functions - */ -void qed_init_l2_cache(L2TableCache *l2_cache); -void qed_free_l2_cache(L2TableCache *l2_cache); -CachedL2Table *qed_alloc_l2_cache_entry(L2TableCache *l2_cache); -void qed_unref_l2_cache_entry(CachedL2Table *entry); -CachedL2Table *qed_find_l2_cache_entry(L2TableCache *l2_cache, uint64_t offset); -void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table); - -/** - * Table I/O functions - */ -int qed_read_l1_table_sync(BDRVQEDState *s); -void qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n, -                        BlockDriverCompletionFunc *cb, void *opaque); -int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, -                            unsigned int n); -int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, -                           uint64_t offset); -void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset, -                       BlockDriverCompletionFunc *cb, void *opaque); -void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, -                        unsigned int index, unsigned int n, bool flush, -                        BlockDriverCompletionFunc *cb, void *opaque); -int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request, -                            unsigned int index, unsigned int n, bool flush); - -/** - * Cluster functions - */ -void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos, -                      size_t len, QEDFindClusterFunc *cb, void *opaque); - -/** - * Consistency check - */ -int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix); - -QEDTable *qed_alloc_table(BDRVQEDState *s); - -/** - * Round down to the start of a cluster - */ -static inline uint64_t qed_start_of_cluster(BDRVQEDState *s, uint64_t offset) -{ -    return offset & ~(uint64_t)(s->header.cluster_size - 1); -} - -static inline uint64_t qed_offset_into_cluster(BDRVQEDState *s, uint64_t offset) -{ -    return offset & (s->header.cluster_size - 1); -} - -static inline uint64_t qed_bytes_to_clusters(BDRVQEDState *s, uint64_t bytes) -{ -    return qed_start_of_cluster(s, bytes + (s->header.cluster_size - 1)) / -           (s->header.cluster_size - 1); -} - -static inline unsigned int qed_l1_index(BDRVQEDState *s, uint64_t pos) -{ -    return pos >> s->l1_shift; -} - -static inline unsigned int qed_l2_index(BDRVQEDState *s, uint64_t pos) -{ -    return (pos >> s->l2_shift) & s->l2_mask; -} - -/** - * Test if a cluster offset is valid - */ -static inline bool qed_check_cluster_offset(BDRVQEDState *s, uint64_t offset) -{ -    uint64_t header_size = (uint64_t)s->header.header_size * -                           s->header.cluster_size; - -    if (offset & (s->header.cluster_size - 1)) { -        return false; -    } -    return offset >= header_size && offset < s->file_size; -} - -/** - * Test if a table offset is valid - */ -static inline bool qed_check_table_offset(BDRVQEDState *s, uint64_t offset) -{ -    uint64_t end_offset = offset + (s->header.table_size - 1) * -                          s->header.cluster_size; - -    /* Overflow check */ -    if (end_offset <= offset) { -        return false; -    } - -    return qed_check_cluster_offset(s, offset) && -           qed_check_cluster_offset(s, end_offset); -} - -static inline bool qed_offset_is_cluster_aligned(BDRVQEDState *s, -                                                 uint64_t offset) -{ -    if (qed_offset_into_cluster(s, offset)) { -        return false; -    } -    return true; -} - -static inline bool qed_offset_is_unalloc_cluster(uint64_t offset) -{ -    if (offset == 0) { -        return true; -    } -    return false; -} - -static inline bool qed_offset_is_zero_cluster(uint64_t offset) -{ -    if (offset == 1) { -        return true; -    } -    return false; -} - -#endif /* BLOCK_QED_H */ diff --git a/contrib/qemu/block/snapshot.c b/contrib/qemu/block/snapshot.c deleted file mode 100644 index 6c6d9deea1f..00000000000 --- a/contrib/qemu/block/snapshot.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Block layer snapshot related functions - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "block/snapshot.h" -#include "block/block_int.h" - -int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, -                       const char *name) -{ -    QEMUSnapshotInfo *sn_tab, *sn; -    int nb_sns, i, ret; - -    ret = -ENOENT; -    nb_sns = bdrv_snapshot_list(bs, &sn_tab); -    if (nb_sns < 0) { -        return ret; -    } -    for (i = 0; i < nb_sns; i++) { -        sn = &sn_tab[i]; -        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) { -            *sn_info = *sn; -            ret = 0; -            break; -        } -    } -    g_free(sn_tab); -    return ret; -} - -int bdrv_can_snapshot(BlockDriverState *bs) -{ -    BlockDriver *drv = bs->drv; -    if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { -        return 0; -    } - -    if (!drv->bdrv_snapshot_create) { -        if (bs->file != NULL) { -            return bdrv_can_snapshot(bs->file); -        } -        return 0; -    } - -    return 1; -} - -int bdrv_snapshot_create(BlockDriverState *bs, -                         QEMUSnapshotInfo *sn_info) -{ -    BlockDriver *drv = bs->drv; -    if (!drv) { -        return -ENOMEDIUM; -    } -    if (drv->bdrv_snapshot_create) { -        return drv->bdrv_snapshot_create(bs, sn_info); -    } -    if (bs->file) { -        return bdrv_snapshot_create(bs->file, sn_info); -    } -    return -ENOTSUP; -} - -int bdrv_snapshot_goto(BlockDriverState *bs, -                       const char *snapshot_id) -{ -    BlockDriver *drv = bs->drv; -    int ret, open_ret; - -    if (!drv) { -        return -ENOMEDIUM; -    } -    if (drv->bdrv_snapshot_goto) { -        return drv->bdrv_snapshot_goto(bs, snapshot_id); -    } - -    if (bs->file) { -        drv->bdrv_close(bs); -        ret = bdrv_snapshot_goto(bs->file, snapshot_id); -        open_ret = drv->bdrv_open(bs, NULL, bs->open_flags); -        if (open_ret < 0) { -            bdrv_delete(bs->file); -            bs->drv = NULL; -            return open_ret; -        } -        return ret; -    } - -    return -ENOTSUP; -} - -int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) -{ -    BlockDriver *drv = bs->drv; -    if (!drv) { -        return -ENOMEDIUM; -    } -    if (drv->bdrv_snapshot_delete) { -        return drv->bdrv_snapshot_delete(bs, snapshot_id); -    } -    if (bs->file) { -        return bdrv_snapshot_delete(bs->file, snapshot_id); -    } -    return -ENOTSUP; -} - -int bdrv_snapshot_list(BlockDriverState *bs, -                       QEMUSnapshotInfo **psn_info) -{ -    BlockDriver *drv = bs->drv; -    if (!drv) { -        return -ENOMEDIUM; -    } -    if (drv->bdrv_snapshot_list) { -        return drv->bdrv_snapshot_list(bs, psn_info); -    } -    if (bs->file) { -        return bdrv_snapshot_list(bs->file, psn_info); -    } -    return -ENOTSUP; -} - -int bdrv_snapshot_load_tmp(BlockDriverState *bs, -        const char *snapshot_name) -{ -    BlockDriver *drv = bs->drv; -    if (!drv) { -        return -ENOMEDIUM; -    } -    if (!bs->read_only) { -        return -EINVAL; -    } -    if (drv->bdrv_snapshot_load_tmp) { -        return drv->bdrv_snapshot_load_tmp(bs, snapshot_name); -    } -    return -ENOTSUP; -} diff --git a/contrib/qemu/config-host.h b/contrib/qemu/config-host.h deleted file mode 100644 index 6b5c8da1243..00000000000 --- a/contrib/qemu/config-host.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Automatically generated by create_config - do not modify */ -#define CONFIG_QEMU_CONFDIR "/usr/local/etc/qemu" -#define CONFIG_QEMU_DATADIR "/usr/local/share/qemu" -#define CONFIG_QEMU_DOCDIR "/usr/local/share/doc/qemu" -#define CONFIG_QEMU_LOCALSTATEDIR "/usr/local/var" -#define CONFIG_QEMU_HELPERDIR "/usr/local/libexec" -#define CONFIG_QEMU_LOCALEDIR "/usr/local/share/locale" -#define HOST_X86_64 1 -#define CONFIG_QEMU_LDST_OPTIMIZATION 1 -#define CONFIG_POSIX 1 -#define CONFIG_LINUX 1 -#define CONFIG_SLIRP 1 -#define CONFIG_SMBD_COMMAND "/usr/sbin/smbd" -#define CONFIG_AUDIO_DRIVERS \ -    &oss_audio_driver,\ - -#define CONFIG_OSS 1 -#define CONFIG_BDRV_RW_WHITELIST\ -    NULL -#define CONFIG_BDRV_RO_WHITELIST\ -    NULL -#define CONFIG_VNC 1 -#define CONFIG_VNC_TLS 1 -#define CONFIG_VNC_SASL 1 -#define CONFIG_VNC_WS 1 -#define CONFIG_FNMATCH 1 -#define CONFIG_UUID 1 -#define CONFIG_XFS 1 -#define QEMU_VERSION "1.5.50" -#define QEMU_PKGVERSION "" -#define CONFIG_CURSES 1 -#define CONFIG_UTIMENSAT 1 -#define CONFIG_PIPE2 1 -#define CONFIG_ACCEPT4 1 -#define CONFIG_SPLICE 1 -#define CONFIG_EVENTFD 1 -#define CONFIG_FALLOCATE 1 -#define CONFIG_FALLOCATE_PUNCH_HOLE 1 -#define CONFIG_SYNC_FILE_RANGE 1 -#define CONFIG_FIEMAP 1 -#define CONFIG_DUP3 1 -#define CONFIG_EPOLL 1 -#define CONFIG_EPOLL_CREATE1 1 -#define CONFIG_EPOLL_PWAIT 1 -#define CONFIG_SENDFILE 1 -#define CONFIG_INOTIFY 1 -#define CONFIG_INOTIFY1 1 -#define CONFIG_BYTESWAP_H 1 -#define CONFIG_CURL 1 -#define CONFIG_LINUX_AIO 1 -#define CONFIG_ATTR 1 -#define CONFIG_VHOST_SCSI 1 -#define CONFIG_IOVEC 1 -#define CONFIG_PREADV 1 -#define CONFIG_FDT 1 -#define CONFIG_SIGNALFD 1 -#define CONFIG_FDATASYNC 1 -#define CONFIG_MADVISE 1 -#define CONFIG_POSIX_MADVISE 1 -#define CONFIG_SIGEV_THREAD_ID 1 -#define CONFIG_UNAME_RELEASE "" -#define CONFIG_QOM_CAST_DEBUG 1 -#define CONFIG_COROUTINE_BACKEND ucontext -#define CONFIG_OPEN_BY_HANDLE 1 -#define CONFIG_LINUX_MAGIC_H 1 -#define CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE 1 -#define CONFIG_HAS_ENVIRON 1 -#define CONFIG_CPUID_H 1 -#define CONFIG_VIRTIO_BLK_DATA_PLANE $(CONFIG_VIRTIO) -#define CONFIG_TRACE_NOP 1 -#define CONFIG_TRACE_FILE trace -#define CONFIG_TRACE_DEFAULT 1 diff --git a/contrib/qemu/coroutine-ucontext.c b/contrib/qemu/coroutine-ucontext.c deleted file mode 100644 index 4bf2cde279b..00000000000 --- a/contrib/qemu/coroutine-ucontext.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * ucontext coroutine initialization code - * - * Copyright (C) 2006  Anthony Liguori <anthony@codemonkey.ws> - * Copyright (C) 2011  Kevin Wolf <kwolf@redhat.com> - * - * 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.0 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/>. - */ - -/* XXX Is there a nicer way to disable glibc's stack check for longjmp? */ -#ifdef _FORTIFY_SOURCE -#undef _FORTIFY_SOURCE -#endif -#include <stdlib.h> -#include <setjmp.h> -#include <stdint.h> -#include <pthread.h> -#include <ucontext.h> -#include "qemu-common.h" -#include "block/coroutine_int.h" - -#ifdef CONFIG_VALGRIND_H -#include <valgrind/valgrind.h> -#endif - -typedef struct { -    Coroutine base; -    void *stack; -    sigjmp_buf env; - -#ifdef CONFIG_VALGRIND_H -    unsigned int valgrind_stack_id; -#endif - -} CoroutineUContext; - -/** - * Per-thread coroutine bookkeeping - */ -typedef struct { -    /** Currently executing coroutine */ -    Coroutine *current; - -    /** The default coroutine */ -    CoroutineUContext leader; -} CoroutineThreadState; - -static pthread_key_t thread_state_key; - -/* - * va_args to makecontext() must be type 'int', so passing - * the pointer we need may require several int args. This - * union is a quick hack to let us do that - */ -union cc_arg { -    void *p; -    int i[2]; -}; - -static CoroutineThreadState *coroutine_get_thread_state(void) -{ -    CoroutineThreadState *s = pthread_getspecific(thread_state_key); - -    if (!s) { -        s = g_malloc0(sizeof(*s)); -        s->current = &s->leader.base; -        pthread_setspecific(thread_state_key, s); -    } -    return s; -} - -static void qemu_coroutine_thread_cleanup(void *opaque) -{ -    CoroutineThreadState *s = opaque; - -    g_free(s); -} - -static void __attribute__((constructor)) coroutine_init(void) -{ -    int ret; - -    ret = pthread_key_create(&thread_state_key, qemu_coroutine_thread_cleanup); -    if (ret != 0) { -        fprintf(stderr, "unable to create leader key: %s\n", strerror(errno)); -        abort(); -    } -} - -static void coroutine_trampoline(int i0, int i1) -{ -    union cc_arg arg; -    CoroutineUContext *self; -    Coroutine *co; - -    arg.i[0] = i0; -    arg.i[1] = i1; -    self = arg.p; -    co = &self->base; - -    /* Initialize longjmp environment and switch back the caller */ -    if (!sigsetjmp(self->env, 0)) { -        siglongjmp(*(sigjmp_buf *)co->entry_arg, 1); -    } - -    while (true) { -        co->entry(co->entry_arg); -        qemu_coroutine_switch(co, co->caller, COROUTINE_TERMINATE); -    } -} - -Coroutine *qemu_coroutine_new(void) -{ -    const size_t stack_size = 1 << 20; -    CoroutineUContext *co; -    ucontext_t old_uc, uc; -    sigjmp_buf old_env; -    union cc_arg arg = {0}; - -    /* The ucontext functions preserve signal masks which incurs a -     * system call overhead.  sigsetjmp(buf, 0)/siglongjmp() does not -     * preserve signal masks but only works on the current stack. -     * Since we need a way to create and switch to a new stack, use -     * the ucontext functions for that but sigsetjmp()/siglongjmp() for -     * everything else. -     */ - -    if (getcontext(&uc) == -1) { -        abort(); -    } - -    co = g_malloc0(sizeof(*co)); -    co->stack = g_malloc(stack_size); -    co->base.entry_arg = &old_env; /* stash away our jmp_buf */ - -    uc.uc_link = &old_uc; -    uc.uc_stack.ss_sp = co->stack; -    uc.uc_stack.ss_size = stack_size; -    uc.uc_stack.ss_flags = 0; - -#ifdef CONFIG_VALGRIND_H -    co->valgrind_stack_id = -        VALGRIND_STACK_REGISTER(co->stack, co->stack + stack_size); -#endif - -    arg.p = co; - -    makecontext(&uc, (void (*)(void))coroutine_trampoline, -                2, arg.i[0], arg.i[1]); - -    /* swapcontext() in, siglongjmp() back out */ -    if (!sigsetjmp(old_env, 0)) { -        swapcontext(&old_uc, &uc); -    } -    return &co->base; -} - -#ifdef CONFIG_VALGRIND_H -#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE -/* Work around an unused variable in the valgrind.h macro... */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#endif -static inline void valgrind_stack_deregister(CoroutineUContext *co) -{ -    VALGRIND_STACK_DEREGISTER(co->valgrind_stack_id); -} -#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE -#pragma GCC diagnostic pop -#endif -#endif - -void qemu_coroutine_delete(Coroutine *co_) -{ -    CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_); - -#ifdef CONFIG_VALGRIND_H -    valgrind_stack_deregister(co); -#endif - -    g_free(co->stack); -    g_free(co); -} - -CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_, -                                      CoroutineAction action) -{ -    CoroutineUContext *from = DO_UPCAST(CoroutineUContext, base, from_); -    CoroutineUContext *to = DO_UPCAST(CoroutineUContext, base, to_); -    CoroutineThreadState *s = coroutine_get_thread_state(); -    int ret; - -    s->current = to_; - -    ret = sigsetjmp(from->env, 0); -    if (ret == 0) { -        siglongjmp(to->env, action); -    } -    return ret; -} - -Coroutine *qemu_coroutine_self(void) -{ -    CoroutineThreadState *s = coroutine_get_thread_state(); - -    return s->current; -} - -bool qemu_in_coroutine(void) -{ -    CoroutineThreadState *s = pthread_getspecific(thread_state_key); - -    return s && s->current->caller; -} diff --git a/contrib/qemu/include/block/aio.h b/contrib/qemu/include/block/aio.h deleted file mode 100644 index 183679374fa..00000000000 --- a/contrib/qemu/include/block/aio.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * QEMU aio implementation - * - * Copyright IBM, Corp. 2008 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2.  See - * the COPYING file in the top-level directory. - * - */ - -#ifndef QEMU_AIO_H -#define QEMU_AIO_H - -#include "qemu-common.h" -#include "qemu/queue.h" -#include "qemu/event_notifier.h" - -typedef struct BlockDriverAIOCB BlockDriverAIOCB; -typedef void BlockDriverCompletionFunc(void *opaque, int ret); - -typedef struct AIOCBInfo { -    void (*cancel)(BlockDriverAIOCB *acb); -    size_t aiocb_size; -} AIOCBInfo; - -struct BlockDriverAIOCB { -    const AIOCBInfo *aiocb_info; -    BlockDriverState *bs; -    BlockDriverCompletionFunc *cb; -    void *opaque; -}; - -void *qemu_aio_get(const AIOCBInfo *aiocb_info, BlockDriverState *bs, -                   BlockDriverCompletionFunc *cb, void *opaque); -void qemu_aio_release(void *p); - -typedef struct AioHandler AioHandler; -typedef void QEMUBHFunc(void *opaque); -typedef void IOHandler(void *opaque); - -typedef struct AioContext { -    GSource source; - -    /* The list of registered AIO handlers */ -    QLIST_HEAD(, AioHandler) aio_handlers; - -    /* This is a simple lock used to protect the aio_handlers list. -     * Specifically, it's used to ensure that no callbacks are removed while -     * we're walking and dispatching callbacks. -     */ -    int walking_handlers; - -    /* Anchor of the list of Bottom Halves belonging to the context */ -    struct QEMUBH *first_bh; - -    /* A simple lock used to protect the first_bh list, and ensure that -     * no callbacks are removed while we're walking and dispatching callbacks. -     */ -    int walking_bh; - -    /* Used for aio_notify.  */ -    EventNotifier notifier; - -    /* GPollFDs for aio_poll() */ -    GArray *pollfds; - -    /* Thread pool for performing work and receiving completion callbacks */ -    struct ThreadPool *thread_pool; -} AioContext; - -/* Returns 1 if there are still outstanding AIO requests; 0 otherwise */ -typedef int (AioFlushEventNotifierHandler)(EventNotifier *e); - -/** - * aio_context_new: Allocate a new AioContext. - * - * AioContext provide a mini event-loop that can be waited on synchronously. - * They also provide bottom halves, a service to execute a piece of code - * as soon as possible. - */ -AioContext *aio_context_new(void); - -/** - * aio_context_ref: - * @ctx: The AioContext to operate on. - * - * Add a reference to an AioContext. - */ -void aio_context_ref(AioContext *ctx); - -/** - * aio_context_unref: - * @ctx: The AioContext to operate on. - * - * Drop a reference to an AioContext. - */ -void aio_context_unref(AioContext *ctx); - -/** - * aio_bh_new: Allocate a new bottom half structure. - * - * Bottom halves are lightweight callbacks whose invocation is guaranteed - * to be wait-free, thread-safe and signal-safe.  The #QEMUBH structure - * is opaque and must be allocated prior to its use. - */ -QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque); - -/** - * aio_notify: Force processing of pending events. - * - * Similar to signaling a condition variable, aio_notify forces - * aio_wait to exit, so that the next call will re-examine pending events. - * The caller of aio_notify will usually call aio_wait again very soon, - * or go through another iteration of the GLib main loop.  Hence, aio_notify - * also has the side effect of recalculating the sets of file descriptors - * that the main loop waits for. - * - * Calling aio_notify is rarely necessary, because for example scheduling - * a bottom half calls it already. - */ -void aio_notify(AioContext *ctx); - -/** - * aio_bh_poll: Poll bottom halves for an AioContext. - * - * These are internal functions used by the QEMU main loop. - */ -int aio_bh_poll(AioContext *ctx); - -/** - * qemu_bh_schedule: Schedule a bottom half. - * - * Scheduling a bottom half interrupts the main loop and causes the - * execution of the callback that was passed to qemu_bh_new. - * - * Bottom halves that are scheduled from a bottom half handler are instantly - * invoked.  This can create an infinite loop if a bottom half handler - * schedules itself. - * - * @bh: The bottom half to be scheduled. - */ -void qemu_bh_schedule(QEMUBH *bh); - -/** - * qemu_bh_cancel: Cancel execution of a bottom half. - * - * Canceling execution of a bottom half undoes the effect of calls to - * qemu_bh_schedule without freeing its resources yet.  While cancellation - * itself is also wait-free and thread-safe, it can of course race with the - * loop that executes bottom halves unless you are holding the iothread - * mutex.  This makes it mostly useless if you are not holding the mutex. - * - * @bh: The bottom half to be canceled. - */ -void qemu_bh_cancel(QEMUBH *bh); - -/** - *qemu_bh_delete: Cancel execution of a bottom half and free its resources. - * - * Deleting a bottom half frees the memory that was allocated for it by - * qemu_bh_new.  It also implies canceling the bottom half if it was - * scheduled. - * - * @bh: The bottom half to be deleted. - */ -void qemu_bh_delete(QEMUBH *bh); - -/* Return whether there are any pending callbacks from the GSource - * attached to the AioContext. - * - * This is used internally in the implementation of the GSource. - */ -bool aio_pending(AioContext *ctx); - -/* Progress in completing AIO work to occur.  This can issue new pending - * aio as a result of executing I/O completion or bh callbacks. - * - * If there is no pending AIO operation or completion (bottom half), - * return false.  If there are pending AIO operations of bottom halves, - * return true. - * - * If there are no pending bottom halves, but there are pending AIO - * operations, it may not be possible to make any progress without - * blocking.  If @blocking is true, this function will wait until one - * or more AIO events have completed, to ensure something has moved - * before returning. - */ -bool aio_poll(AioContext *ctx, bool blocking); - -#ifdef CONFIG_POSIX -/* Returns 1 if there are still outstanding AIO requests; 0 otherwise */ -typedef int (AioFlushHandler)(void *opaque); - -/* Register a file descriptor and associated callbacks.  Behaves very similarly - * to qemu_set_fd_handler2.  Unlike qemu_set_fd_handler2, these callbacks will - * be invoked when using qemu_aio_wait(). - * - * Code that invokes AIO completion functions should rely on this function - * instead of qemu_set_fd_handler[2]. - */ -void aio_set_fd_handler(AioContext *ctx, -                        int fd, -                        IOHandler *io_read, -                        IOHandler *io_write, -                        AioFlushHandler *io_flush, -                        void *opaque); -#endif - -/* Register an event notifier and associated callbacks.  Behaves very similarly - * to event_notifier_set_handler.  Unlike event_notifier_set_handler, these callbacks - * will be invoked when using qemu_aio_wait(). - * - * Code that invokes AIO completion functions should rely on this function - * instead of event_notifier_set_handler. - */ -void aio_set_event_notifier(AioContext *ctx, -                            EventNotifier *notifier, -                            EventNotifierHandler *io_read, -                            AioFlushEventNotifierHandler *io_flush); - -/* Return a GSource that lets the main loop poll the file descriptors attached - * to this AioContext. - */ -GSource *aio_get_g_source(AioContext *ctx); - -/* Return the ThreadPool bound to this AioContext */ -struct ThreadPool *aio_get_thread_pool(AioContext *ctx); - -/* Functions to operate on the main QEMU AioContext.  */ - -bool qemu_aio_wait(void); -void qemu_aio_set_event_notifier(EventNotifier *notifier, -                                 EventNotifierHandler *io_read, -                                 AioFlushEventNotifierHandler *io_flush); - -#ifdef CONFIG_POSIX -void qemu_aio_set_fd_handler(int fd, -                             IOHandler *io_read, -                             IOHandler *io_write, -                             AioFlushHandler *io_flush, -                             void *opaque); -#endif - -#endif diff --git a/contrib/qemu/include/block/block.h b/contrib/qemu/include/block/block.h deleted file mode 100644 index b6b9014a9ce..00000000000 --- a/contrib/qemu/include/block/block.h +++ /dev/null @@ -1,443 +0,0 @@ -#ifndef BLOCK_H -#define BLOCK_H - -#include "block/aio.h" -#include "qemu-common.h" -#include "qemu/option.h" -#include "block/coroutine.h" -#include "qapi/qmp/qobject.h" -#include "qapi-types.h" - -/* block.c */ -typedef struct BlockDriver BlockDriver; -typedef struct BlockJob BlockJob; - -typedef struct BlockDriverInfo { -    /* in bytes, 0 if irrelevant */ -    int cluster_size; -    /* offset at which the VM state can be saved (0 if not possible) */ -    int64_t vm_state_offset; -    bool is_dirty; -} BlockDriverInfo; - -typedef struct BlockFragInfo { -    uint64_t allocated_clusters; -    uint64_t total_clusters; -    uint64_t fragmented_clusters; -    uint64_t compressed_clusters; -} BlockFragInfo; - -/* Callbacks for block device models */ -typedef struct BlockDevOps { -    /* -     * Runs when virtual media changed (monitor commands eject, change) -     * Argument load is true on load and false on eject. -     * Beware: doesn't run when a host device's physical media -     * changes.  Sure would be useful if it did. -     * Device models with removable media must implement this callback. -     */ -    void (*change_media_cb)(void *opaque, bool load); -    /* -     * Runs when an eject request is issued from the monitor, the tray -     * is closed, and the medium is locked. -     * Device models that do not implement is_medium_locked will not need -     * this callback.  Device models that can lock the medium or tray might -     * want to implement the callback and unlock the tray when "force" is -     * true, even if they do not support eject requests. -     */ -    void (*eject_request_cb)(void *opaque, bool force); -    /* -     * Is the virtual tray open? -     * Device models implement this only when the device has a tray. -     */ -    bool (*is_tray_open)(void *opaque); -    /* -     * Is the virtual medium locked into the device? -     * Device models implement this only when device has such a lock. -     */ -    bool (*is_medium_locked)(void *opaque); -    /* -     * Runs when the size changed (e.g. monitor command block_resize) -     */ -    void (*resize_cb)(void *opaque); -} BlockDevOps; - -#define BDRV_O_RDWR        0x0002 -#define BDRV_O_SNAPSHOT    0x0008 /* open the file read only and save writes in a snapshot */ -#define BDRV_O_NOCACHE     0x0020 /* do not use the host page cache */ -#define BDRV_O_CACHE_WB    0x0040 /* use write-back caching */ -#define BDRV_O_NATIVE_AIO  0x0080 /* use native AIO instead of the thread pool */ -#define BDRV_O_NO_BACKING  0x0100 /* don't open the backing file */ -#define BDRV_O_NO_FLUSH    0x0200 /* disable flushing on this disk */ -#define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */ -#define BDRV_O_INCOMING    0x0800  /* consistency hint for incoming migration */ -#define BDRV_O_CHECK       0x1000  /* open solely for consistency check */ -#define BDRV_O_ALLOW_RDWR  0x2000  /* allow reopen to change from r/o to r/w */ -#define BDRV_O_UNMAP       0x4000  /* execute guest UNMAP/TRIM operations */ - -#define BDRV_O_CACHE_MASK  (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH) - -#define BDRV_SECTOR_BITS   9 -#define BDRV_SECTOR_SIZE   (1ULL << BDRV_SECTOR_BITS) -#define BDRV_SECTOR_MASK   ~(BDRV_SECTOR_SIZE - 1) - -typedef enum { -    BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP -} BlockErrorAction; - -typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue; - -typedef struct BDRVReopenState { -    BlockDriverState *bs; -    int flags; -    void *opaque; -} BDRVReopenState; - - -void bdrv_iostatus_enable(BlockDriverState *bs); -void bdrv_iostatus_reset(BlockDriverState *bs); -void bdrv_iostatus_disable(BlockDriverState *bs); -bool bdrv_iostatus_is_enabled(const BlockDriverState *bs); -void bdrv_iostatus_set_err(BlockDriverState *bs, int error); -void bdrv_info_print(Monitor *mon, const QObject *data); -void bdrv_info(Monitor *mon, QObject **ret_data); -void bdrv_stats_print(Monitor *mon, const QObject *data); -void bdrv_info_stats(Monitor *mon, QObject **ret_data); - -/* disk I/O throttling */ -void bdrv_io_limits_enable(BlockDriverState *bs); -void bdrv_io_limits_disable(BlockDriverState *bs); -bool bdrv_io_limits_enabled(BlockDriverState *bs); - -void bdrv_init(void); -void bdrv_init_with_whitelist(void); -BlockDriver *bdrv_find_protocol(const char *filename, -                                bool allow_protocol_prefix); -BlockDriver *bdrv_find_format(const char *format_name); -BlockDriver *bdrv_find_whitelisted_format(const char *format_name, -                                          bool readonly); -int bdrv_create(BlockDriver *drv, const char* filename, -    QEMUOptionParameter *options); -int bdrv_create_file(const char* filename, QEMUOptionParameter *options); -BlockDriverState *bdrv_new(const char *device_name); -void bdrv_make_anon(BlockDriverState *bs); -void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old); -void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top); -void bdrv_delete(BlockDriverState *bs); -int bdrv_parse_cache_flags(const char *mode, int *flags); -int bdrv_parse_discard_flags(const char *mode, int *flags); -int bdrv_file_open(BlockDriverState **pbs, const char *filename, -                   QDict *options, int flags); -int bdrv_open_backing_file(BlockDriverState *bs, QDict *options); -int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, -              int flags, BlockDriver *drv); -BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue, -                                    BlockDriverState *bs, int flags); -int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp); -int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp); -int bdrv_reopen_prepare(BDRVReopenState *reopen_state, -                        BlockReopenQueue *queue, Error **errp); -void bdrv_reopen_commit(BDRVReopenState *reopen_state); -void bdrv_reopen_abort(BDRVReopenState *reopen_state); -void bdrv_close(BlockDriverState *bs); -void bdrv_add_close_notifier(BlockDriverState *bs, Notifier *notify); -int bdrv_attach_dev(BlockDriverState *bs, void *dev); -void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev); -void bdrv_detach_dev(BlockDriverState *bs, void *dev); -void *bdrv_get_attached_dev(BlockDriverState *bs); -void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, -                      void *opaque); -void bdrv_dev_eject_request(BlockDriverState *bs, bool force); -bool bdrv_dev_has_removable_media(BlockDriverState *bs); -bool bdrv_dev_is_tray_open(BlockDriverState *bs); -bool bdrv_dev_is_medium_locked(BlockDriverState *bs); -int bdrv_read(BlockDriverState *bs, int64_t sector_num, -              uint8_t *buf, int nb_sectors); -int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num, -                          uint8_t *buf, int nb_sectors); -int bdrv_write(BlockDriverState *bs, int64_t sector_num, -               const uint8_t *buf, int nb_sectors); -int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov); -int bdrv_pread(BlockDriverState *bs, int64_t offset, -               void *buf, int count); -int bdrv_pwrite(BlockDriverState *bs, int64_t offset, -                const void *buf, int count); -int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov); -int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, -    const void *buf, int count); -int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, -    int nb_sectors, QEMUIOVector *qiov); -int coroutine_fn bdrv_co_copy_on_readv(BlockDriverState *bs, -    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); -int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, -    int nb_sectors, QEMUIOVector *qiov); -/* - * Efficiently zero a region of the disk image.  Note that this is a regular - * I/O request like read or write and should have a reasonable size.  This - * function is not suitable for zeroing the entire image in a single request - * because it may allocate memory for the entire region. - */ -int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, -    int nb_sectors); -int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num, -    int nb_sectors, int *pnum); -int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, -                                            BlockDriverState *base, -                                            int64_t sector_num, -                                            int nb_sectors, int *pnum); -BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, -    const char *backing_file); -int bdrv_get_backing_file_depth(BlockDriverState *bs); -int bdrv_truncate(BlockDriverState *bs, int64_t offset); -int64_t bdrv_getlength(BlockDriverState *bs); -int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); -void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); -int bdrv_commit(BlockDriverState *bs); -int bdrv_commit_all(void); -int bdrv_change_backing_file(BlockDriverState *bs, -    const char *backing_file, const char *backing_fmt); -void bdrv_register(BlockDriver *bdrv); -int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top, -                           BlockDriverState *base); -BlockDriverState *bdrv_find_overlay(BlockDriverState *active, -                                    BlockDriverState *bs); -BlockDriverState *bdrv_find_base(BlockDriverState *bs); - - -typedef struct BdrvCheckResult { -    int corruptions; -    int leaks; -    int check_errors; -    int corruptions_fixed; -    int leaks_fixed; -    int64_t image_end_offset; -    BlockFragInfo bfi; -} BdrvCheckResult; - -typedef enum { -    BDRV_FIX_LEAKS    = 1, -    BDRV_FIX_ERRORS   = 2, -} BdrvCheckMode; - -int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix); - -/* async block I/O */ -typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector, -                                     int sector_num); -BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, -                                 QEMUIOVector *iov, int nb_sectors, -                                 BlockDriverCompletionFunc *cb, void *opaque); -BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, -                                  QEMUIOVector *iov, int nb_sectors, -                                  BlockDriverCompletionFunc *cb, void *opaque); -BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, -                                 BlockDriverCompletionFunc *cb, void *opaque); -BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs, -                                   int64_t sector_num, int nb_sectors, -                                   BlockDriverCompletionFunc *cb, void *opaque); -void bdrv_aio_cancel(BlockDriverAIOCB *acb); - -typedef struct BlockRequest { -    /* Fields to be filled by multiwrite caller */ -    int64_t sector; -    int nb_sectors; -    QEMUIOVector *qiov; -    BlockDriverCompletionFunc *cb; -    void *opaque; - -    /* Filled by multiwrite implementation */ -    int error; -} BlockRequest; - -int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, -    int num_reqs); - -/* sg packet commands */ -int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf); -BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, -        unsigned long int req, void *buf, -        BlockDriverCompletionFunc *cb, void *opaque); - -/* Invalidate any cached metadata used by image formats */ -void bdrv_invalidate_cache(BlockDriverState *bs); -void bdrv_invalidate_cache_all(void); - -void bdrv_clear_incoming_migration_all(void); - -/* Ensure contents are flushed to disk.  */ -int bdrv_flush(BlockDriverState *bs); -int coroutine_fn bdrv_co_flush(BlockDriverState *bs); -int bdrv_flush_all(void); -void bdrv_close_all(void); -void bdrv_drain_all(void); - -int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); -int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); -int bdrv_has_zero_init_1(BlockDriverState *bs); -int bdrv_has_zero_init(BlockDriverState *bs); -int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, -                      int *pnum); -int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base, -                            int64_t sector_num, int nb_sectors, int *pnum); - -void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error, -                       BlockdevOnError on_write_error); -BlockdevOnError bdrv_get_on_error(BlockDriverState *bs, bool is_read); -BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int error); -void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action, -                       bool is_read, int error); -int bdrv_is_read_only(BlockDriverState *bs); -int bdrv_is_sg(BlockDriverState *bs); -int bdrv_enable_write_cache(BlockDriverState *bs); -void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce); -int bdrv_is_inserted(BlockDriverState *bs); -int bdrv_media_changed(BlockDriverState *bs); -void bdrv_lock_medium(BlockDriverState *bs, bool locked); -void bdrv_eject(BlockDriverState *bs, bool eject_flag); -const char *bdrv_get_format_name(BlockDriverState *bs); -BlockDriverState *bdrv_find(const char *name); -BlockDriverState *bdrv_next(BlockDriverState *bs); -void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), -                  void *opaque); -int bdrv_is_encrypted(BlockDriverState *bs); -int bdrv_key_required(BlockDriverState *bs); -int bdrv_set_key(BlockDriverState *bs, const char *key); -int bdrv_query_missing_keys(void); -void bdrv_iterate_format(void (*it)(void *opaque, const char *name), -                         void *opaque); -const char *bdrv_get_device_name(BlockDriverState *bs); -int bdrv_get_flags(BlockDriverState *bs); -int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, -                          const uint8_t *buf, int nb_sectors); -int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi); -void bdrv_round_to_clusters(BlockDriverState *bs, -                            int64_t sector_num, int nb_sectors, -                            int64_t *cluster_sector_num, -                            int *cluster_nb_sectors); - -const char *bdrv_get_encrypted_filename(BlockDriverState *bs); -void bdrv_get_backing_filename(BlockDriverState *bs, -                               char *filename, int filename_size); -void bdrv_get_full_backing_filename(BlockDriverState *bs, -                                    char *dest, size_t sz); -int bdrv_is_snapshot(BlockDriverState *bs); - -int path_is_absolute(const char *path); -void path_combine(char *dest, int dest_size, -                  const char *base_path, -                  const char *filename); - -int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos); -int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, -                      int64_t pos, int size); - -int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, -                      int64_t pos, int size); - -void bdrv_img_create(const char *filename, const char *fmt, -                     const char *base_filename, const char *base_fmt, -                     char *options, uint64_t img_size, int flags, -                     Error **errp, bool quiet); - -void bdrv_set_buffer_alignment(BlockDriverState *bs, int align); -void *qemu_blockalign(BlockDriverState *bs, size_t size); -bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov); - -struct HBitmapIter; -void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity); -int bdrv_get_dirty(BlockDriverState *bs, int64_t sector); -void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors); -void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors); -void bdrv_dirty_iter_init(BlockDriverState *bs, struct HBitmapIter *hbi); -int64_t bdrv_get_dirty_count(BlockDriverState *bs); - -void bdrv_enable_copy_on_read(BlockDriverState *bs); -void bdrv_disable_copy_on_read(BlockDriverState *bs); - -void bdrv_set_in_use(BlockDriverState *bs, int in_use); -int bdrv_in_use(BlockDriverState *bs); - -#ifdef CONFIG_LINUX_AIO -int raw_get_aio_fd(BlockDriverState *bs); -#else -static inline int raw_get_aio_fd(BlockDriverState *bs) -{ -    return -ENOTSUP; -} -#endif - -enum BlockAcctType { -    BDRV_ACCT_READ, -    BDRV_ACCT_WRITE, -    BDRV_ACCT_FLUSH, -    BDRV_MAX_IOTYPE, -}; - -typedef struct BlockAcctCookie { -    int64_t bytes; -    int64_t start_time_ns; -    enum BlockAcctType type; -} BlockAcctCookie; - -void bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, -        int64_t bytes, enum BlockAcctType type); -void bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie); - -typedef enum { -    BLKDBG_L1_UPDATE, - -    BLKDBG_L1_GROW_ALLOC_TABLE, -    BLKDBG_L1_GROW_WRITE_TABLE, -    BLKDBG_L1_GROW_ACTIVATE_TABLE, - -    BLKDBG_L2_LOAD, -    BLKDBG_L2_UPDATE, -    BLKDBG_L2_UPDATE_COMPRESSED, -    BLKDBG_L2_ALLOC_COW_READ, -    BLKDBG_L2_ALLOC_WRITE, - -    BLKDBG_READ_AIO, -    BLKDBG_READ_BACKING_AIO, -    BLKDBG_READ_COMPRESSED, - -    BLKDBG_WRITE_AIO, -    BLKDBG_WRITE_COMPRESSED, - -    BLKDBG_VMSTATE_LOAD, -    BLKDBG_VMSTATE_SAVE, - -    BLKDBG_COW_READ, -    BLKDBG_COW_WRITE, - -    BLKDBG_REFTABLE_LOAD, -    BLKDBG_REFTABLE_GROW, - -    BLKDBG_REFBLOCK_LOAD, -    BLKDBG_REFBLOCK_UPDATE, -    BLKDBG_REFBLOCK_UPDATE_PART, -    BLKDBG_REFBLOCK_ALLOC, -    BLKDBG_REFBLOCK_ALLOC_HOOKUP, -    BLKDBG_REFBLOCK_ALLOC_WRITE, -    BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS, -    BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE, -    BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE, - -    BLKDBG_CLUSTER_ALLOC, -    BLKDBG_CLUSTER_ALLOC_BYTES, -    BLKDBG_CLUSTER_FREE, - -    BLKDBG_FLUSH_TO_OS, -    BLKDBG_FLUSH_TO_DISK, - -    BLKDBG_EVENT_MAX, -} BlkDebugEvent; - -#define BLKDBG_EVENT(bs, evt) bdrv_debug_event(bs, evt) -void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event); - -int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, -                           const char *tag); -int bdrv_debug_resume(BlockDriverState *bs, const char *tag); -bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); - -#endif diff --git a/contrib/qemu/include/block/block_int.h b/contrib/qemu/include/block/block_int.h deleted file mode 100644 index c6ac871e210..00000000000 --- a/contrib/qemu/include/block/block_int.h +++ /dev/null @@ -1,421 +0,0 @@ -/* - * QEMU System Emulator block driver - * - * Copyright (c) 2003 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef BLOCK_INT_H -#define BLOCK_INT_H - -#include "block/block.h" -#include "qemu/option.h" -#include "qemu/queue.h" -#include "block/coroutine.h" -#include "qemu/timer.h" -#include "qapi-types.h" -#include "qapi/qmp/qerror.h" -#include "monitor/monitor.h" -#include "qemu/hbitmap.h" -#include "block/snapshot.h" - -#define BLOCK_FLAG_ENCRYPT          1 -#define BLOCK_FLAG_COMPAT6          4 -#define BLOCK_FLAG_LAZY_REFCOUNTS   8 - -#define BLOCK_IO_LIMIT_READ     0 -#define BLOCK_IO_LIMIT_WRITE    1 -#define BLOCK_IO_LIMIT_TOTAL    2 - -#define BLOCK_IO_SLICE_TIME     100000000 -#define NANOSECONDS_PER_SECOND  1000000000.0 - -#define BLOCK_OPT_SIZE              "size" -#define BLOCK_OPT_ENCRYPT           "encryption" -#define BLOCK_OPT_COMPAT6           "compat6" -#define BLOCK_OPT_BACKING_FILE      "backing_file" -#define BLOCK_OPT_BACKING_FMT       "backing_fmt" -#define BLOCK_OPT_CLUSTER_SIZE      "cluster_size" -#define BLOCK_OPT_TABLE_SIZE        "table_size" -#define BLOCK_OPT_PREALLOC          "preallocation" -#define BLOCK_OPT_SUBFMT            "subformat" -#define BLOCK_OPT_COMPAT_LEVEL      "compat" -#define BLOCK_OPT_LAZY_REFCOUNTS    "lazy_refcounts" -#define BLOCK_OPT_ADAPTER_TYPE      "adapter_type" - -typedef struct BdrvTrackedRequest { -    BlockDriverState *bs; -    int64_t sector_num; -    int nb_sectors; -    bool is_write; -    QLIST_ENTRY(BdrvTrackedRequest) list; -    Coroutine *co; /* owner, used for deadlock detection */ -    CoQueue wait_queue; /* coroutines blocked on this request */ -} BdrvTrackedRequest; - - -typedef struct BlockIOLimit { -    int64_t bps[3]; -    int64_t iops[3]; -} BlockIOLimit; - -typedef struct BlockIOBaseValue { -    uint64_t bytes[2]; -    uint64_t ios[2]; -} BlockIOBaseValue; - -struct BlockDriver { -    const char *format_name; -    int instance_size; -    int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename); -    int (*bdrv_probe_device)(const char *filename); - -    /* Any driver implementing this callback is expected to be able to handle -     * NULL file names in its .bdrv_open() implementation */ -    void (*bdrv_parse_filename)(const char *filename, QDict *options, Error **errp); - -    /* For handling image reopen for split or non-split files */ -    int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state, -                               BlockReopenQueue *queue, Error **errp); -    void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state); -    void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state); - -    int (*bdrv_open)(BlockDriverState *bs, QDict *options, int flags); -    int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags); -    int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num, -                     uint8_t *buf, int nb_sectors); -    int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num, -                      const uint8_t *buf, int nb_sectors); -    void (*bdrv_close)(BlockDriverState *bs); -    void (*bdrv_rebind)(BlockDriverState *bs); -    int (*bdrv_create)(const char *filename, QEMUOptionParameter *options); -    int (*bdrv_set_key)(BlockDriverState *bs, const char *key); -    int (*bdrv_make_empty)(BlockDriverState *bs); -    /* aio */ -    BlockDriverAIOCB *(*bdrv_aio_readv)(BlockDriverState *bs, -        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, -        BlockDriverCompletionFunc *cb, void *opaque); -    BlockDriverAIOCB *(*bdrv_aio_writev)(BlockDriverState *bs, -        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, -        BlockDriverCompletionFunc *cb, void *opaque); -    BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs, -        BlockDriverCompletionFunc *cb, void *opaque); -    BlockDriverAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors, -        BlockDriverCompletionFunc *cb, void *opaque); - -    int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); -    int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); -    /* -     * Efficiently zero a region of the disk image.  Typically an image format -     * would use a compact metadata representation to implement this.  This -     * function pointer may be NULL and .bdrv_co_writev() will be called -     * instead. -     */ -    int coroutine_fn (*bdrv_co_write_zeroes)(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors); -    int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors); -    int coroutine_fn (*bdrv_co_is_allocated)(BlockDriverState *bs, -        int64_t sector_num, int nb_sectors, int *pnum); - -    /* -     * Invalidate any cached meta-data. -     */ -    void (*bdrv_invalidate_cache)(BlockDriverState *bs); - -    /* -     * Flushes all data that was already written to the OS all the way down to -     * the disk (for example raw-posix calls fsync()). -     */ -    int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs); - -    /* -     * Flushes all internal caches to the OS. The data may still sit in a -     * writeback cache of the host OS, but it will survive a crash of the qemu -     * process. -     */ -    int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs); - -    const char *protocol_name; -    int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset); -    int64_t (*bdrv_getlength)(BlockDriverState *bs); -    int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs); -    int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num, -                                 const uint8_t *buf, int nb_sectors); - -    int (*bdrv_snapshot_create)(BlockDriverState *bs, -                                QEMUSnapshotInfo *sn_info); -    int (*bdrv_snapshot_goto)(BlockDriverState *bs, -                              const char *snapshot_id); -    int (*bdrv_snapshot_delete)(BlockDriverState *bs, const char *snapshot_id); -    int (*bdrv_snapshot_list)(BlockDriverState *bs, -                              QEMUSnapshotInfo **psn_info); -    int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs, -                                  const char *snapshot_name); -    int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi); - -    int (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov, -                             int64_t pos); -    int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf, -                             int64_t pos, int size); - -    int (*bdrv_change_backing_file)(BlockDriverState *bs, -        const char *backing_file, const char *backing_fmt); - -    /* removable device specific */ -    int (*bdrv_is_inserted)(BlockDriverState *bs); -    int (*bdrv_media_changed)(BlockDriverState *bs); -    void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag); -    void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked); - -    /* to control generic scsi devices */ -    int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf); -    BlockDriverAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs, -        unsigned long int req, void *buf, -        BlockDriverCompletionFunc *cb, void *opaque); - -    /* List of options for creating images, terminated by name == NULL */ -    QEMUOptionParameter *create_options; - - -    /* -     * Returns 0 for completed check, -errno for internal errors. -     * The check results are stored in result. -     */ -    int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result, -        BdrvCheckMode fix); - -    void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event); - -    /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */ -    int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event, -        const char *tag); -    int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag); -    bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag); - -    /* -     * Returns 1 if newly created images are guaranteed to contain only -     * zeros, 0 otherwise. -     */ -    int (*bdrv_has_zero_init)(BlockDriverState *bs); - -    QLIST_ENTRY(BlockDriver) list; -}; - -/* - * Note: the function bdrv_append() copies and swaps contents of - * BlockDriverStates, so if you add new fields to this struct, please - * inspect bdrv_append() to determine if the new fields need to be - * copied as well. - */ -struct BlockDriverState { -    int64_t total_sectors; /* if we are reading a disk image, give its -                              size in sectors */ -    int read_only; /* if true, the media is read only */ -    int open_flags; /* flags used to open the file, re-used for re-open */ -    int encrypted; /* if true, the media is encrypted */ -    int valid_key; /* if true, a valid encryption key has been set */ -    int sg;        /* if true, the device is a /dev/sg* */ -    int copy_on_read; /* if true, copy read backing sectors into image -                         note this is a reference count */ - -    BlockDriver *drv; /* NULL means no media */ -    void *opaque; - -    void *dev;                  /* attached device model, if any */ -    /* TODO change to DeviceState when all users are qdevified */ -    const BlockDevOps *dev_ops; -    void *dev_opaque; - -    char filename[1024]; -    char backing_file[1024]; /* if non zero, the image is a diff of -                                this file image */ -    char backing_format[16]; /* if non-zero and backing_file exists */ -    int is_temporary; - -    BlockDriverState *backing_hd; -    BlockDriverState *file; - -    NotifierList close_notifiers; - -    /* Callback before write request is processed */ -    NotifierWithReturnList before_write_notifiers; - -    /* number of in-flight copy-on-read requests */ -    unsigned int copy_on_read_in_flight; - -    /* the time for latest disk I/O */ -    int64_t slice_start; -    int64_t slice_end; -    BlockIOLimit io_limits; -    BlockIOBaseValue slice_submitted; -    CoQueue      throttled_reqs; -    QEMUTimer    *block_timer; -    bool         io_limits_enabled; - -    /* I/O stats (display with "info blockstats"). */ -    uint64_t nr_bytes[BDRV_MAX_IOTYPE]; -    uint64_t nr_ops[BDRV_MAX_IOTYPE]; -    uint64_t total_time_ns[BDRV_MAX_IOTYPE]; -    uint64_t wr_highest_sector; - -    /* Whether the disk can expand beyond total_sectors */ -    int growable; - -    /* the memory alignment required for the buffers handled by this driver */ -    int buffer_alignment; - -    /* do we need to tell the quest if we have a volatile write cache? */ -    int enable_write_cache; - -    /* NOTE: the following infos are only hints for real hardware -       drivers. They are not used by the block driver */ -    BlockdevOnError on_read_error, on_write_error; -    bool iostatus_enabled; -    BlockDeviceIoStatus iostatus; -    char device_name[32]; -    HBitmap *dirty_bitmap; -    int in_use; /* users other than guest access, eg. block migration */ -    QTAILQ_ENTRY(BlockDriverState) list; - -    QLIST_HEAD(, BdrvTrackedRequest) tracked_requests; - -    /* long-running background operation */ -    BlockJob *job; - -    QDict *options; -}; - -int get_tmp_filename(char *filename, int size); - -void bdrv_set_io_limits(BlockDriverState *bs, -                        BlockIOLimit *io_limits); - -/** - * bdrv_add_before_write_notifier: - * - * Register a callback that is invoked before write requests are processed but - * after any throttling or waiting for overlapping requests. - */ -void bdrv_add_before_write_notifier(BlockDriverState *bs, -                                    NotifierWithReturn *notifier); - -/** - * bdrv_get_aio_context: - * - * Returns: the currently bound #AioContext - */ -AioContext *bdrv_get_aio_context(BlockDriverState *bs); - -#ifdef _WIN32 -int is_windows_drive(const char *filename); -#endif -void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv, -                               enum MonitorEvent ev, -                               BlockErrorAction action, bool is_read); - -/** - * stream_start: - * @bs: Block device to operate on. - * @base: Block device that will become the new base, or %NULL to - * flatten the whole backing file chain onto @bs. - * @base_id: The file name that will be written to @bs as the new - * backing file if the job completes.  Ignored if @base is %NULL. - * @speed: The maximum speed, in bytes per second, or 0 for unlimited. - * @on_error: The action to take upon error. - * @cb: Completion function for the job. - * @opaque: Opaque pointer value passed to @cb. - * @errp: Error object. - * - * Start a streaming operation on @bs.  Clusters that are unallocated - * in @bs, but allocated in any image between @base and @bs (both - * exclusive) will be written to @bs.  At the end of a successful - * streaming job, the backing file of @bs will be changed to - * @base_id in the written image and to @base in the live BlockDriverState. - */ -void stream_start(BlockDriverState *bs, BlockDriverState *base, -                  const char *base_id, int64_t speed, BlockdevOnError on_error, -                  BlockDriverCompletionFunc *cb, -                  void *opaque, Error **errp); - -/** - * commit_start: - * @bs: Top Block device - * @base: Block device that will be written into, and become the new top - * @speed: The maximum speed, in bytes per second, or 0 for unlimited. - * @on_error: The action to take upon error. - * @cb: Completion function for the job. - * @opaque: Opaque pointer value passed to @cb. - * @errp: Error object. - * - */ -void commit_start(BlockDriverState *bs, BlockDriverState *base, -                 BlockDriverState *top, int64_t speed, -                 BlockdevOnError on_error, BlockDriverCompletionFunc *cb, -                 void *opaque, Error **errp); - -/* - * mirror_start: - * @bs: Block device to operate on. - * @target: Block device to write to. - * @speed: The maximum speed, in bytes per second, or 0 for unlimited. - * @granularity: The chosen granularity for the dirty bitmap. - * @buf_size: The amount of data that can be in flight at one time. - * @mode: Whether to collapse all images in the chain to the target. - * @on_source_error: The action to take upon error reading from the source. - * @on_target_error: The action to take upon error writing to the target. - * @cb: Completion function for the job. - * @opaque: Opaque pointer value passed to @cb. - * @errp: Error object. - * - * Start a mirroring operation on @bs.  Clusters that are allocated - * in @bs will be written to @bs until the job is cancelled or - * manually completed.  At the end of a successful mirroring job, - * @bs will be switched to read from @target. - */ -void mirror_start(BlockDriverState *bs, BlockDriverState *target, -                  int64_t speed, int64_t granularity, int64_t buf_size, -                  MirrorSyncMode mode, BlockdevOnError on_source_error, -                  BlockdevOnError on_target_error, -                  BlockDriverCompletionFunc *cb, -                  void *opaque, Error **errp); - -/* - * backup_start: - * @bs: Block device to operate on. - * @target: Block device to write to. - * @speed: The maximum speed, in bytes per second, or 0 for unlimited. - * @on_source_error: The action to take upon error reading from the source. - * @on_target_error: The action to take upon error writing to the target. - * @cb: Completion function for the job. - * @opaque: Opaque pointer value passed to @cb. - * - * Start a backup operation on @bs.  Clusters in @bs are written to @target - * until the job is cancelled or manually completed. - */ -void backup_start(BlockDriverState *bs, BlockDriverState *target, -                  int64_t speed, BlockdevOnError on_source_error, -                  BlockdevOnError on_target_error, -                  BlockDriverCompletionFunc *cb, void *opaque, -                  Error **errp); - -#endif /* BLOCK_INT_H */ diff --git a/contrib/qemu/include/block/blockjob.h b/contrib/qemu/include/block/blockjob.h deleted file mode 100644 index c290d07bba0..00000000000 --- a/contrib/qemu/include/block/blockjob.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Declarations for long-running block device operations - * - * Copyright (c) 2011 IBM Corp. - * Copyright (c) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef BLOCKJOB_H -#define BLOCKJOB_H 1 - -#include "block/block.h" - -/** - * BlockJobType: - * - * A class type for block job objects. - */ -typedef struct BlockJobType { -    /** Derived BlockJob struct size */ -    size_t instance_size; - -    /** String describing the operation, part of query-block-jobs QMP API */ -    const char *job_type; - -    /** Optional callback for job types that support setting a speed limit */ -    void (*set_speed)(BlockJob *job, int64_t speed, Error **errp); - -    /** Optional callback for job types that need to forward I/O status reset */ -    void (*iostatus_reset)(BlockJob *job); - -    /** -     * Optional callback for job types whose completion must be triggered -     * manually. -     */ -    void (*complete)(BlockJob *job, Error **errp); -} BlockJobType; - -/** - * BlockJob: - * - * Long-running operation on a BlockDriverState. - */ -struct BlockJob { -    /** The job type, including the job vtable.  */ -    const BlockJobType *job_type; - -    /** The block device on which the job is operating.  */ -    BlockDriverState *bs; - -    /** -     * The coroutine that executes the job.  If not NULL, it is -     * reentered when busy is false and the job is cancelled. -     */ -    Coroutine *co; - -    /** -     * Set to true if the job should cancel itself.  The flag must -     * always be tested just before toggling the busy flag from false -     * to true.  After a job has been cancelled, it should only yield -     * if #qemu_aio_wait will ("sooner or later") reenter the coroutine. -     */ -    bool cancelled; - -    /** -     * Set to true if the job is either paused, or will pause itself -     * as soon as possible (if busy == true). -     */ -    bool paused; - -    /** -     * Set to false by the job while it is in a quiescent state, where -     * no I/O is pending and the job has yielded on any condition -     * that is not detected by #qemu_aio_wait, such as a timer. -     */ -    bool busy; - -    /** Status that is published by the query-block-jobs QMP API */ -    BlockDeviceIoStatus iostatus; - -    /** Offset that is published by the query-block-jobs QMP API */ -    int64_t offset; - -    /** Length that is published by the query-block-jobs QMP API */ -    int64_t len; - -    /** Speed that was set with @block_job_set_speed.  */ -    int64_t speed; - -    /** The completion function that will be called when the job completes.  */ -    BlockDriverCompletionFunc *cb; - -    /** The opaque value that is passed to the completion function.  */ -    void *opaque; -}; - -/** - * block_job_create: - * @job_type: The class object for the newly-created job. - * @bs: The block - * @speed: The maximum speed, in bytes per second, or 0 for unlimited. - * @cb: Completion function for the job. - * @opaque: Opaque pointer value passed to @cb. - * @errp: Error object. - * - * Create a new long-running block device job and return it.  The job - * will call @cb asynchronously when the job completes.  Note that - * @bs may have been closed at the time the @cb it is called.  If - * this is the case, the job may be reported as either cancelled or - * completed. - * - * This function is not part of the public job interface; it should be - * called from a wrapper that is specific to the job type. - */ -void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs, -                       int64_t speed, BlockDriverCompletionFunc *cb, -                       void *opaque, Error **errp); - -/** - * block_job_sleep_ns: - * @job: The job that calls the function. - * @clock: The clock to sleep on. - * @ns: How many nanoseconds to stop for. - * - * Put the job to sleep (assuming that it wasn't canceled) for @ns - * nanoseconds.  Canceling the job will interrupt the wait immediately. - */ -void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns); - -/** - * block_job_completed: - * @job: The job being completed. - * @ret: The status code. - * - * Call the completion function that was registered at creation time, and - * free @job. - */ -void block_job_completed(BlockJob *job, int ret); - -/** - * block_job_set_speed: - * @job: The job to set the speed for. - * @speed: The new value - * @errp: Error object. - * - * Set a rate-limiting parameter for the job; the actual meaning may - * vary depending on the job type. - */ -void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp); - -/** - * block_job_cancel: - * @job: The job to be canceled. - * - * Asynchronously cancel the specified job. - */ -void block_job_cancel(BlockJob *job); - -/** - * block_job_complete: - * @job: The job to be completed. - * @errp: Error object. - * - * Asynchronously complete the specified job. - */ -void block_job_complete(BlockJob *job, Error **errp); - -/** - * block_job_is_cancelled: - * @job: The job being queried. - * - * Returns whether the job is scheduled for cancellation. - */ -bool block_job_is_cancelled(BlockJob *job); - -/** - * block_job_query: - * @job: The job to get information about. - * - * Return information about a job. - */ -BlockJobInfo *block_job_query(BlockJob *job); - -/** - * block_job_pause: - * @job: The job to be paused. - * - * Asynchronously pause the specified job. - */ -void block_job_pause(BlockJob *job); - -/** - * block_job_resume: - * @job: The job to be resumed. - * - * Resume the specified job. - */ -void block_job_resume(BlockJob *job); - -/** - * qobject_from_block_job: - * @job: The job whose information is requested. - * - * Return a QDict corresponding to @job's query-block-jobs entry. - */ -QObject *qobject_from_block_job(BlockJob *job); - -/** - * block_job_ready: - * @job: The job which is now ready to complete. - * - * Send a BLOCK_JOB_READY event for the specified job. - */ -void block_job_ready(BlockJob *job); - -/** - * block_job_is_paused: - * @job: The job being queried. - * - * Returns whether the job is currently paused, or will pause - * as soon as it reaches a sleeping point. - */ -bool block_job_is_paused(BlockJob *job); - -/** - * block_job_cancel_sync: - * @job: The job to be canceled. - * - * Synchronously cancel the job.  The completion callback is called - * before the function returns.  The job may actually complete - * instead of canceling itself; the circumstances under which this - * happens depend on the kind of job that is active. - * - * Returns the return value from the job if the job actually completed - * during the call, or -ECANCELED if it was canceled. - */ -int block_job_cancel_sync(BlockJob *job); - -/** - * block_job_iostatus_reset: - * @job: The job whose I/O status should be reset. - * - * Reset I/O status on @job and on BlockDriverState objects it uses, - * other than job->bs. - */ -void block_job_iostatus_reset(BlockJob *job); - -/** - * block_job_error_action: - * @job: The job to signal an error for. - * @bs: The block device on which to set an I/O error. - * @on_err: The error action setting. - * @is_read: Whether the operation was a read. - * @error: The error that was reported. - * - * Report an I/O error for a block job and possibly stop the VM.  Return the - * action that was selected based on @on_err and @error. - */ -BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs, -                                        BlockdevOnError on_err, -                                        int is_read, int error); -#endif diff --git a/contrib/qemu/include/block/coroutine.h b/contrib/qemu/include/block/coroutine.h deleted file mode 100644 index 377805a3b08..00000000000 --- a/contrib/qemu/include/block/coroutine.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - * QEMU coroutine implementation - * - * Copyright IBM, Corp. 2011 - * - * Authors: - *  Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com> - *  Kevin Wolf         <kwolf@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef QEMU_COROUTINE_H -#define QEMU_COROUTINE_H - -#include <stdbool.h> -#include "qemu/queue.h" -#include "qemu/timer.h" - -/** - * Coroutines are a mechanism for stack switching and can be used for - * cooperative userspace threading.  These functions provide a simple but - * useful flavor of coroutines that is suitable for writing sequential code, - * rather than callbacks, for operations that need to give up control while - * waiting for events to complete. - * - * These functions are re-entrant and may be used outside the global mutex. - */ - -/** - * Mark a function that executes in coroutine context - * - * Functions that execute in coroutine context cannot be called directly from - * normal functions.  In the future it would be nice to enable compiler or - * static checker support for catching such errors.  This annotation might make - * it possible and in the meantime it serves as documentation. - * - * For example: - * - *   static void coroutine_fn foo(void) { - *       .... - *   } - */ -#define coroutine_fn - -typedef struct Coroutine Coroutine; - -/** - * Coroutine entry point - * - * When the coroutine is entered for the first time, opaque is passed in as an - * argument. - * - * When this function returns, the coroutine is destroyed automatically and - * execution continues in the caller who last entered the coroutine. - */ -typedef void coroutine_fn CoroutineEntry(void *opaque); - -/** - * Create a new coroutine - * - * Use qemu_coroutine_enter() to actually transfer control to the coroutine. - */ -Coroutine *qemu_coroutine_create(CoroutineEntry *entry); - -/** - * Transfer control to a coroutine - * - * The opaque argument is passed as the argument to the entry point when - * entering the coroutine for the first time.  It is subsequently ignored. - */ -void qemu_coroutine_enter(Coroutine *coroutine, void *opaque); - -/** - * Transfer control back to a coroutine's caller - * - * This function does not return until the coroutine is re-entered using - * qemu_coroutine_enter(). - */ -void coroutine_fn qemu_coroutine_yield(void); - -/** - * Get the currently executing coroutine - */ -Coroutine *coroutine_fn qemu_coroutine_self(void); - -/** - * Return whether or not currently inside a coroutine - * - * This can be used to write functions that work both when in coroutine context - * and when not in coroutine context.  Note that such functions cannot use the - * coroutine_fn annotation since they work outside coroutine context. - */ -bool qemu_in_coroutine(void); - - - -/** - * CoQueues are a mechanism to queue coroutines in order to continue executing - * them later. They provide the fundamental primitives on which coroutine locks - * are built. - */ -typedef struct CoQueue { -    QTAILQ_HEAD(, Coroutine) entries; -    AioContext *ctx; -} CoQueue; - -/** - * Initialise a CoQueue. This must be called before any other operation is used - * on the CoQueue. - */ -void qemu_co_queue_init(CoQueue *queue); - -/** - * Adds the current coroutine to the CoQueue and transfers control to the - * caller of the coroutine. - */ -void coroutine_fn qemu_co_queue_wait(CoQueue *queue); - -/** - * Adds the current coroutine to the head of the CoQueue and transfers control to the - * caller of the coroutine. - */ -void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue); - -/** - * Restarts the next coroutine in the CoQueue and removes it from the queue. - * - * Returns true if a coroutine was restarted, false if the queue is empty. - */ -bool qemu_co_queue_next(CoQueue *queue); - -/** - * Restarts all coroutines in the CoQueue and leaves the queue empty. - */ -void qemu_co_queue_restart_all(CoQueue *queue); - -/** - * Checks if the CoQueue is empty. - */ -bool qemu_co_queue_empty(CoQueue *queue); - - -/** - * Provides a mutex that can be used to synchronise coroutines - */ -typedef struct CoMutex { -    bool locked; -    CoQueue queue; -} CoMutex; - -/** - * Initialises a CoMutex. This must be called before any other operation is used - * on the CoMutex. - */ -void qemu_co_mutex_init(CoMutex *mutex); - -/** - * Locks the mutex. If the lock cannot be taken immediately, control is - * transferred to the caller of the current coroutine. - */ -void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex); - -/** - * Unlocks the mutex and schedules the next coroutine that was waiting for this - * lock to be run. - */ -void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex); - -typedef struct CoRwlock { -    bool writer; -    int reader; -    CoQueue queue; -} CoRwlock; - -/** - * Initialises a CoRwlock. This must be called before any other operation - * is used on the CoRwlock - */ -void qemu_co_rwlock_init(CoRwlock *lock); - -/** - * Read locks the CoRwlock. If the lock cannot be taken immediately because - * of a parallel writer, control is transferred to the caller of the current - * coroutine. - */ -void qemu_co_rwlock_rdlock(CoRwlock *lock); - -/** - * Write Locks the mutex. If the lock cannot be taken immediately because - * of a parallel reader, control is transferred to the caller of the current - * coroutine. - */ -void qemu_co_rwlock_wrlock(CoRwlock *lock); - -/** - * Unlocks the read/write lock and schedules the next coroutine that was - * waiting for this lock to be run. - */ -void qemu_co_rwlock_unlock(CoRwlock *lock); - -/** - * Yield the coroutine for a given duration - * - * Note this function uses timers and hence only works when a main loop is in - * use.  See main-loop.h and do not use from qemu-tool programs. - */ -void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns); - -/** - * Yield until a file descriptor becomes readable - * - * Note that this function clobbers the handlers for the file descriptor. - */ -void coroutine_fn yield_until_fd_readable(int fd); -#endif /* QEMU_COROUTINE_H */ diff --git a/contrib/qemu/include/block/coroutine_int.h b/contrib/qemu/include/block/coroutine_int.h deleted file mode 100644 index f133d65af86..00000000000 --- a/contrib/qemu/include/block/coroutine_int.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Coroutine internals - * - * Copyright (c) 2011 Kevin Wolf <kwolf@redhat.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef QEMU_COROUTINE_INT_H -#define QEMU_COROUTINE_INT_H - -#include "qemu/queue.h" -#include "block/coroutine.h" - -typedef enum { -    COROUTINE_YIELD = 1, -    COROUTINE_TERMINATE = 2, -} CoroutineAction; - -struct Coroutine { -    CoroutineEntry *entry; -    void *entry_arg; -    Coroutine *caller; -    QSLIST_ENTRY(Coroutine) pool_next; - -    /* Coroutines that should be woken up when we yield or terminate */ -    QTAILQ_HEAD(, Coroutine) co_queue_wakeup; -    QTAILQ_ENTRY(Coroutine) co_queue_next; -}; - -Coroutine *qemu_coroutine_new(void); -void qemu_coroutine_delete(Coroutine *co); -CoroutineAction qemu_coroutine_switch(Coroutine *from, Coroutine *to, -                                      CoroutineAction action); -void coroutine_fn qemu_co_queue_run_restart(Coroutine *co); - -#endif diff --git a/contrib/qemu/include/block/snapshot.h b/contrib/qemu/include/block/snapshot.h deleted file mode 100644 index eaf61f0326e..00000000000 --- a/contrib/qemu/include/block/snapshot.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Block layer snapshot related functions - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef SNAPSHOT_H -#define SNAPSHOT_H - -#include "qemu-common.h" - -typedef struct QEMUSnapshotInfo { -    char id_str[128]; /* unique snapshot id */ -    /* the following fields are informative. They are not needed for -       the consistency of the snapshot */ -    char name[256]; /* user chosen name */ -    uint64_t vm_state_size; /* VM state info size */ -    uint32_t date_sec; /* UTC date of the snapshot */ -    uint32_t date_nsec; -    uint64_t vm_clock_nsec; /* VM clock relative to boot */ -} QEMUSnapshotInfo; - -int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, -                       const char *name); -int bdrv_can_snapshot(BlockDriverState *bs); -int bdrv_snapshot_create(BlockDriverState *bs, -                         QEMUSnapshotInfo *sn_info); -int bdrv_snapshot_goto(BlockDriverState *bs, -                       const char *snapshot_id); -int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id); -int bdrv_snapshot_list(BlockDriverState *bs, -                       QEMUSnapshotInfo **psn_info); -int bdrv_snapshot_load_tmp(BlockDriverState *bs, -                           const char *snapshot_name); -#endif diff --git a/contrib/qemu/include/config.h b/contrib/qemu/include/config.h deleted file mode 100644 index e20f78696a1..00000000000 --- a/contrib/qemu/include/config.h +++ /dev/null @@ -1,2 +0,0 @@ -#include "config-host.h" -#include "config-target.h" diff --git a/contrib/qemu/include/exec/cpu-common.h b/contrib/qemu/include/exec/cpu-common.h deleted file mode 100644 index e4996e19c32..00000000000 --- a/contrib/qemu/include/exec/cpu-common.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef CPU_COMMON_H -#define CPU_COMMON_H 1 - -/* CPU interfaces that are target independent.  */ - -#ifndef CONFIG_USER_ONLY -#include "exec/hwaddr.h" -#endif - -#ifndef NEED_CPU_H -#include "exec/poison.h" -#endif - -#include "qemu/bswap.h" -#include "qemu/queue.h" - -/** - * CPUListState: - * @cpu_fprintf: Print function. - * @file: File to print to using @cpu_fprint. - * - * State commonly used for iterating over CPU models. - */ -typedef struct CPUListState { -    fprintf_function cpu_fprintf; -    FILE *file; -} CPUListState; - -#if !defined(CONFIG_USER_ONLY) - -enum device_endian { -    DEVICE_NATIVE_ENDIAN, -    DEVICE_BIG_ENDIAN, -    DEVICE_LITTLE_ENDIAN, -}; - -/* address in the RAM (different from a physical address) */ -#if defined(CONFIG_XEN_BACKEND) -typedef uint64_t ram_addr_t; -#  define RAM_ADDR_MAX UINT64_MAX -#  define RAM_ADDR_FMT "%" PRIx64 -#else -typedef uintptr_t ram_addr_t; -#  define RAM_ADDR_MAX UINTPTR_MAX -#  define RAM_ADDR_FMT "%" PRIxPTR -#endif - -/* memory API */ - -typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value); -typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr); - -void qemu_ram_remap(ram_addr_t addr, ram_addr_t length); -/* This should not be used by devices.  */ -MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr); -void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev); - -void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf, -                            int len, int is_write); -static inline void cpu_physical_memory_read(hwaddr addr, -                                            void *buf, int len) -{ -    cpu_physical_memory_rw(addr, buf, len, 0); -} -static inline void cpu_physical_memory_write(hwaddr addr, -                                             const void *buf, int len) -{ -    cpu_physical_memory_rw(addr, (void *)buf, len, 1); -} -void *cpu_physical_memory_map(hwaddr addr, -                              hwaddr *plen, -                              int is_write); -void cpu_physical_memory_unmap(void *buffer, hwaddr len, -                               int is_write, hwaddr access_len); -void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque)); - -bool cpu_physical_memory_is_io(hwaddr phys_addr); - -/* Coalesced MMIO regions are areas where write operations can be reordered. - * This usually implies that write operations are side-effect free.  This allows - * batching which can make a major impact on performance when using - * virtualization. - */ -void qemu_flush_coalesced_mmio_buffer(void); - -uint32_t ldub_phys(hwaddr addr); -uint32_t lduw_le_phys(hwaddr addr); -uint32_t lduw_be_phys(hwaddr addr); -uint32_t ldl_le_phys(hwaddr addr); -uint32_t ldl_be_phys(hwaddr addr); -uint64_t ldq_le_phys(hwaddr addr); -uint64_t ldq_be_phys(hwaddr addr); -void stb_phys(hwaddr addr, uint32_t val); -void stw_le_phys(hwaddr addr, uint32_t val); -void stw_be_phys(hwaddr addr, uint32_t val); -void stl_le_phys(hwaddr addr, uint32_t val); -void stl_be_phys(hwaddr addr, uint32_t val); -void stq_le_phys(hwaddr addr, uint64_t val); -void stq_be_phys(hwaddr addr, uint64_t val); - -#ifdef NEED_CPU_H -uint32_t lduw_phys(hwaddr addr); -uint32_t ldl_phys(hwaddr addr); -uint64_t ldq_phys(hwaddr addr); -void stl_phys_notdirty(hwaddr addr, uint32_t val); -void stw_phys(hwaddr addr, uint32_t val); -void stl_phys(hwaddr addr, uint32_t val); -void stq_phys(hwaddr addr, uint64_t val); -#endif - -void cpu_physical_memory_write_rom(hwaddr addr, -                                   const uint8_t *buf, int len); - -extern struct MemoryRegion io_mem_rom; -extern struct MemoryRegion io_mem_notdirty; - -typedef void (RAMBlockIterFunc)(void *host_addr, -    ram_addr_t offset, ram_addr_t length, void *opaque); - -void qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque); - -#endif - -#endif /* !CPU_COMMON_H */ diff --git a/contrib/qemu/include/exec/hwaddr.h b/contrib/qemu/include/exec/hwaddr.h deleted file mode 100644 index c9eb78fba18..00000000000 --- a/contrib/qemu/include/exec/hwaddr.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Define hwaddr if it exists.  */ - -#ifndef HWADDR_H -#define HWADDR_H - -#define HWADDR_BITS 64 -/* hwaddr is the type of a physical address (its size can -   be different from 'target_ulong').  */ - -typedef uint64_t hwaddr; -#define HWADDR_MAX UINT64_MAX -#define TARGET_FMT_plx "%016" PRIx64 -#define HWADDR_PRId PRId64 -#define HWADDR_PRIi PRIi64 -#define HWADDR_PRIo PRIo64 -#define HWADDR_PRIu PRIu64 -#define HWADDR_PRIx PRIx64 -#define HWADDR_PRIX PRIX64 - -#endif diff --git a/contrib/qemu/include/exec/poison.h b/contrib/qemu/include/exec/poison.h deleted file mode 100644 index 2341a750413..00000000000 --- a/contrib/qemu/include/exec/poison.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Poison identifiers that should not be used when building -   target independent device code.  */ - -#ifndef HW_POISON_H -#define HW_POISON_H -#ifdef __GNUC__ - -#pragma GCC poison TARGET_I386 -#pragma GCC poison TARGET_X86_64 -#pragma GCC poison TARGET_ALPHA -#pragma GCC poison TARGET_ARM -#pragma GCC poison TARGET_CRIS -#pragma GCC poison TARGET_LM32 -#pragma GCC poison TARGET_M68K -#pragma GCC poison TARGET_MIPS -#pragma GCC poison TARGET_MIPS64 -#pragma GCC poison TARGET_OPENRISC -#pragma GCC poison TARGET_PPC -#pragma GCC poison TARGET_PPCEMB -#pragma GCC poison TARGET_PPC64 -#pragma GCC poison TARGET_ABI32 -#pragma GCC poison TARGET_SH4 -#pragma GCC poison TARGET_SPARC -#pragma GCC poison TARGET_SPARC64 - -#pragma GCC poison TARGET_WORDS_BIGENDIAN -#pragma GCC poison BSWAP_NEEDED - -#pragma GCC poison TARGET_LONG_BITS -#pragma GCC poison TARGET_FMT_lx -#pragma GCC poison TARGET_FMT_ld - -#pragma GCC poison TARGET_PAGE_SIZE -#pragma GCC poison TARGET_PAGE_MASK -#pragma GCC poison TARGET_PAGE_BITS -#pragma GCC poison TARGET_PAGE_ALIGN - -#pragma GCC poison CPUArchState -#pragma GCC poison env - -#pragma GCC poison lduw_phys -#pragma GCC poison ldl_phys -#pragma GCC poison ldq_phys -#pragma GCC poison stl_phys_notdirty -#pragma GCC poison stw_phys -#pragma GCC poison stl_phys -#pragma GCC poison stq_phys - -#pragma GCC poison CPU_INTERRUPT_HARD -#pragma GCC poison CPU_INTERRUPT_EXITTB -#pragma GCC poison CPU_INTERRUPT_HALT -#pragma GCC poison CPU_INTERRUPT_DEBUG -#pragma GCC poison CPU_INTERRUPT_TGT_EXT_0 -#pragma GCC poison CPU_INTERRUPT_TGT_EXT_1 -#pragma GCC poison CPU_INTERRUPT_TGT_EXT_2 -#pragma GCC poison CPU_INTERRUPT_TGT_EXT_3 -#pragma GCC poison CPU_INTERRUPT_TGT_EXT_4 -#pragma GCC poison CPU_INTERRUPT_TGT_INT_0 -#pragma GCC poison CPU_INTERRUPT_TGT_INT_1 -#pragma GCC poison CPU_INTERRUPT_TGT_INT_2 - -#endif -#endif diff --git a/contrib/qemu/include/fpu/softfloat.h b/contrib/qemu/include/fpu/softfloat.h deleted file mode 100644 index f3927e2419f..00000000000 --- a/contrib/qemu/include/fpu/softfloat.h +++ /dev/null @@ -1,641 +0,0 @@ -/* - * QEMU float support - * - * Derived from SoftFloat. - */ - -/*============================================================================ - -This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser.  This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704.  Funding was partially provided by the -National Science Foundation under grant MIP-9311980.  The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek.  More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -#ifndef SOFTFLOAT_H -#define SOFTFLOAT_H - -#if defined(CONFIG_SOLARIS) && defined(CONFIG_NEEDS_LIBSUNMATH) -#include <sunmath.h> -#endif - -#include <inttypes.h> -#include "config-host.h" -#include "qemu/osdep.h" - -/*---------------------------------------------------------------------------- -| Each of the following `typedef's defines the most convenient type that holds -| integers of at least as many bits as specified.  For example, `uint8' should -| be the most convenient type that can hold unsigned integers of as many as -| 8 bits.  The `flag' type must be able to hold either a 0 or 1.  For most -| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed -| to the same as `int'. -*----------------------------------------------------------------------------*/ -typedef uint8_t flag; -typedef uint8_t uint8; -typedef int8_t int8; -typedef unsigned int uint32; -typedef signed int int32; -typedef uint64_t uint64; -typedef int64_t int64; - -#define LIT64( a ) a##LL -#define INLINE static inline - -#define STATUS_PARAM , float_status *status -#define STATUS(field) status->field -#define STATUS_VAR , status - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point ordering relations -*----------------------------------------------------------------------------*/ -enum { -    float_relation_less      = -1, -    float_relation_equal     =  0, -    float_relation_greater   =  1, -    float_relation_unordered =  2 -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point types. -*----------------------------------------------------------------------------*/ -/* Use structures for soft-float types.  This prevents accidentally mixing -   them with native int/float types.  A sufficiently clever compiler and -   sane ABI should be able to see though these structs.  However -   x86/gcc 3.x seems to struggle a bit, so leave them disabled by default.  */ -//#define USE_SOFTFLOAT_STRUCT_TYPES -#ifdef USE_SOFTFLOAT_STRUCT_TYPES -typedef struct { -    uint16_t v; -} float16; -#define float16_val(x) (((float16)(x)).v) -#define make_float16(x) __extension__ ({ float16 f16_val = {x}; f16_val; }) -#define const_float16(x) { x } -typedef struct { -    uint32_t v; -} float32; -/* The cast ensures an error if the wrong type is passed.  */ -#define float32_val(x) (((float32)(x)).v) -#define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; }) -#define const_float32(x) { x } -typedef struct { -    uint64_t v; -} float64; -#define float64_val(x) (((float64)(x)).v) -#define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; }) -#define const_float64(x) { x } -#else -typedef uint16_t float16; -typedef uint32_t float32; -typedef uint64_t float64; -#define float16_val(x) (x) -#define float32_val(x) (x) -#define float64_val(x) (x) -#define make_float16(x) (x) -#define make_float32(x) (x) -#define make_float64(x) (x) -#define const_float16(x) (x) -#define const_float32(x) (x) -#define const_float64(x) (x) -#endif -typedef struct { -    uint64_t low; -    uint16_t high; -} floatx80; -#define make_floatx80(exp, mant) ((floatx80) { mant, exp }) -#define make_floatx80_init(exp, mant) { .low = mant, .high = exp } -typedef struct { -#ifdef HOST_WORDS_BIGENDIAN -    uint64_t high, low; -#else -    uint64_t low, high; -#endif -} float128; -#define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ }) -#define make_float128_init(high_, low_) { .high = high_, .low = low_ } - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point underflow tininess-detection mode. -*----------------------------------------------------------------------------*/ -enum { -    float_tininess_after_rounding  = 0, -    float_tininess_before_rounding = 1 -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point rounding mode. -*----------------------------------------------------------------------------*/ -enum { -    float_round_nearest_even = 0, -    float_round_down         = 1, -    float_round_up           = 2, -    float_round_to_zero      = 3 -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point exception flags. -*----------------------------------------------------------------------------*/ -enum { -    float_flag_invalid   =  1, -    float_flag_divbyzero =  4, -    float_flag_overflow  =  8, -    float_flag_underflow = 16, -    float_flag_inexact   = 32, -    float_flag_input_denormal = 64, -    float_flag_output_denormal = 128 -}; - -typedef struct float_status { -    signed char float_detect_tininess; -    signed char float_rounding_mode; -    signed char float_exception_flags; -    signed char floatx80_rounding_precision; -    /* should denormalised results go to zero and set the inexact flag? */ -    flag flush_to_zero; -    /* should denormalised inputs go to zero and set the input_denormal flag? */ -    flag flush_inputs_to_zero; -    flag default_nan_mode; -} float_status; - -void set_float_rounding_mode(int val STATUS_PARAM); -void set_float_exception_flags(int val STATUS_PARAM); -INLINE void set_float_detect_tininess(int val STATUS_PARAM) -{ -    STATUS(float_detect_tininess) = val; -} -INLINE void set_flush_to_zero(flag val STATUS_PARAM) -{ -    STATUS(flush_to_zero) = val; -} -INLINE void set_flush_inputs_to_zero(flag val STATUS_PARAM) -{ -    STATUS(flush_inputs_to_zero) = val; -} -INLINE void set_default_nan_mode(flag val STATUS_PARAM) -{ -    STATUS(default_nan_mode) = val; -} -INLINE int get_float_exception_flags(float_status *status) -{ -    return STATUS(float_exception_flags); -} -void set_floatx80_rounding_precision(int val STATUS_PARAM); - -/*---------------------------------------------------------------------------- -| Routine to raise any or all of the software IEC/IEEE floating-point -| exception flags. -*----------------------------------------------------------------------------*/ -void float_raise( int8 flags STATUS_PARAM); - -/*---------------------------------------------------------------------------- -| Options to indicate which negations to perform in float*_muladd() -| Using these differs from negating an input or output before calling -| the muladd function in that this means that a NaN doesn't have its -| sign bit inverted before it is propagated. -*----------------------------------------------------------------------------*/ -enum { -    float_muladd_negate_c = 1, -    float_muladd_negate_product = 2, -    float_muladd_negate_result = 4, -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ -float32 int32_to_float32( int32 STATUS_PARAM ); -float64 int32_to_float64( int32 STATUS_PARAM ); -float32 uint32_to_float32( uint32 STATUS_PARAM ); -float64 uint32_to_float64( uint32 STATUS_PARAM ); -floatx80 int32_to_floatx80( int32 STATUS_PARAM ); -float128 int32_to_float128( int32 STATUS_PARAM ); -float32 int64_to_float32( int64 STATUS_PARAM ); -float32 uint64_to_float32( uint64 STATUS_PARAM ); -float64 int64_to_float64( int64 STATUS_PARAM ); -float64 uint64_to_float64( uint64 STATUS_PARAM ); -floatx80 int64_to_floatx80( int64 STATUS_PARAM ); -float128 int64_to_float128( int64 STATUS_PARAM ); -float128 uint64_to_float128( uint64 STATUS_PARAM ); - -/*---------------------------------------------------------------------------- -| Software half-precision conversion routines. -*----------------------------------------------------------------------------*/ -float16 float32_to_float16( float32, flag STATUS_PARAM ); -float32 float16_to_float32( float16, flag STATUS_PARAM ); - -/*---------------------------------------------------------------------------- -| Software half-precision operations. -*----------------------------------------------------------------------------*/ -int float16_is_quiet_nan( float16 ); -int float16_is_signaling_nan( float16 ); -float16 float16_maybe_silence_nan( float16 ); - -INLINE int float16_is_any_nan(float16 a) -{ -    return ((float16_val(a) & ~0x8000) > 0x7c00); -} - -/*---------------------------------------------------------------------------- -| The pattern for a default generated half-precision NaN. -*----------------------------------------------------------------------------*/ -extern const float16 float16_default_nan; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision conversion routines. -*----------------------------------------------------------------------------*/ -int_fast16_t float32_to_int16_round_to_zero(float32 STATUS_PARAM); -uint_fast16_t float32_to_uint16_round_to_zero(float32 STATUS_PARAM); -int32 float32_to_int32( float32 STATUS_PARAM ); -int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM ); -uint32 float32_to_uint32( float32 STATUS_PARAM ); -uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM ); -int64 float32_to_int64( float32 STATUS_PARAM ); -int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM ); -float64 float32_to_float64( float32 STATUS_PARAM ); -floatx80 float32_to_floatx80( float32 STATUS_PARAM ); -float128 float32_to_float128( float32 STATUS_PARAM ); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision operations. -*----------------------------------------------------------------------------*/ -float32 float32_round_to_int( float32 STATUS_PARAM ); -float32 float32_add( float32, float32 STATUS_PARAM ); -float32 float32_sub( float32, float32 STATUS_PARAM ); -float32 float32_mul( float32, float32 STATUS_PARAM ); -float32 float32_div( float32, float32 STATUS_PARAM ); -float32 float32_rem( float32, float32 STATUS_PARAM ); -float32 float32_muladd(float32, float32, float32, int STATUS_PARAM); -float32 float32_sqrt( float32 STATUS_PARAM ); -float32 float32_exp2( float32 STATUS_PARAM ); -float32 float32_log2( float32 STATUS_PARAM ); -int float32_eq( float32, float32 STATUS_PARAM ); -int float32_le( float32, float32 STATUS_PARAM ); -int float32_lt( float32, float32 STATUS_PARAM ); -int float32_unordered( float32, float32 STATUS_PARAM ); -int float32_eq_quiet( float32, float32 STATUS_PARAM ); -int float32_le_quiet( float32, float32 STATUS_PARAM ); -int float32_lt_quiet( float32, float32 STATUS_PARAM ); -int float32_unordered_quiet( float32, float32 STATUS_PARAM ); -int float32_compare( float32, float32 STATUS_PARAM ); -int float32_compare_quiet( float32, float32 STATUS_PARAM ); -float32 float32_min(float32, float32 STATUS_PARAM); -float32 float32_max(float32, float32 STATUS_PARAM); -int float32_is_quiet_nan( float32 ); -int float32_is_signaling_nan( float32 ); -float32 float32_maybe_silence_nan( float32 ); -float32 float32_scalbn( float32, int STATUS_PARAM ); - -INLINE float32 float32_abs(float32 a) -{ -    /* Note that abs does *not* handle NaN specially, nor does -     * it flush denormal inputs to zero. -     */ -    return make_float32(float32_val(a) & 0x7fffffff); -} - -INLINE float32 float32_chs(float32 a) -{ -    /* Note that chs does *not* handle NaN specially, nor does -     * it flush denormal inputs to zero. -     */ -    return make_float32(float32_val(a) ^ 0x80000000); -} - -INLINE int float32_is_infinity(float32 a) -{ -    return (float32_val(a) & 0x7fffffff) == 0x7f800000; -} - -INLINE int float32_is_neg(float32 a) -{ -    return float32_val(a) >> 31; -} - -INLINE int float32_is_zero(float32 a) -{ -    return (float32_val(a) & 0x7fffffff) == 0; -} - -INLINE int float32_is_any_nan(float32 a) -{ -    return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL); -} - -INLINE int float32_is_zero_or_denormal(float32 a) -{ -    return (float32_val(a) & 0x7f800000) == 0; -} - -INLINE float32 float32_set_sign(float32 a, int sign) -{ -    return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31)); -} - -#define float32_zero make_float32(0) -#define float32_one make_float32(0x3f800000) -#define float32_ln2 make_float32(0x3f317218) -#define float32_pi make_float32(0x40490fdb) -#define float32_half make_float32(0x3f000000) -#define float32_infinity make_float32(0x7f800000) - - -/*---------------------------------------------------------------------------- -| The pattern for a default generated single-precision NaN. -*----------------------------------------------------------------------------*/ -extern const float32 float32_default_nan; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int_fast16_t float64_to_int16_round_to_zero(float64 STATUS_PARAM); -uint_fast16_t float64_to_uint16_round_to_zero(float64 STATUS_PARAM); -int32 float64_to_int32( float64 STATUS_PARAM ); -int32 float64_to_int32_round_to_zero( float64 STATUS_PARAM ); -uint32 float64_to_uint32( float64 STATUS_PARAM ); -uint32 float64_to_uint32_round_to_zero( float64 STATUS_PARAM ); -int64 float64_to_int64( float64 STATUS_PARAM ); -int64 float64_to_int64_round_to_zero( float64 STATUS_PARAM ); -uint64 float64_to_uint64 (float64 a STATUS_PARAM); -uint64 float64_to_uint64_round_to_zero (float64 a STATUS_PARAM); -float32 float64_to_float32( float64 STATUS_PARAM ); -floatx80 float64_to_floatx80( float64 STATUS_PARAM ); -float128 float64_to_float128( float64 STATUS_PARAM ); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision operations. -*----------------------------------------------------------------------------*/ -float64 float64_round_to_int( float64 STATUS_PARAM ); -float64 float64_trunc_to_int( float64 STATUS_PARAM ); -float64 float64_add( float64, float64 STATUS_PARAM ); -float64 float64_sub( float64, float64 STATUS_PARAM ); -float64 float64_mul( float64, float64 STATUS_PARAM ); -float64 float64_div( float64, float64 STATUS_PARAM ); -float64 float64_rem( float64, float64 STATUS_PARAM ); -float64 float64_muladd(float64, float64, float64, int STATUS_PARAM); -float64 float64_sqrt( float64 STATUS_PARAM ); -float64 float64_log2( float64 STATUS_PARAM ); -int float64_eq( float64, float64 STATUS_PARAM ); -int float64_le( float64, float64 STATUS_PARAM ); -int float64_lt( float64, float64 STATUS_PARAM ); -int float64_unordered( float64, float64 STATUS_PARAM ); -int float64_eq_quiet( float64, float64 STATUS_PARAM ); -int float64_le_quiet( float64, float64 STATUS_PARAM ); -int float64_lt_quiet( float64, float64 STATUS_PARAM ); -int float64_unordered_quiet( float64, float64 STATUS_PARAM ); -int float64_compare( float64, float64 STATUS_PARAM ); -int float64_compare_quiet( float64, float64 STATUS_PARAM ); -float64 float64_min(float64, float64 STATUS_PARAM); -float64 float64_max(float64, float64 STATUS_PARAM); -int float64_is_quiet_nan( float64 a ); -int float64_is_signaling_nan( float64 ); -float64 float64_maybe_silence_nan( float64 ); -float64 float64_scalbn( float64, int STATUS_PARAM ); - -INLINE float64 float64_abs(float64 a) -{ -    /* Note that abs does *not* handle NaN specially, nor does -     * it flush denormal inputs to zero. -     */ -    return make_float64(float64_val(a) & 0x7fffffffffffffffLL); -} - -INLINE float64 float64_chs(float64 a) -{ -    /* Note that chs does *not* handle NaN specially, nor does -     * it flush denormal inputs to zero. -     */ -    return make_float64(float64_val(a) ^ 0x8000000000000000LL); -} - -INLINE int float64_is_infinity(float64 a) -{ -    return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL; -} - -INLINE int float64_is_neg(float64 a) -{ -    return float64_val(a) >> 63; -} - -INLINE int float64_is_zero(float64 a) -{ -    return (float64_val(a) & 0x7fffffffffffffffLL) == 0; -} - -INLINE int float64_is_any_nan(float64 a) -{ -    return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL); -} - -INLINE int float64_is_zero_or_denormal(float64 a) -{ -    return (float64_val(a) & 0x7ff0000000000000LL) == 0; -} - -INLINE float64 float64_set_sign(float64 a, int sign) -{ -    return make_float64((float64_val(a) & 0x7fffffffffffffffULL) -                        | ((int64_t)sign << 63)); -} - -#define float64_zero make_float64(0) -#define float64_one make_float64(0x3ff0000000000000LL) -#define float64_ln2 make_float64(0x3fe62e42fefa39efLL) -#define float64_pi make_float64(0x400921fb54442d18LL) -#define float64_half make_float64(0x3fe0000000000000LL) -#define float64_infinity make_float64(0x7ff0000000000000LL) - -/*---------------------------------------------------------------------------- -| The pattern for a default generated double-precision NaN. -*----------------------------------------------------------------------------*/ -extern const float64 float64_default_nan; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 floatx80_to_int32( floatx80 STATUS_PARAM ); -int32 floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM ); -int64 floatx80_to_int64( floatx80 STATUS_PARAM ); -int64 floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM ); -float32 floatx80_to_float32( floatx80 STATUS_PARAM ); -float64 floatx80_to_float64( floatx80 STATUS_PARAM ); -float128 floatx80_to_float128( floatx80 STATUS_PARAM ); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision operations. -*----------------------------------------------------------------------------*/ -floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM ); -floatx80 floatx80_add( floatx80, floatx80 STATUS_PARAM ); -floatx80 floatx80_sub( floatx80, floatx80 STATUS_PARAM ); -floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM ); -floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM ); -floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM ); -floatx80 floatx80_sqrt( floatx80 STATUS_PARAM ); -int floatx80_eq( floatx80, floatx80 STATUS_PARAM ); -int floatx80_le( floatx80, floatx80 STATUS_PARAM ); -int floatx80_lt( floatx80, floatx80 STATUS_PARAM ); -int floatx80_unordered( floatx80, floatx80 STATUS_PARAM ); -int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM ); -int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM ); -int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM ); -int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM ); -int floatx80_compare( floatx80, floatx80 STATUS_PARAM ); -int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM ); -int floatx80_is_quiet_nan( floatx80 ); -int floatx80_is_signaling_nan( floatx80 ); -floatx80 floatx80_maybe_silence_nan( floatx80 ); -floatx80 floatx80_scalbn( floatx80, int STATUS_PARAM ); - -INLINE floatx80 floatx80_abs(floatx80 a) -{ -    a.high &= 0x7fff; -    return a; -} - -INLINE floatx80 floatx80_chs(floatx80 a) -{ -    a.high ^= 0x8000; -    return a; -} - -INLINE int floatx80_is_infinity(floatx80 a) -{ -    return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL; -} - -INLINE int floatx80_is_neg(floatx80 a) -{ -    return a.high >> 15; -} - -INLINE int floatx80_is_zero(floatx80 a) -{ -    return (a.high & 0x7fff) == 0 && a.low == 0; -} - -INLINE int floatx80_is_zero_or_denormal(floatx80 a) -{ -    return (a.high & 0x7fff) == 0; -} - -INLINE int floatx80_is_any_nan(floatx80 a) -{ -    return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1); -} - -#define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL) -#define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL) -#define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL) -#define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL) -#define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL) -#define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL) - -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. -*----------------------------------------------------------------------------*/ -extern const floatx80 floatx80_default_nan; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE quadruple-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 float128_to_int32( float128 STATUS_PARAM ); -int32 float128_to_int32_round_to_zero( float128 STATUS_PARAM ); -int64 float128_to_int64( float128 STATUS_PARAM ); -int64 float128_to_int64_round_to_zero( float128 STATUS_PARAM ); -float32 float128_to_float32( float128 STATUS_PARAM ); -float64 float128_to_float64( float128 STATUS_PARAM ); -floatx80 float128_to_floatx80( float128 STATUS_PARAM ); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE quadruple-precision operations. -*----------------------------------------------------------------------------*/ -float128 float128_round_to_int( float128 STATUS_PARAM ); -float128 float128_add( float128, float128 STATUS_PARAM ); -float128 float128_sub( float128, float128 STATUS_PARAM ); -float128 float128_mul( float128, float128 STATUS_PARAM ); -float128 float128_div( float128, float128 STATUS_PARAM ); -float128 float128_rem( float128, float128 STATUS_PARAM ); -float128 float128_sqrt( float128 STATUS_PARAM ); -int float128_eq( float128, float128 STATUS_PARAM ); -int float128_le( float128, float128 STATUS_PARAM ); -int float128_lt( float128, float128 STATUS_PARAM ); -int float128_unordered( float128, float128 STATUS_PARAM ); -int float128_eq_quiet( float128, float128 STATUS_PARAM ); -int float128_le_quiet( float128, float128 STATUS_PARAM ); -int float128_lt_quiet( float128, float128 STATUS_PARAM ); -int float128_unordered_quiet( float128, float128 STATUS_PARAM ); -int float128_compare( float128, float128 STATUS_PARAM ); -int float128_compare_quiet( float128, float128 STATUS_PARAM ); -int float128_is_quiet_nan( float128 ); -int float128_is_signaling_nan( float128 ); -float128 float128_maybe_silence_nan( float128 ); -float128 float128_scalbn( float128, int STATUS_PARAM ); - -INLINE float128 float128_abs(float128 a) -{ -    a.high &= 0x7fffffffffffffffLL; -    return a; -} - -INLINE float128 float128_chs(float128 a) -{ -    a.high ^= 0x8000000000000000LL; -    return a; -} - -INLINE int float128_is_infinity(float128 a) -{ -    return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0; -} - -INLINE int float128_is_neg(float128 a) -{ -    return a.high >> 63; -} - -INLINE int float128_is_zero(float128 a) -{ -    return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0; -} - -INLINE int float128_is_zero_or_denormal(float128 a) -{ -    return (a.high & 0x7fff000000000000LL) == 0; -} - -INLINE int float128_is_any_nan(float128 a) -{ -    return ((a.high >> 48) & 0x7fff) == 0x7fff && -        ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0)); -} - -#define float128_zero make_float128(0, 0) - -/*---------------------------------------------------------------------------- -| The pattern for a default generated quadruple-precision NaN. -*----------------------------------------------------------------------------*/ -extern const float128 float128_default_nan; - -#endif /* !SOFTFLOAT_H */ diff --git a/contrib/qemu/include/glib-compat.h b/contrib/qemu/include/glib-compat.h deleted file mode 100644 index 8aa77afd626..00000000000 --- a/contrib/qemu/include/glib-compat.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GLIB Compatibility Functions - * - * Copyright IBM, Corp. 2013 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ - -#ifndef QEMU_GLIB_COMPAT_H -#define QEMU_GLIB_COMPAT_H - -#include <glib.h> - -#if !GLIB_CHECK_VERSION(2, 14, 0) -static inline guint g_timeout_add_seconds(guint interval, GSourceFunc function, -                                          gpointer data) -{ -    return g_timeout_add(interval * 1000, function, data); -} -#endif - -#endif diff --git a/contrib/qemu/include/migration/migration.h b/contrib/qemu/include/migration/migration.h deleted file mode 100644 index bc9fde0b2ab..00000000000 --- a/contrib/qemu/include/migration/migration.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * QEMU live migration - * - * Copyright IBM, Corp. 2008 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2.  See - * the COPYING file in the top-level directory. - * - */ - -#ifndef QEMU_MIGRATION_H -#define QEMU_MIGRATION_H - -#include "qapi/qmp/qdict.h" -#include "qemu-common.h" -#include "qemu/thread.h" -#include "qemu/notify.h" -#include "qapi/error.h" -#include "migration/vmstate.h" -#include "qapi-types.h" -#include "exec/cpu-common.h" - -struct MigrationParams { -    bool blk; -    bool shared; -}; - -typedef struct MigrationState MigrationState; - -struct MigrationState -{ -    int64_t bandwidth_limit; -    size_t bytes_xfer; -    size_t xfer_limit; -    QemuThread thread; -    QEMUBH *cleanup_bh; -    QEMUFile *file; - -    int state; -    MigrationParams params; -    double mbps; -    int64_t total_time; -    int64_t downtime; -    int64_t expected_downtime; -    int64_t dirty_pages_rate; -    int64_t dirty_bytes_rate; -    bool enabled_capabilities[MIGRATION_CAPABILITY_MAX]; -    int64_t xbzrle_cache_size; -}; - -void process_incoming_migration(QEMUFile *f); - -void qemu_start_incoming_migration(const char *uri, Error **errp); - -uint64_t migrate_max_downtime(void); - -void do_info_migrate_print(Monitor *mon, const QObject *data); - -void do_info_migrate(Monitor *mon, QObject **ret_data); - -void exec_start_incoming_migration(const char *host_port, Error **errp); - -void exec_start_outgoing_migration(MigrationState *s, const char *host_port, Error **errp); - -void tcp_start_incoming_migration(const char *host_port, Error **errp); - -void tcp_start_outgoing_migration(MigrationState *s, const char *host_port, Error **errp); - -void unix_start_incoming_migration(const char *path, Error **errp); - -void unix_start_outgoing_migration(MigrationState *s, const char *path, Error **errp); - -void fd_start_incoming_migration(const char *path, Error **errp); - -void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp); - -void migrate_fd_error(MigrationState *s); - -void migrate_fd_connect(MigrationState *s); - -int migrate_fd_close(MigrationState *s); - -void add_migration_state_change_notifier(Notifier *notify); -void remove_migration_state_change_notifier(Notifier *notify); -bool migration_is_active(MigrationState *); -bool migration_has_finished(MigrationState *); -bool migration_has_failed(MigrationState *); -MigrationState *migrate_get_current(void); - -uint64_t ram_bytes_remaining(void); -uint64_t ram_bytes_transferred(void); -uint64_t ram_bytes_total(void); - -void acct_update_position(QEMUFile *f, size_t size, bool zero); - -extern SaveVMHandlers savevm_ram_handlers; - -uint64_t dup_mig_bytes_transferred(void); -uint64_t dup_mig_pages_transferred(void); -uint64_t skipped_mig_bytes_transferred(void); -uint64_t skipped_mig_pages_transferred(void); -uint64_t norm_mig_bytes_transferred(void); -uint64_t norm_mig_pages_transferred(void); -uint64_t xbzrle_mig_bytes_transferred(void); -uint64_t xbzrle_mig_pages_transferred(void); -uint64_t xbzrle_mig_pages_overflow(void); -uint64_t xbzrle_mig_pages_cache_miss(void); - -/** - * @migrate_add_blocker - prevent migration from proceeding - * - * @reason - an error to be returned whenever migration is attempted - */ -void migrate_add_blocker(Error *reason); - -/** - * @migrate_del_blocker - remove a blocking error from migration - * - * @reason - the error blocking migration - */ -void migrate_del_blocker(Error *reason); - -bool migrate_rdma_pin_all(void); - -bool migrate_auto_converge(void); - -int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen, -                         uint8_t *dst, int dlen); -int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen); - -int migrate_use_xbzrle(void); -int64_t migrate_xbzrle_cache_size(void); - -int64_t xbzrle_cache_resize(int64_t new_size); - -void ram_control_before_iterate(QEMUFile *f, uint64_t flags); -void ram_control_after_iterate(QEMUFile *f, uint64_t flags); -void ram_control_load_hook(QEMUFile *f, uint64_t flags); - -/* Whenever this is found in the data stream, the flags - * will be passed to ram_control_load_hook in the incoming-migration - * side. This lets before_ram_iterate/after_ram_iterate add - * transport-specific sections to the RAM migration data. - */ -#define RAM_SAVE_FLAG_HOOK     0x80 - -#define RAM_SAVE_CONTROL_NOT_SUPP -1000 -#define RAM_SAVE_CONTROL_DELAYED  -2000 - -size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset, -                             ram_addr_t offset, size_t size, -                             int *bytes_sent); - -#endif diff --git a/contrib/qemu/include/migration/qemu-file.h b/contrib/qemu/include/migration/qemu-file.h deleted file mode 100644 index 0f757fbeb63..00000000000 --- a/contrib/qemu/include/migration/qemu-file.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * QEMU System Emulator - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef QEMU_FILE_H -#define QEMU_FILE_H 1 -#include "exec/cpu-common.h" - -/* This function writes a chunk of data to a file at the given position. - * The pos argument can be ignored if the file is only being used for - * streaming.  The handler should try to write all of the data it can. - */ -typedef int (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf, -                                    int64_t pos, int size); - -/* Read a chunk of data from a file at the given position.  The pos argument - * can be ignored if the file is only be used for streaming.  The number of - * bytes actually read should be returned. - */ -typedef int (QEMUFileGetBufferFunc)(void *opaque, uint8_t *buf, -                                    int64_t pos, int size); - -/* Close a file - * - * Return negative error number on error, 0 or positive value on success. - * - * The meaning of return value on success depends on the specific back-end being - * used. - */ -typedef int (QEMUFileCloseFunc)(void *opaque); - -/* Called to return the OS file descriptor associated to the QEMUFile. - */ -typedef int (QEMUFileGetFD)(void *opaque); - -/* - * This function writes an iovec to file. - */ -typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov, -                                           int iovcnt, int64_t pos); - -/* - * This function provides hooks around different - * stages of RAM migration. - */ -typedef int (QEMURamHookFunc)(QEMUFile *f, void *opaque, uint64_t flags); - -/* - * Constants used by ram_control_* hooks - */ -#define RAM_CONTROL_SETUP    0 -#define RAM_CONTROL_ROUND    1 -#define RAM_CONTROL_HOOK     2 -#define RAM_CONTROL_FINISH   3 - -/* - * This function allows override of where the RAM page - * is saved (such as RDMA, for example.) - */ -typedef size_t (QEMURamSaveFunc)(QEMUFile *f, void *opaque, -                               ram_addr_t block_offset, -                               ram_addr_t offset, -                               size_t size, -                               int *bytes_sent); - -typedef struct QEMUFileOps { -    QEMUFilePutBufferFunc *put_buffer; -    QEMUFileGetBufferFunc *get_buffer; -    QEMUFileCloseFunc *close; -    QEMUFileGetFD *get_fd; -    QEMUFileWritevBufferFunc *writev_buffer; -    QEMURamHookFunc *before_ram_iterate; -    QEMURamHookFunc *after_ram_iterate; -    QEMURamHookFunc *hook_ram_load; -    QEMURamSaveFunc *save_page; -} QEMUFileOps; - -QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops); -QEMUFile *qemu_fopen(const char *filename, const char *mode); -QEMUFile *qemu_fdopen(int fd, const char *mode); -QEMUFile *qemu_fopen_socket(int fd, const char *mode); -QEMUFile *qemu_popen_cmd(const char *command, const char *mode); -int qemu_get_fd(QEMUFile *f); -int qemu_fclose(QEMUFile *f); -int64_t qemu_ftell(QEMUFile *f); -void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size); -void qemu_put_byte(QEMUFile *f, int v); -/* - * put_buffer without copying the buffer. - * The buffer should be available till it is sent asynchronously. - */ -void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size); -bool qemu_file_mode_is_not_valid(const char *mode); - -static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v) -{ -    qemu_put_byte(f, (int)v); -} - -#define qemu_put_sbyte qemu_put_byte - -void qemu_put_be16(QEMUFile *f, unsigned int v); -void qemu_put_be32(QEMUFile *f, unsigned int v); -void qemu_put_be64(QEMUFile *f, uint64_t v); -int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size); -int qemu_get_byte(QEMUFile *f); -void qemu_update_position(QEMUFile *f, size_t size); - -static inline unsigned int qemu_get_ubyte(QEMUFile *f) -{ -    return (unsigned int)qemu_get_byte(f); -} - -#define qemu_get_sbyte qemu_get_byte - -unsigned int qemu_get_be16(QEMUFile *f); -unsigned int qemu_get_be32(QEMUFile *f); -uint64_t qemu_get_be64(QEMUFile *f); - -int qemu_file_rate_limit(QEMUFile *f); -void qemu_file_reset_rate_limit(QEMUFile *f); -void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate); -int64_t qemu_file_get_rate_limit(QEMUFile *f); -int qemu_file_get_error(QEMUFile *f); -void qemu_fflush(QEMUFile *f); - -static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv) -{ -    qemu_put_be64(f, *pv); -} - -static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv) -{ -    qemu_put_be32(f, *pv); -} - -static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv) -{ -    qemu_put_be16(f, *pv); -} - -static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv) -{ -    qemu_put_byte(f, *pv); -} - -static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv) -{ -    *pv = qemu_get_be64(f); -} - -static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv) -{ -    *pv = qemu_get_be32(f); -} - -static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv) -{ -    *pv = qemu_get_be16(f); -} - -static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv) -{ -    *pv = qemu_get_byte(f); -} - -// Signed versions for type safety -static inline void qemu_put_sbuffer(QEMUFile *f, const int8_t *buf, int size) -{ -    qemu_put_buffer(f, (const uint8_t *)buf, size); -} - -static inline void qemu_put_sbe16(QEMUFile *f, int v) -{ -    qemu_put_be16(f, (unsigned int)v); -} - -static inline void qemu_put_sbe32(QEMUFile *f, int v) -{ -    qemu_put_be32(f, (unsigned int)v); -} - -static inline void qemu_put_sbe64(QEMUFile *f, int64_t v) -{ -    qemu_put_be64(f, (uint64_t)v); -} - -static inline size_t qemu_get_sbuffer(QEMUFile *f, int8_t *buf, int size) -{ -    return qemu_get_buffer(f, (uint8_t *)buf, size); -} - -static inline int qemu_get_sbe16(QEMUFile *f) -{ -    return (int)qemu_get_be16(f); -} - -static inline int qemu_get_sbe32(QEMUFile *f) -{ -    return (int)qemu_get_be32(f); -} - -static inline int64_t qemu_get_sbe64(QEMUFile *f) -{ -    return (int64_t)qemu_get_be64(f); -} - -static inline void qemu_put_s8s(QEMUFile *f, const int8_t *pv) -{ -    qemu_put_8s(f, (const uint8_t *)pv); -} - -static inline void qemu_put_sbe16s(QEMUFile *f, const int16_t *pv) -{ -    qemu_put_be16s(f, (const uint16_t *)pv); -} - -static inline void qemu_put_sbe32s(QEMUFile *f, const int32_t *pv) -{ -    qemu_put_be32s(f, (const uint32_t *)pv); -} - -static inline void qemu_put_sbe64s(QEMUFile *f, const int64_t *pv) -{ -    qemu_put_be64s(f, (const uint64_t *)pv); -} - -static inline void qemu_get_s8s(QEMUFile *f, int8_t *pv) -{ -    qemu_get_8s(f, (uint8_t *)pv); -} - -static inline void qemu_get_sbe16s(QEMUFile *f, int16_t *pv) -{ -    qemu_get_be16s(f, (uint16_t *)pv); -} - -static inline void qemu_get_sbe32s(QEMUFile *f, int32_t *pv) -{ -    qemu_get_be32s(f, (uint32_t *)pv); -} - -static inline void qemu_get_sbe64s(QEMUFile *f, int64_t *pv) -{ -    qemu_get_be64s(f, (uint64_t *)pv); -} -#endif diff --git a/contrib/qemu/include/migration/vmstate.h b/contrib/qemu/include/migration/vmstate.h deleted file mode 100644 index 1c31b5d6fb5..00000000000 --- a/contrib/qemu/include/migration/vmstate.h +++ /dev/null @@ -1,740 +0,0 @@ -/* - * QEMU migration/snapshot declarations - * - * Copyright (c) 2009-2011 Red Hat, Inc. - * - * Original author: Juan Quintela <quintela@redhat.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef QEMU_VMSTATE_H -#define QEMU_VMSTATE_H 1 - -#ifndef CONFIG_USER_ONLY -#include <migration/qemu-file.h> -#endif - -typedef void SaveStateHandler(QEMUFile *f, void *opaque); -typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id); - -typedef struct SaveVMHandlers { -    /* This runs inside the iothread lock.  */ -    void (*set_params)(const MigrationParams *params, void * opaque); -    SaveStateHandler *save_state; - -    void (*cancel)(void *opaque); -    int (*save_live_complete)(QEMUFile *f, void *opaque); - -    /* This runs both outside and inside the iothread lock.  */ -    bool (*is_active)(void *opaque); - -    /* This runs outside the iothread lock in the migration case, and -     * within the lock in the savevm case.  The callback had better only -     * use data that is local to the migration thread or protected -     * by other locks. -     */ -    int (*save_live_iterate)(QEMUFile *f, void *opaque); - -    /* This runs outside the iothread lock!  */ -    int (*save_live_setup)(QEMUFile *f, void *opaque); -    uint64_t (*save_live_pending)(QEMUFile *f, void *opaque, uint64_t max_size); - -    LoadStateHandler *load_state; -} SaveVMHandlers; - -int register_savevm(DeviceState *dev, -                    const char *idstr, -                    int instance_id, -                    int version_id, -                    SaveStateHandler *save_state, -                    LoadStateHandler *load_state, -                    void *opaque); - -int register_savevm_live(DeviceState *dev, -                         const char *idstr, -                         int instance_id, -                         int version_id, -                         SaveVMHandlers *ops, -                         void *opaque); - -void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque); -void register_device_unmigratable(DeviceState *dev, const char *idstr, -                                                                void *opaque); - - -typedef struct VMStateInfo VMStateInfo; -typedef struct VMStateDescription VMStateDescription; - -struct VMStateInfo { -    const char *name; -    int (*get)(QEMUFile *f, void *pv, size_t size); -    void (*put)(QEMUFile *f, void *pv, size_t size); -}; - -enum VMStateFlags { -    VMS_SINGLE           = 0x001, -    VMS_POINTER          = 0x002, -    VMS_ARRAY            = 0x004, -    VMS_STRUCT           = 0x008, -    VMS_VARRAY_INT32     = 0x010,  /* Array with size in int32_t field*/ -    VMS_BUFFER           = 0x020,  /* static sized buffer */ -    VMS_ARRAY_OF_POINTER = 0x040, -    VMS_VARRAY_UINT16    = 0x080,  /* Array with size in uint16_t field */ -    VMS_VBUFFER          = 0x100,  /* Buffer with size in int32_t field */ -    VMS_MULTIPLY         = 0x200,  /* multiply "size" field by field_size */ -    VMS_VARRAY_UINT8     = 0x400,  /* Array with size in uint8_t field*/ -    VMS_VARRAY_UINT32    = 0x800,  /* Array with size in uint32_t field*/ -}; - -typedef struct { -    const char *name; -    size_t offset; -    size_t size; -    size_t start; -    int num; -    size_t num_offset; -    size_t size_offset; -    const VMStateInfo *info; -    enum VMStateFlags flags; -    const VMStateDescription *vmsd; -    int version_id; -    bool (*field_exists)(void *opaque, int version_id); -} VMStateField; - -typedef struct VMStateSubsection { -    const VMStateDescription *vmsd; -    bool (*needed)(void *opaque); -} VMStateSubsection; - -struct VMStateDescription { -    const char *name; -    int unmigratable; -    int version_id; -    int minimum_version_id; -    int minimum_version_id_old; -    LoadStateHandler *load_state_old; -    int (*pre_load)(void *opaque); -    int (*post_load)(void *opaque, int version_id); -    void (*pre_save)(void *opaque); -    VMStateField *fields; -    const VMStateSubsection *subsections; -}; - -#ifdef CONFIG_USER_ONLY -extern const VMStateDescription vmstate_dummy; -#endif - -extern const VMStateInfo vmstate_info_bool; - -extern const VMStateInfo vmstate_info_int8; -extern const VMStateInfo vmstate_info_int16; -extern const VMStateInfo vmstate_info_int32; -extern const VMStateInfo vmstate_info_int64; - -extern const VMStateInfo vmstate_info_uint8_equal; -extern const VMStateInfo vmstate_info_uint16_equal; -extern const VMStateInfo vmstate_info_int32_equal; -extern const VMStateInfo vmstate_info_uint32_equal; -extern const VMStateInfo vmstate_info_uint64_equal; -extern const VMStateInfo vmstate_info_int32_le; - -extern const VMStateInfo vmstate_info_uint8; -extern const VMStateInfo vmstate_info_uint16; -extern const VMStateInfo vmstate_info_uint32; -extern const VMStateInfo vmstate_info_uint64; - -extern const VMStateInfo vmstate_info_float64; - -extern const VMStateInfo vmstate_info_timer; -extern const VMStateInfo vmstate_info_buffer; -extern const VMStateInfo vmstate_info_unused_buffer; -extern const VMStateInfo vmstate_info_bitmap; - -#define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0) -#define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0) -#define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0) - -#define vmstate_offset_value(_state, _field, _type)                  \ -    (offsetof(_state, _field) +                                      \ -     type_check(_type, typeof_field(_state, _field))) - -#define vmstate_offset_pointer(_state, _field, _type)                \ -    (offsetof(_state, _field) +                                      \ -     type_check_pointer(_type, typeof_field(_state, _field))) - -#define vmstate_offset_array(_state, _field, _type, _num)            \ -    (offsetof(_state, _field) +                                      \ -     type_check_array(_type, typeof_field(_state, _field), _num)) - -#define vmstate_offset_2darray(_state, _field, _type, _n1, _n2)      \ -    (offsetof(_state, _field) +                                      \ -     type_check_2darray(_type, typeof_field(_state, _field), _n1, _n2)) - -#define vmstate_offset_sub_array(_state, _field, _type, _start)      \ -    (offsetof(_state, _field[_start])) - -#define vmstate_offset_buffer(_state, _field)                        \ -    vmstate_offset_array(_state, _field, uint8_t,                    \ -                         sizeof(typeof_field(_state, _field))) - -#define VMSTATE_SINGLE_TEST(_field, _state, _test, _version, _info, _type) { \ -    .name         = (stringify(_field)),                             \ -    .version_id   = (_version),                                      \ -    .field_exists = (_test),                                         \ -    .size         = sizeof(_type),                                   \ -    .info         = &(_info),                                        \ -    .flags        = VMS_SINGLE,                                      \ -    .offset       = vmstate_offset_value(_state, _field, _type),     \ -} - -#define VMSTATE_POINTER(_field, _state, _version, _info, _type) {    \ -    .name       = (stringify(_field)),                               \ -    .version_id = (_version),                                        \ -    .info       = &(_info),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_SINGLE|VMS_POINTER,                            \ -    .offset     = vmstate_offset_value(_state, _field, _type),       \ -} - -#define VMSTATE_POINTER_TEST(_field, _state, _test, _info, _type) {  \ -    .name       = (stringify(_field)),                               \ -    .info       = &(_info),                                          \ -    .field_exists = (_test),                                         \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_SINGLE|VMS_POINTER,                            \ -    .offset     = vmstate_offset_value(_state, _field, _type),       \ -} - -#define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) {\ -    .name       = (stringify(_field)),                               \ -    .version_id = (_version),                                        \ -    .num        = (_num),                                            \ -    .info       = &(_info),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_ARRAY,                                         \ -    .offset     = vmstate_offset_array(_state, _field, _type, _num), \ -} - -#define VMSTATE_2DARRAY(_field, _state, _n1, _n2, _version, _info, _type) { \ -    .name       = (stringify(_field)),                                      \ -    .version_id = (_version),                                               \ -    .num        = (_n1) * (_n2),                                            \ -    .info       = &(_info),                                                 \ -    .size       = sizeof(_type),                                            \ -    .flags      = VMS_ARRAY,                                                \ -    .offset     = vmstate_offset_2darray(_state, _field, _type, _n1, _n2),  \ -} - -#define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\ -    .name         = (stringify(_field)),                              \ -    .field_exists = (_test),                                          \ -    .num          = (_num),                                           \ -    .info         = &(_info),                                         \ -    .size         = sizeof(_type),                                    \ -    .flags        = VMS_ARRAY,                                        \ -    .offset       = vmstate_offset_array(_state, _field, _type, _num),\ -} - -#define VMSTATE_SUB_ARRAY(_field, _state, _start, _num, _version, _info, _type) { \ -    .name       = (stringify(_field)),                               \ -    .version_id = (_version),                                        \ -    .num        = (_num),                                            \ -    .info       = &(_info),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_ARRAY,                                         \ -    .offset     = vmstate_offset_sub_array(_state, _field, _type, _start), \ -} - -#define VMSTATE_ARRAY_INT32_UNSAFE(_field, _state, _field_num, _info, _type) {\ -    .name       = (stringify(_field)),                               \ -    .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ -    .info       = &(_info),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_VARRAY_INT32,                                  \ -    .offset     = offsetof(_state, _field),                          \ -} - -#define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\ -    .name       = (stringify(_field)),                               \ -    .version_id = (_version),                                        \ -    .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ -    .info       = &(_info),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_VARRAY_INT32|VMS_POINTER,                      \ -    .offset     = vmstate_offset_pointer(_state, _field, _type),     \ -} - -#define VMSTATE_VARRAY_UINT32(_field, _state, _field_num, _version, _info, _type) {\ -    .name       = (stringify(_field)),                               \ -    .version_id = (_version),                                        \ -    .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ -    .info       = &(_info),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_VARRAY_UINT32|VMS_POINTER,                     \ -    .offset     = vmstate_offset_pointer(_state, _field, _type),     \ -} - -#define VMSTATE_VARRAY_UINT16_UNSAFE(_field, _state, _field_num, _version, _info, _type) {\ -    .name       = (stringify(_field)),                               \ -    .version_id = (_version),                                        \ -    .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\ -    .info       = &(_info),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_VARRAY_UINT16,                                 \ -    .offset     = offsetof(_state, _field),                          \ -} - -#define VMSTATE_STRUCT_TEST(_field, _state, _test, _version, _vmsd, _type) { \ -    .name         = (stringify(_field)),                             \ -    .version_id   = (_version),                                      \ -    .field_exists = (_test),                                         \ -    .vmsd         = &(_vmsd),                                        \ -    .size         = sizeof(_type),                                   \ -    .flags        = VMS_STRUCT,                                      \ -    .offset       = vmstate_offset_value(_state, _field, _type),     \ -} - -#define VMSTATE_STRUCT_POINTER_TEST(_field, _state, _test, _vmsd, _type) { \ -    .name         = (stringify(_field)),                             \ -    .field_exists = (_test),                                         \ -    .vmsd         = &(_vmsd),                                        \ -    .size         = sizeof(_type),                                   \ -    .flags        = VMS_STRUCT|VMS_POINTER,                          \ -    .offset       = vmstate_offset_value(_state, _field, _type),     \ -} - -#define VMSTATE_ARRAY_OF_POINTER(_field, _state, _num, _version, _info, _type) {\ -    .name       = (stringify(_field)),                               \ -    .version_id = (_version),                                        \ -    .num        = (_num),                                            \ -    .info       = &(_info),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_ARRAY|VMS_ARRAY_OF_POINTER,                    \ -    .offset     = vmstate_offset_array(_state, _field, _type, _num), \ -} - -#define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, _vmsd, _type) { \ -    .name         = (stringify(_field)),                             \ -    .num          = (_num),                                          \ -    .field_exists = (_test),                                         \ -    .version_id   = (_version),                                      \ -    .vmsd         = &(_vmsd),                                        \ -    .size         = sizeof(_type),                                   \ -    .flags        = VMS_STRUCT|VMS_ARRAY,                            \ -    .offset       = vmstate_offset_array(_state, _field, _type, _num),\ -} - -#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \ -    .name       = (stringify(_field)),                               \ -    .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \ -    .version_id = (_version),                                        \ -    .vmsd       = &(_vmsd),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_STRUCT|VMS_VARRAY_UINT8,                       \ -    .offset     = offsetof(_state, _field),                          \ -} - -#define VMSTATE_STRUCT_VARRAY_POINTER_INT32(_field, _state, _field_num, _vmsd, _type) { \ -    .name       = (stringify(_field)),                               \ -    .version_id = 0,                                                 \ -    .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ -    .size       = sizeof(_type),                                     \ -    .vmsd       = &(_vmsd),                                          \ -    .flags      = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT,       \ -    .offset     = vmstate_offset_pointer(_state, _field, _type),     \ -} - -#define VMSTATE_STRUCT_VARRAY_POINTER_UINT32(_field, _state, _field_num, _vmsd, _type) { \ -    .name       = (stringify(_field)),                               \ -    .version_id = 0,                                                 \ -    .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ -    .size       = sizeof(_type),                                     \ -    .vmsd       = &(_vmsd),                                          \ -    .flags      = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT,       \ -    .offset     = vmstate_offset_pointer(_state, _field, _type),     \ -} - -#define VMSTATE_STRUCT_VARRAY_POINTER_UINT16(_field, _state, _field_num, _vmsd, _type) { \ -    .name       = (stringify(_field)),                               \ -    .version_id = 0,                                                 \ -    .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\ -    .size       = sizeof(_type),                                     \ -    .vmsd       = &(_vmsd),                                          \ -    .flags      = VMS_POINTER | VMS_VARRAY_UINT16 | VMS_STRUCT,      \ -    .offset     = vmstate_offset_pointer(_state, _field, _type),     \ -} - -#define VMSTATE_STRUCT_VARRAY_INT32(_field, _state, _field_num, _version, _vmsd, _type) { \ -    .name       = (stringify(_field)),                               \ -    .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ -    .version_id = (_version),                                        \ -    .vmsd       = &(_vmsd),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_STRUCT|VMS_VARRAY_INT32,                       \ -    .offset     = offsetof(_state, _field),                          \ -} - -#define VMSTATE_STRUCT_VARRAY_UINT32(_field, _state, _field_num, _version, _vmsd, _type) { \ -    .name       = (stringify(_field)),                               \ -    .num_offset = vmstate_offset_value(_state, _field_num, uint32_t), \ -    .version_id = (_version),                                        \ -    .vmsd       = &(_vmsd),                                          \ -    .size       = sizeof(_type),                                     \ -    .flags      = VMS_STRUCT|VMS_VARRAY_UINT32,                      \ -    .offset     = offsetof(_state, _field),                          \ -} - -#define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \ -    .name         = (stringify(_field)),                             \ -    .version_id   = (_version),                                      \ -    .field_exists = (_test),                                         \ -    .size         = (_size - _start),                                \ -    .info         = &vmstate_info_buffer,                            \ -    .flags        = VMS_BUFFER,                                      \ -    .offset       = vmstate_offset_buffer(_state, _field) + _start,  \ -} - -#define VMSTATE_VBUFFER_MULTIPLY(_field, _state, _version, _test, _start, _field_size, _multiply) { \ -    .name         = (stringify(_field)),                             \ -    .version_id   = (_version),                                      \ -    .field_exists = (_test),                                         \ -    .size_offset  = vmstate_offset_value(_state, _field_size, uint32_t),\ -    .size         = (_multiply),                                      \ -    .info         = &vmstate_info_buffer,                            \ -    .flags        = VMS_VBUFFER|VMS_POINTER|VMS_MULTIPLY,            \ -    .offset       = offsetof(_state, _field),                        \ -    .start        = (_start),                                        \ -} - -#define VMSTATE_VBUFFER(_field, _state, _version, _test, _start, _field_size) { \ -    .name         = (stringify(_field)),                             \ -    .version_id   = (_version),                                      \ -    .field_exists = (_test),                                         \ -    .size_offset  = vmstate_offset_value(_state, _field_size, int32_t),\ -    .info         = &vmstate_info_buffer,                            \ -    .flags        = VMS_VBUFFER|VMS_POINTER,                         \ -    .offset       = offsetof(_state, _field),                        \ -    .start        = (_start),                                        \ -} - -#define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _start, _field_size) { \ -    .name         = (stringify(_field)),                             \ -    .version_id   = (_version),                                      \ -    .field_exists = (_test),                                         \ -    .size_offset  = vmstate_offset_value(_state, _field_size, uint32_t),\ -    .info         = &vmstate_info_buffer,                            \ -    .flags        = VMS_VBUFFER|VMS_POINTER,                         \ -    .offset       = offsetof(_state, _field),                        \ -    .start        = (_start),                                        \ -} - -#define VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, _info, _size) { \ -    .name       = (stringify(_field)),                               \ -    .version_id = (_version),                                        \ -    .size       = (_size),                                           \ -    .info       = &(_info),                                          \ -    .flags      = VMS_BUFFER,                                        \ -    .offset     = offsetof(_state, _field),                          \ -} - -#define VMSTATE_BUFFER_POINTER_UNSAFE(_field, _state, _version, _size) { \ -    .name       = (stringify(_field)),                               \ -    .version_id = (_version),                                        \ -    .size       = (_size),                                           \ -    .info       = &vmstate_info_buffer,                              \ -    .flags      = VMS_BUFFER|VMS_POINTER,                            \ -    .offset     = offsetof(_state, _field),                          \ -} - -#define VMSTATE_UNUSED_BUFFER(_test, _version, _size) {              \ -    .name         = "unused",                                        \ -    .field_exists = (_test),                                         \ -    .version_id   = (_version),                                      \ -    .size         = (_size),                                         \ -    .info         = &vmstate_info_unused_buffer,                     \ -    .flags        = VMS_BUFFER,                                      \ -} - -/* _field_size should be a int32_t field in the _state struct giving the - * size of the bitmap _field in bits. - */ -#define VMSTATE_BITMAP(_field, _state, _version, _field_size) {      \ -    .name         = (stringify(_field)),                             \ -    .version_id   = (_version),                                      \ -    .size_offset  = vmstate_offset_value(_state, _field_size, int32_t),\ -    .info         = &vmstate_info_bitmap,                            \ -    .flags        = VMS_VBUFFER|VMS_POINTER,                         \ -    .offset       = offsetof(_state, _field),                        \ -} - -/* _f : field name -   _f_n : num of elements field_name -   _n : num of elements -   _s : struct state name -   _v : version -*/ - -#define VMSTATE_SINGLE(_field, _state, _version, _info, _type)        \ -    VMSTATE_SINGLE_TEST(_field, _state, NULL, _version, _info, _type) - -#define VMSTATE_STRUCT(_field, _state, _version, _vmsd, _type)        \ -    VMSTATE_STRUCT_TEST(_field, _state, NULL, _version, _vmsd, _type) - -#define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type)          \ -    VMSTATE_STRUCT_POINTER_TEST(_field, _state, NULL, _vmsd, _type) - -#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) \ -    VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version,   \ -            _vmsd, _type) - -#define VMSTATE_BOOL_V(_f, _s, _v)                                    \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_bool, bool) - -#define VMSTATE_INT8_V(_f, _s, _v)                                    \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int8, int8_t) -#define VMSTATE_INT16_V(_f, _s, _v)                                   \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int16, int16_t) -#define VMSTATE_INT32_V(_f, _s, _v)                                   \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int32, int32_t) -#define VMSTATE_INT64_V(_f, _s, _v)                                   \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int64, int64_t) - -#define VMSTATE_UINT8_V(_f, _s, _v)                                   \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint8, uint8_t) -#define VMSTATE_UINT16_V(_f, _s, _v)                                  \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16, uint16_t) -#define VMSTATE_UINT32_V(_f, _s, _v)                                  \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32, uint32_t) -#define VMSTATE_UINT64_V(_f, _s, _v)                                  \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64, uint64_t) - -#define VMSTATE_BOOL(_f, _s)                                          \ -    VMSTATE_BOOL_V(_f, _s, 0) - -#define VMSTATE_INT8(_f, _s)                                          \ -    VMSTATE_INT8_V(_f, _s, 0) -#define VMSTATE_INT16(_f, _s)                                         \ -    VMSTATE_INT16_V(_f, _s, 0) -#define VMSTATE_INT32(_f, _s)                                         \ -    VMSTATE_INT32_V(_f, _s, 0) -#define VMSTATE_INT64(_f, _s)                                         \ -    VMSTATE_INT64_V(_f, _s, 0) - -#define VMSTATE_UINT8(_f, _s)                                         \ -    VMSTATE_UINT8_V(_f, _s, 0) -#define VMSTATE_UINT16(_f, _s)                                        \ -    VMSTATE_UINT16_V(_f, _s, 0) -#define VMSTATE_UINT32(_f, _s)                                        \ -    VMSTATE_UINT32_V(_f, _s, 0) -#define VMSTATE_UINT64(_f, _s)                                        \ -    VMSTATE_UINT64_V(_f, _s, 0) - -#define VMSTATE_UINT8_EQUAL(_f, _s)                                   \ -    VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint8_equal, uint8_t) - -#define VMSTATE_UINT16_EQUAL(_f, _s)                                  \ -    VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint16_equal, uint16_t) - -#define VMSTATE_UINT16_EQUAL_V(_f, _s, _v)                            \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16_equal, uint16_t) - -#define VMSTATE_INT32_EQUAL(_f, _s)                                   \ -    VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_equal, int32_t) - -#define VMSTATE_UINT32_EQUAL_V(_f, _s, _v)                            \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32_equal, uint32_t) - -#define VMSTATE_UINT32_EQUAL(_f, _s)                                  \ -    VMSTATE_UINT32_EQUAL_V(_f, _s, 0) - -#define VMSTATE_UINT64_EQUAL_V(_f, _s, _v)                            \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64_equal, uint64_t) - -#define VMSTATE_UINT64_EQUAL(_f, _s)                                  \ -    VMSTATE_UINT64_EQUAL_V(_f, _s, 0) - -#define VMSTATE_INT32_LE(_f, _s)                                   \ -    VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t) - -#define VMSTATE_UINT8_TEST(_f, _s, _t)                               \ -    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t) - -#define VMSTATE_UINT16_TEST(_f, _s, _t)                               \ -    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t) - -#define VMSTATE_UINT32_TEST(_f, _s, _t)                                  \ -    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint32, uint32_t) - - -#define VMSTATE_FLOAT64_V(_f, _s, _v)                                 \ -    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_float64, float64) - -#define VMSTATE_FLOAT64(_f, _s)                                       \ -    VMSTATE_FLOAT64_V(_f, _s, 0) - -#define VMSTATE_TIMER_TEST(_f, _s, _test)                             \ -    VMSTATE_POINTER_TEST(_f, _s, _test, vmstate_info_timer, QEMUTimer *) - -#define VMSTATE_TIMER_V(_f, _s, _v)                                   \ -    VMSTATE_POINTER(_f, _s, _v, vmstate_info_timer, QEMUTimer *) - -#define VMSTATE_TIMER(_f, _s)                                         \ -    VMSTATE_TIMER_V(_f, _s, 0) - -#define VMSTATE_TIMER_ARRAY(_f, _s, _n)                              \ -    VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *) - -#define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v)                         \ -    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool) - -#define VMSTATE_BOOL_ARRAY(_f, _s, _n)                               \ -    VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v)                         \ -    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t) - -#define VMSTATE_UINT16_2DARRAY_V(_f, _s, _n1, _n2, _v)                \ -    VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint16, uint16_t) - -#define VMSTATE_UINT16_ARRAY(_f, _s, _n)                               \ -    VMSTATE_UINT16_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_UINT16_2DARRAY(_f, _s, _n1, _n2)                      \ -    VMSTATE_UINT16_2DARRAY_V(_f, _s, _n1, _n2, 0) - -#define VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, _v)                 \ -    VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint8, uint8_t) - -#define VMSTATE_UINT8_ARRAY_V(_f, _s, _n, _v)                         \ -    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint8, uint8_t) - -#define VMSTATE_UINT8_ARRAY(_f, _s, _n)                               \ -    VMSTATE_UINT8_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_UINT8_2DARRAY(_f, _s, _n1, _n2)                       \ -    VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, 0) - -#define VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)                        \ -    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint32, uint32_t) - -#define VMSTATE_UINT32_ARRAY(_f, _s, _n)                              \ -    VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)                        \ -    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint64, uint64_t) - -#define VMSTATE_UINT64_ARRAY(_f, _s, _n)                              \ -    VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_INT16_ARRAY_V(_f, _s, _n, _v)                         \ -    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int16, int16_t) - -#define VMSTATE_INT16_ARRAY(_f, _s, _n)                               \ -    VMSTATE_INT16_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_INT32_ARRAY_V(_f, _s, _n, _v)                         \ -    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int32, int32_t) - -#define VMSTATE_INT32_ARRAY(_f, _s, _n)                               \ -    VMSTATE_INT32_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num)                \ -    VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t) - -#define VMSTATE_UINT32_ARRAY(_f, _s, _n)                              \ -    VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v)                         \ -    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t) - -#define VMSTATE_INT64_ARRAY(_f, _s, _n)                               \ -    VMSTATE_INT64_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_FLOAT64_ARRAY_V(_f, _s, _n, _v)                       \ -    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_float64, float64) - -#define VMSTATE_FLOAT64_ARRAY(_f, _s, _n)                             \ -    VMSTATE_FLOAT64_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_BUFFER_V(_f, _s, _v)                                  \ -    VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f))) - -#define VMSTATE_BUFFER(_f, _s)                                        \ -    VMSTATE_BUFFER_V(_f, _s, 0) - -#define VMSTATE_PARTIAL_BUFFER(_f, _s, _size)                         \ -    VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, 0, _size) - -#define VMSTATE_BUFFER_START_MIDDLE(_f, _s, _start) \ -    VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, _start, sizeof(typeof_field(_s, _f))) - -#define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size)                        \ -    VMSTATE_VBUFFER(_f, _s, 0, NULL, 0, _size) - -#define VMSTATE_PARTIAL_VBUFFER_UINT32(_f, _s, _size)                        \ -    VMSTATE_VBUFFER_UINT32(_f, _s, 0, NULL, 0, _size) - -#define VMSTATE_SUB_VBUFFER(_f, _s, _start, _size)                    \ -    VMSTATE_VBUFFER(_f, _s, 0, NULL, _start, _size) - -#define VMSTATE_BUFFER_TEST(_f, _s, _test)                            \ -    VMSTATE_STATIC_BUFFER(_f, _s, 0, _test, 0, sizeof(typeof_field(_s, _f))) - -#define VMSTATE_BUFFER_UNSAFE(_field, _state, _version, _size)        \ -    VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, vmstate_info_buffer, _size) - -#define VMSTATE_UNUSED_V(_v, _size)                                   \ -    VMSTATE_UNUSED_BUFFER(NULL, _v, _size) - -#define VMSTATE_UNUSED(_size)                                         \ -    VMSTATE_UNUSED_V(0, _size) - -#define VMSTATE_UNUSED_TEST(_test, _size)                             \ -    VMSTATE_UNUSED_BUFFER(_test, 0, _size) - -#define VMSTATE_END_OF_LIST()                                         \ -    {} - -int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, -                       void *opaque, int version_id); -void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, -                        void *opaque); - -int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, -                                   const VMStateDescription *vmsd, -                                   void *base, int alias_id, -                                   int required_for_version); - -static inline int vmstate_register(DeviceState *dev, int instance_id, -                                   const VMStateDescription *vmsd, -                                   void *opaque) -{ -    return vmstate_register_with_alias_id(dev, instance_id, vmsd, -                                          opaque, -1, 0); -} - -void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, -                        void *opaque); - -struct MemoryRegion; -void vmstate_register_ram(struct MemoryRegion *memory, DeviceState *dev); -void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *dev); -void vmstate_register_ram_global(struct MemoryRegion *memory); - -#endif diff --git a/contrib/qemu/include/monitor/monitor.h b/contrib/qemu/include/monitor/monitor.h deleted file mode 100644 index 1942cc42fe2..00000000000 --- a/contrib/qemu/include/monitor/monitor.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef MONITOR_H -#define MONITOR_H - -#include "qemu-common.h" -#include "qapi/qmp/qerror.h" -#include "qapi/qmp/qdict.h" -#include "block/block.h" -#include "monitor/readline.h" - -extern Monitor *cur_mon; -extern Monitor *default_mon; - -/* flags for monitor_init */ -#define MONITOR_IS_DEFAULT    0x01 -#define MONITOR_USE_READLINE  0x02 -#define MONITOR_USE_CONTROL   0x04 -#define MONITOR_USE_PRETTY    0x08 - -/* flags for monitor commands */ -#define MONITOR_CMD_ASYNC       0x0001 - -/* QMP events */ -typedef enum MonitorEvent { -    QEVENT_SHUTDOWN, -    QEVENT_RESET, -    QEVENT_POWERDOWN, -    QEVENT_STOP, -    QEVENT_RESUME, -    QEVENT_VNC_CONNECTED, -    QEVENT_VNC_INITIALIZED, -    QEVENT_VNC_DISCONNECTED, -    QEVENT_BLOCK_IO_ERROR, -    QEVENT_RTC_CHANGE, -    QEVENT_WATCHDOG, -    QEVENT_SPICE_CONNECTED, -    QEVENT_SPICE_INITIALIZED, -    QEVENT_SPICE_DISCONNECTED, -    QEVENT_BLOCK_JOB_COMPLETED, -    QEVENT_BLOCK_JOB_CANCELLED, -    QEVENT_BLOCK_JOB_ERROR, -    QEVENT_BLOCK_JOB_READY, -    QEVENT_DEVICE_DELETED, -    QEVENT_DEVICE_TRAY_MOVED, -    QEVENT_NIC_RX_FILTER_CHANGED, -    QEVENT_SUSPEND, -    QEVENT_SUSPEND_DISK, -    QEVENT_WAKEUP, -    QEVENT_BALLOON_CHANGE, -    QEVENT_SPICE_MIGRATE_COMPLETED, -    QEVENT_GUEST_PANICKED, - -    /* Add to 'monitor_event_names' array in monitor.c when -     * defining new events here */ - -    QEVENT_MAX, -} MonitorEvent; - -int monitor_cur_is_qmp(void); - -void monitor_protocol_event(MonitorEvent event, QObject *data); -void monitor_init(CharDriverState *chr, int flags); - -int monitor_suspend(Monitor *mon); -void monitor_resume(Monitor *mon); - -int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, -                                BlockDriverCompletionFunc *completion_cb, -                                void *opaque); -int monitor_read_block_device_key(Monitor *mon, const char *device, -                                  BlockDriverCompletionFunc *completion_cb, -                                  void *opaque); - -int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp); -int monitor_handle_fd_param(Monitor *mon, const char *fdname); - -void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) -    GCC_FMT_ATTR(2, 0); -void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -void monitor_print_filename(Monitor *mon, const char *filename); -void monitor_flush(Monitor *mon); -int monitor_set_cpu(int cpu_index); -int monitor_get_cpu_index(void); - -typedef void (MonitorCompletion)(void *opaque, QObject *ret_data); - -void monitor_set_error(Monitor *mon, QError *qerror); -void monitor_read_command(Monitor *mon, int show_prompt); -ReadLineState *monitor_get_rs(Monitor *mon); -int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, -                          void *opaque); - -int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret); - -int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret); - -AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id, -                                bool has_opaque, const char *opaque, -                                Error **errp); -int monitor_fdset_get_fd(int64_t fdset_id, int flags); -int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd); -int monitor_fdset_dup_fd_remove(int dup_fd); -int monitor_fdset_dup_fd_find(int dup_fd); - -#endif /* !MONITOR_H */ diff --git a/contrib/qemu/include/monitor/readline.h b/contrib/qemu/include/monitor/readline.h deleted file mode 100644 index fc9806ecf1a..00000000000 --- a/contrib/qemu/include/monitor/readline.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef READLINE_H -#define READLINE_H - -#include "qemu-common.h" - -#define READLINE_CMD_BUF_SIZE 4095 -#define READLINE_MAX_CMDS 64 -#define READLINE_MAX_COMPLETIONS 256 - -typedef void ReadLineFunc(Monitor *mon, const char *str, void *opaque); -typedef void ReadLineCompletionFunc(const char *cmdline); - -typedef struct ReadLineState { -    char cmd_buf[READLINE_CMD_BUF_SIZE + 1]; -    int cmd_buf_index; -    int cmd_buf_size; - -    char last_cmd_buf[READLINE_CMD_BUF_SIZE + 1]; -    int last_cmd_buf_index; -    int last_cmd_buf_size; - -    int esc_state; -    int esc_param; - -    char *history[READLINE_MAX_CMDS]; -    int hist_entry; - -    ReadLineCompletionFunc *completion_finder; -    char *completions[READLINE_MAX_COMPLETIONS]; -    int nb_completions; -    int completion_index; - -    ReadLineFunc *readline_func; -    void *readline_opaque; -    int read_password; -    char prompt[256]; -    Monitor *mon; -} ReadLineState; - -void readline_add_completion(ReadLineState *rs, const char *str); -void readline_set_completion_index(ReadLineState *rs, int completion_index); - -const char *readline_get_history(ReadLineState *rs, unsigned int index); - -void readline_handle_byte(ReadLineState *rs, int ch); - -void readline_start(ReadLineState *rs, const char *prompt, int read_password, -                    ReadLineFunc *readline_func, void *opaque); -void readline_restart(ReadLineState *rs); -void readline_show_prompt(ReadLineState *rs); - -ReadLineState *readline_init(Monitor *mon, -                             ReadLineCompletionFunc *completion_finder); - -#endif /* !READLINE_H */ diff --git a/contrib/qemu/include/qapi/error.h b/contrib/qemu/include/qapi/error.h deleted file mode 100644 index ffd1cea4772..00000000000 --- a/contrib/qemu/include/qapi/error.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * QEMU Error Objects - * - * Copyright IBM, Corp. 2011 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.  See - * the COPYING.LIB file in the top-level directory. - */ -#ifndef ERROR_H -#define ERROR_H - -#include "qemu/compiler.h" -#include "qapi-types.h" -#include <stdbool.h> - -/** - * A class representing internal errors within QEMU.  An error has a ErrorClass - * code and a human message. - */ -typedef struct Error Error; - -/** - * Set an indirect pointer to an error given a ErrorClass value and a - * printf-style human message.  This function is not meant to be used outside - * of QEMU. - */ -void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(3, 4); - -/** - * Set an indirect pointer to an error given a ErrorClass value and a - * printf-style human message, followed by a strerror() string if - * @os_error is not zero. - */ -void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5); - -/** - * Same as error_set(), but sets a generic error - */ -#define error_setg(err, fmt, ...) \ -    error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__) -#define error_setg_errno(err, os_error, fmt, ...) \ -    error_set_errno(err, os_error, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__) - -/** - * Helper for open() errors - */ -void error_setg_file_open(Error **errp, int os_errno, const char *filename); - -/** - * Returns true if an indirect pointer to an error is pointing to a valid - * error object. - */ -bool error_is_set(Error **err); - -/* - * Get the error class of an error object. - */ -ErrorClass error_get_class(const Error *err); - -/** - * Returns an exact copy of the error passed as an argument. - */ -Error *error_copy(const Error *err); - -/** - * Get a human readable representation of an error object. - */ -const char *error_get_pretty(Error *err); - -/** - * Propagate an error to an indirect pointer to an error.  This function will - * always transfer ownership of the error reference and handles the case where - * dst_err is NULL correctly.  Errors after the first are discarded. - */ -void error_propagate(Error **dst_err, Error *local_err); - -/** - * Free an error object. - */ -void error_free(Error *err); - -#endif diff --git a/contrib/qemu/include/qapi/qmp/json-lexer.h b/contrib/qemu/include/qapi/qmp/json-lexer.h deleted file mode 100644 index cdff0460a83..00000000000 --- a/contrib/qemu/include/qapi/qmp/json-lexer.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * JSON lexer - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef QEMU_JSON_LEXER_H -#define QEMU_JSON_LEXER_H - -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qlist.h" - -typedef enum json_token_type { -    JSON_OPERATOR = 100, -    JSON_INTEGER, -    JSON_FLOAT, -    JSON_KEYWORD, -    JSON_STRING, -    JSON_ESCAPE, -    JSON_SKIP, -    JSON_ERROR, -} JSONTokenType; - -typedef struct JSONLexer JSONLexer; - -typedef void (JSONLexerEmitter)(JSONLexer *, QString *, JSONTokenType, int x, int y); - -struct JSONLexer -{ -    JSONLexerEmitter *emit; -    int state; -    QString *token; -    int x, y; -}; - -void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func); - -int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size); - -int json_lexer_flush(JSONLexer *lexer); - -void json_lexer_destroy(JSONLexer *lexer); - -#endif diff --git a/contrib/qemu/include/qapi/qmp/json-parser.h b/contrib/qemu/include/qapi/qmp/json-parser.h deleted file mode 100644 index 44d88f34685..00000000000 --- a/contrib/qemu/include/qapi/qmp/json-parser.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * JSON Parser  - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef QEMU_JSON_PARSER_H -#define QEMU_JSON_PARSER_H - -#include "qemu-common.h" -#include "qapi/qmp/qlist.h" -#include "qapi/error.h" - -QObject *json_parser_parse(QList *tokens, va_list *ap); -QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp); - -#endif diff --git a/contrib/qemu/include/qapi/qmp/json-streamer.h b/contrib/qemu/include/qapi/qmp/json-streamer.h deleted file mode 100644 index 823f7d7fa42..00000000000 --- a/contrib/qemu/include/qapi/qmp/json-streamer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * JSON streaming support - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef QEMU_JSON_STREAMER_H -#define QEMU_JSON_STREAMER_H - -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/json-lexer.h" - -typedef struct JSONMessageParser -{ -    void (*emit)(struct JSONMessageParser *parser, QList *tokens); -    JSONLexer lexer; -    int brace_count; -    int bracket_count; -    QList *tokens; -    uint64_t token_size; -} JSONMessageParser; - -void json_message_parser_init(JSONMessageParser *parser, -                              void (*func)(JSONMessageParser *, QList *)); - -int json_message_parser_feed(JSONMessageParser *parser, -                             const char *buffer, size_t size); - -int json_message_parser_flush(JSONMessageParser *parser); - -void json_message_parser_destroy(JSONMessageParser *parser); - -#endif diff --git a/contrib/qemu/include/qapi/qmp/qbool.h b/contrib/qemu/include/qapi/qmp/qbool.h deleted file mode 100644 index c4eaab9bb9f..00000000000 --- a/contrib/qemu/include/qapi/qmp/qbool.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * QBool Module - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef QBOOL_H -#define QBOOL_H - -#include <stdint.h> -#include "qapi/qmp/qobject.h" - -typedef struct QBool { -    QObject_HEAD; -    int value; -} QBool; - -QBool *qbool_from_int(int value); -int qbool_get_int(const QBool *qb); -QBool *qobject_to_qbool(const QObject *obj); - -#endif /* QBOOL_H */ diff --git a/contrib/qemu/include/qapi/qmp/qdict.h b/contrib/qemu/include/qapi/qmp/qdict.h deleted file mode 100644 index 685b2e3fcbb..00000000000 --- a/contrib/qemu/include/qapi/qmp/qdict.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * QDict Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#ifndef QDICT_H -#define QDICT_H - -#include "qapi/qmp/qobject.h" -#include "qapi/qmp/qlist.h" -#include "qemu/queue.h" -#include <stdint.h> - -#define QDICT_BUCKET_MAX 512 - -typedef struct QDictEntry { -    char *key; -    QObject *value; -    QLIST_ENTRY(QDictEntry) next; -} QDictEntry; - -typedef struct QDict { -    QObject_HEAD; -    size_t size; -    QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX]; -} QDict; - -/* Object API */ -QDict *qdict_new(void); -const char *qdict_entry_key(const QDictEntry *entry); -QObject *qdict_entry_value(const QDictEntry *entry); -size_t qdict_size(const QDict *qdict); -void qdict_put_obj(QDict *qdict, const char *key, QObject *value); -void qdict_del(QDict *qdict, const char *key); -int qdict_haskey(const QDict *qdict, const char *key); -QObject *qdict_get(const QDict *qdict, const char *key); -QDict *qobject_to_qdict(const QObject *obj); -void qdict_iter(const QDict *qdict, -                void (*iter)(const char *key, QObject *obj, void *opaque), -                void *opaque); -const QDictEntry *qdict_first(const QDict *qdict); -const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry); - -/* Helper to qdict_put_obj(), accepts any object */ -#define qdict_put(qdict, key, obj) \ -        qdict_put_obj(qdict, key, QOBJECT(obj)) - -/* High level helpers */ -double qdict_get_double(const QDict *qdict, const char *key); -int64_t qdict_get_int(const QDict *qdict, const char *key); -int qdict_get_bool(const QDict *qdict, const char *key); -QList *qdict_get_qlist(const QDict *qdict, const char *key); -QDict *qdict_get_qdict(const QDict *qdict, const char *key); -const char *qdict_get_str(const QDict *qdict, const char *key); -int64_t qdict_get_try_int(const QDict *qdict, const char *key, -                          int64_t def_value); -int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value); -const char *qdict_get_try_str(const QDict *qdict, const char *key); - -QDict *qdict_clone_shallow(const QDict *src); - -#endif /* QDICT_H */ diff --git a/contrib/qemu/include/qapi/qmp/qerror.h b/contrib/qemu/include/qapi/qmp/qerror.h deleted file mode 100644 index c30c2f6d7a3..00000000000 --- a/contrib/qemu/include/qapi/qmp/qerror.h +++ /dev/null @@ -1,249 +0,0 @@ -/* - * QError Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ -#ifndef QERROR_H -#define QERROR_H - -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" -#include "qemu/error-report.h" -#include "qapi/error.h" -#include "qapi-types.h" -#include <stdarg.h> - -typedef struct QError { -    QObject_HEAD; -    Location loc; -    char *err_msg; -    ErrorClass err_class; -} QError; - -QString *qerror_human(const QError *qerror); -void qerror_report(ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -void qerror_report_err(Error *err); -void assert_no_error(Error *err); - -/* - * QError class list - * Please keep the definitions in alphabetical order. - * Use scripts/check-qerror.sh to check. - */ -#define QERR_ADD_CLIENT_FAILED \ -    ERROR_CLASS_GENERIC_ERROR, "Could not add client" - -#define QERR_AMBIGUOUS_PATH \ -    ERROR_CLASS_GENERIC_ERROR, "Path '%s' does not uniquely identify an object" - -#define QERR_BAD_BUS_FOR_DEVICE \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' can't go on a %s bus" - -#define QERR_BASE_NOT_FOUND \ -    ERROR_CLASS_GENERIC_ERROR, "Base '%s' not found" - -#define QERR_BLOCK_JOB_NOT_ACTIVE \ -    ERROR_CLASS_DEVICE_NOT_ACTIVE, "No active block job on device '%s'" - -#define QERR_BLOCK_JOB_PAUSED \ -    ERROR_CLASS_GENERIC_ERROR, "The block job for device '%s' is currently paused" - -#define QERR_BLOCK_JOB_NOT_READY \ -    ERROR_CLASS_GENERIC_ERROR, "The active block job for device '%s' cannot be completed" - -#define QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED \ -    ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by device '%s' does not support feature '%s'" - -#define QERR_BUFFER_OVERRUN \ -    ERROR_CLASS_GENERIC_ERROR, "An internal buffer overran" - -#define QERR_BUS_NO_HOTPLUG \ -    ERROR_CLASS_GENERIC_ERROR, "Bus '%s' does not support hotplugging" - -#define QERR_BUS_NOT_FOUND \ -    ERROR_CLASS_GENERIC_ERROR, "Bus '%s' not found" - -#define QERR_COMMAND_DISABLED \ -    ERROR_CLASS_GENERIC_ERROR, "The command %s has been disabled for this instance" - -#define QERR_COMMAND_NOT_FOUND \ -    ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found" - -#define QERR_DEVICE_ENCRYPTED \ -    ERROR_CLASS_DEVICE_ENCRYPTED, "'%s' (%s) is encrypted" - -#define QERR_DEVICE_FEATURE_BLOCKS_MIGRATION \ -    ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when using feature '%s' in device '%s'" - -#define QERR_DEVICE_HAS_NO_MEDIUM \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no medium" - -#define QERR_DEVICE_INIT_FAILED \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' could not be initialized" - -#define QERR_DEVICE_IN_USE \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is in use" - -#define QERR_DEVICE_IS_READ_ONLY \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is read only" - -#define QERR_DEVICE_LOCKED \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is locked" - -#define QERR_DEVICE_MULTIPLE_BUSSES \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' has multiple child busses" - -#define QERR_DEVICE_NO_BUS \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no child bus" - -#define QERR_DEVICE_NO_HOTPLUG \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' does not support hotplugging" - -#define QERR_DEVICE_NOT_ACTIVE \ -    ERROR_CLASS_DEVICE_NOT_ACTIVE, "Device '%s' has not been activated" - -#define QERR_DEVICE_NOT_ENCRYPTED \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not encrypted" - -#define QERR_DEVICE_NOT_FOUND \ -    ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found" - -#define QERR_DEVICE_NOT_REMOVABLE \ -    ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not removable" - -#define QERR_DUPLICATE_ID \ -    ERROR_CLASS_GENERIC_ERROR, "Duplicate ID '%s' for %s" - -#define QERR_FD_NOT_FOUND \ -    ERROR_CLASS_GENERIC_ERROR, "File descriptor named '%s' not found" - -#define QERR_FD_NOT_SUPPLIED \ -    ERROR_CLASS_GENERIC_ERROR, "No file descriptor supplied via SCM_RIGHTS" - -#define QERR_FEATURE_DISABLED \ -    ERROR_CLASS_GENERIC_ERROR, "The feature '%s' is not enabled" - -#define QERR_INVALID_BLOCK_FORMAT \ -    ERROR_CLASS_GENERIC_ERROR, "Invalid block format '%s'" - -#define QERR_INVALID_OPTION_GROUP \ -    ERROR_CLASS_GENERIC_ERROR, "There is no option group '%s'" - -#define QERR_INVALID_PARAMETER \ -    ERROR_CLASS_GENERIC_ERROR, "Invalid parameter '%s'" - -#define QERR_INVALID_PARAMETER_COMBINATION \ -    ERROR_CLASS_GENERIC_ERROR, "Invalid parameter combination" - -#define QERR_INVALID_PARAMETER_TYPE \ -    ERROR_CLASS_GENERIC_ERROR, "Invalid parameter type for '%s', expected: %s" - -#define QERR_INVALID_PARAMETER_VALUE \ -    ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' expects %s" - -#define QERR_INVALID_PASSWORD \ -    ERROR_CLASS_GENERIC_ERROR, "Password incorrect" - -#define QERR_IO_ERROR \ -    ERROR_CLASS_GENERIC_ERROR, "An IO error has occurred" - -#define QERR_JSON_PARSE_ERROR \ -    ERROR_CLASS_GENERIC_ERROR, "JSON parse error, %s" - -#define QERR_JSON_PARSING \ -    ERROR_CLASS_GENERIC_ERROR, "Invalid JSON syntax" - -#define QERR_KVM_MISSING_CAP \ -    ERROR_CLASS_K_V_M_MISSING_CAP, "Using KVM without %s, %s unavailable" - -#define QERR_MIGRATION_ACTIVE \ -    ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress" - -#define QERR_MIGRATION_NOT_SUPPORTED \ -    ERROR_CLASS_GENERIC_ERROR, "State blocked by non-migratable device '%s'" - -#define QERR_MISSING_PARAMETER \ -    ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' is missing" - -#define QERR_NO_BUS_FOR_DEVICE \ -    ERROR_CLASS_GENERIC_ERROR, "No '%s' bus found for device '%s'" - -#define QERR_NOT_SUPPORTED \ -    ERROR_CLASS_GENERIC_ERROR, "Not supported" - -#define QERR_PERMISSION_DENIED \ -    ERROR_CLASS_GENERIC_ERROR, "Insufficient permission to perform this operation" - -#define QERR_PROPERTY_NOT_FOUND \ -    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' not found" - -#define QERR_PROPERTY_VALUE_BAD \ -    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' doesn't take value '%s'" - -#define QERR_PROPERTY_VALUE_IN_USE \ -    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't take value '%s', it's in use" - -#define QERR_PROPERTY_VALUE_NOT_FOUND \ -    ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't find value '%s'" - -#define QERR_PROPERTY_VALUE_NOT_POWER_OF_2 \ -    ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2" - -#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \ -    ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")" - -#define QERR_QGA_COMMAND_FAILED \ -    ERROR_CLASS_GENERIC_ERROR, "Guest agent command failed, error was '%s'" - -#define QERR_QGA_LOGGING_FAILED \ -    ERROR_CLASS_GENERIC_ERROR, "Guest agent failed to log non-optional log statement" - -#define QERR_QMP_BAD_INPUT_OBJECT \ -    ERROR_CLASS_GENERIC_ERROR, "Expected '%s' in QMP input" - -#define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \ -    ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' expects '%s'" - -#define QERR_QMP_EXTRA_MEMBER \ -    ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' is unexpected" - -#define QERR_RESET_REQUIRED \ -    ERROR_CLASS_GENERIC_ERROR, "Resetting the Virtual Machine is required" - -#define QERR_SET_PASSWD_FAILED \ -    ERROR_CLASS_GENERIC_ERROR, "Could not set password" - -#define QERR_TOO_MANY_FILES \ -    ERROR_CLASS_GENERIC_ERROR, "Too many open files" - -#define QERR_UNDEFINED_ERROR \ -    ERROR_CLASS_GENERIC_ERROR, "An undefined error has occurred" - -#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \ -    ERROR_CLASS_GENERIC_ERROR, "'%s' uses a %s feature which is not supported by this qemu version: %s" - -#define QERR_UNSUPPORTED \ -    ERROR_CLASS_GENERIC_ERROR, "this feature or command is not currently supported" - -#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \ -    ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when VirtFS export path '%s' is mounted in the guest using mount_tag '%s'" - -#define QERR_SOCKET_CONNECT_FAILED \ -    ERROR_CLASS_GENERIC_ERROR, "Failed to connect to socket" - -#define QERR_SOCKET_LISTEN_FAILED \ -    ERROR_CLASS_GENERIC_ERROR, "Failed to set socket to listening mode" - -#define QERR_SOCKET_BIND_FAILED \ -    ERROR_CLASS_GENERIC_ERROR, "Failed to bind socket" - -#define QERR_SOCKET_CREATE_FAILED \ -    ERROR_CLASS_GENERIC_ERROR, "Failed to create socket" - -#endif /* QERROR_H */ diff --git a/contrib/qemu/include/qapi/qmp/qfloat.h b/contrib/qemu/include/qapi/qmp/qfloat.h deleted file mode 100644 index a8658443dc2..00000000000 --- a/contrib/qemu/include/qapi/qmp/qfloat.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * QFloat Module - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef QFLOAT_H -#define QFLOAT_H - -#include <stdint.h> -#include "qapi/qmp/qobject.h" - -typedef struct QFloat { -    QObject_HEAD; -    double value; -} QFloat; - -QFloat *qfloat_from_double(double value); -double qfloat_get_double(const QFloat *qi); -QFloat *qobject_to_qfloat(const QObject *obj); - -#endif /* QFLOAT_H */ diff --git a/contrib/qemu/include/qapi/qmp/qint.h b/contrib/qemu/include/qapi/qmp/qint.h deleted file mode 100644 index 48a41b0f2ae..00000000000 --- a/contrib/qemu/include/qapi/qmp/qint.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * QInt Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#ifndef QINT_H -#define QINT_H - -#include <stdint.h> -#include "qapi/qmp/qobject.h" - -typedef struct QInt { -    QObject_HEAD; -    int64_t value; -} QInt; - -QInt *qint_from_int(int64_t value); -int64_t qint_get_int(const QInt *qi); -QInt *qobject_to_qint(const QObject *obj); - -#endif /* QINT_H */ diff --git a/contrib/qemu/include/qapi/qmp/qjson.h b/contrib/qemu/include/qapi/qmp/qjson.h deleted file mode 100644 index 73351ed6d68..00000000000 --- a/contrib/qemu/include/qapi/qmp/qjson.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * QObject JSON integration - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef QJSON_H -#define QJSON_H - -#include <stdarg.h> -#include "qemu/compiler.h" -#include "qapi/qmp/qobject.h" -#include "qapi/qmp/qstring.h" - -QObject *qobject_from_json(const char *string) GCC_FMT_ATTR(1, 0); -QObject *qobject_from_jsonf(const char *string, ...) GCC_FMT_ATTR(1, 2); -QObject *qobject_from_jsonv(const char *string, va_list *ap) GCC_FMT_ATTR(1, 0); - -QString *qobject_to_json(const QObject *obj); -QString *qobject_to_json_pretty(const QObject *obj); - -#endif /* QJSON_H */ diff --git a/contrib/qemu/include/qapi/qmp/qlist.h b/contrib/qemu/include/qapi/qmp/qlist.h deleted file mode 100644 index 6cc4831df3e..00000000000 --- a/contrib/qemu/include/qapi/qmp/qlist.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * QList Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#ifndef QLIST_H -#define QLIST_H - -#include "qapi/qmp/qobject.h" -#include "qemu/queue.h" - -typedef struct QListEntry { -    QObject *value; -    QTAILQ_ENTRY(QListEntry) next; -} QListEntry; - -typedef struct QList { -    QObject_HEAD; -    QTAILQ_HEAD(,QListEntry) head; -} QList; - -#define qlist_append(qlist, obj) \ -        qlist_append_obj(qlist, QOBJECT(obj)) - -#define QLIST_FOREACH_ENTRY(qlist, var)             \ -        for ((var) = ((qlist)->head.tqh_first);     \ -            (var);                                  \ -            (var) = ((var)->next.tqe_next)) - -static inline QObject *qlist_entry_obj(const QListEntry *entry) -{ -    return entry->value; -} - -QList *qlist_new(void); -QList *qlist_copy(QList *src); -void qlist_append_obj(QList *qlist, QObject *obj); -void qlist_iter(const QList *qlist, -                void (*iter)(QObject *obj, void *opaque), void *opaque); -QObject *qlist_pop(QList *qlist); -QObject *qlist_peek(QList *qlist); -int qlist_empty(const QList *qlist); -size_t qlist_size(const QList *qlist); -QList *qobject_to_qlist(const QObject *obj); - -static inline const QListEntry *qlist_first(const QList *qlist) -{ -    return QTAILQ_FIRST(&qlist->head); -} - -static inline const QListEntry *qlist_next(const QListEntry *entry) -{ -    return QTAILQ_NEXT(entry, next); -} - -#endif /* QLIST_H */ diff --git a/contrib/qemu/include/qapi/qmp/qobject.h b/contrib/qemu/include/qapi/qmp/qobject.h deleted file mode 100644 index 9124649ed20..00000000000 --- a/contrib/qemu/include/qapi/qmp/qobject.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * QEMU Object Model. - * - * Based on ideas by Avi Kivity <avi@redhat.com> - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - * QObject Reference Counts Terminology - * ------------------------------------ - * - *  - Returning references: A function that returns an object may - *  return it as either a weak or a strong reference.  If the reference - *  is strong, you are responsible for calling QDECREF() on the reference - *  when you are done. - * - *  If the reference is weak, the owner of the reference may free it at - *  any time in the future.  Before storing the reference anywhere, you - *  should call QINCREF() to make the reference strong. - * - *  - Transferring ownership: when you transfer ownership of a reference - *  by calling a function, you are no longer responsible for calling - *  QDECREF() when the reference is no longer needed.  In other words, - *  when the function returns you must behave as if the reference to the - *  passed object was weak. - */ -#ifndef QOBJECT_H -#define QOBJECT_H - -#include <stddef.h> -#include <assert.h> - -typedef enum { -    QTYPE_NONE, -    QTYPE_QINT, -    QTYPE_QSTRING, -    QTYPE_QDICT, -    QTYPE_QLIST, -    QTYPE_QFLOAT, -    QTYPE_QBOOL, -    QTYPE_QERROR, -} qtype_code; - -struct QObject; - -typedef struct QType { -    qtype_code code; -    void (*destroy)(struct QObject *); -} QType; - -typedef struct QObject { -    const QType *type; -    size_t refcnt; -} QObject; - -/* Objects definitions must include this */ -#define QObject_HEAD  \ -    QObject base - -/* Get the 'base' part of an object */ -#define QOBJECT(obj) (&(obj)->base) - -/* High-level interface for qobject_incref() */ -#define QINCREF(obj)      \ -    qobject_incref(QOBJECT(obj)) - -/* High-level interface for qobject_decref() */ -#define QDECREF(obj)              \ -    qobject_decref(obj ? QOBJECT(obj) : NULL) - -/* Initialize an object to default values */ -#define QOBJECT_INIT(obj, qtype_type)   \ -    obj->base.refcnt = 1;               \ -    obj->base.type   = qtype_type - -/** - * qobject_incref(): Increment QObject's reference count - */ -static inline void qobject_incref(QObject *obj) -{ -    if (obj) -        obj->refcnt++; -} - -/** - * qobject_decref(): Decrement QObject's reference count, deallocate - * when it reaches zero - */ -static inline void qobject_decref(QObject *obj) -{ -    if (obj && --obj->refcnt == 0) { -        assert(obj->type != NULL); -        assert(obj->type->destroy != NULL); -        obj->type->destroy(obj); -    } -} - -/** - * qobject_type(): Return the QObject's type - */ -static inline qtype_code qobject_type(const QObject *obj) -{ -    assert(obj->type != NULL); -    return obj->type->code; -} - -#endif /* QOBJECT_H */ diff --git a/contrib/qemu/include/qapi/qmp/qstring.h b/contrib/qemu/include/qapi/qmp/qstring.h deleted file mode 100644 index 1bc3666107c..00000000000 --- a/contrib/qemu/include/qapi/qmp/qstring.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * QString Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#ifndef QSTRING_H -#define QSTRING_H - -#include <stdint.h> -#include "qapi/qmp/qobject.h" - -typedef struct QString { -    QObject_HEAD; -    char *string; -    size_t length; -    size_t capacity; -} QString; - -QString *qstring_new(void); -QString *qstring_from_str(const char *str); -QString *qstring_from_substr(const char *str, int start, int end); -size_t qstring_get_length(const QString *qstring); -const char *qstring_get_str(const QString *qstring); -void qstring_append_int(QString *qstring, int64_t value); -void qstring_append(QString *qstring, const char *str); -void qstring_append_chr(QString *qstring, int c); -QString *qobject_to_qstring(const QObject *obj); - -#endif /* QSTRING_H */ diff --git a/contrib/qemu/include/qapi/qmp/types.h b/contrib/qemu/include/qapi/qmp/types.h deleted file mode 100644 index 7782ec5a602..00000000000 --- a/contrib/qemu/include/qapi/qmp/types.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Include all QEMU objects. - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#ifndef QEMU_OBJECTS_H -#define QEMU_OBJECTS_H - -#include "qapi/qmp/qobject.h" -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qfloat.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qjson.h" - -#endif /* QEMU_OBJECTS_H */ diff --git a/contrib/qemu/include/qemu-common.h b/contrib/qemu/include/qemu-common.h deleted file mode 100644 index 6948bb91774..00000000000 --- a/contrib/qemu/include/qemu-common.h +++ /dev/null @@ -1,478 +0,0 @@ - -/* Common header file that is included by all of QEMU. - * - * This file is supposed to be included only by .c files. No header file should - * depend on qemu-common.h, as this would easily lead to circular header - * dependencies. - * - * If a header file uses a definition from qemu-common.h, that definition - * must be moved to a separate header file, and the header that uses it - * must include that header. - */ -#ifndef QEMU_COMMON_H -#define QEMU_COMMON_H - -#include "qemu/compiler.h" -#include "config-host.h" -#include "qemu/typedefs.h" - -#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__) -#define WORDS_ALIGNED -#endif - -#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) - -/* we put basic includes here to avoid repeating them in device drivers */ -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdbool.h> -#include <string.h> -#include <strings.h> -#include <inttypes.h> -#include <limits.h> -#include <time.h> -#include <ctype.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <assert.h> -#include <signal.h> -#include "glib-compat.h" - -#ifdef _WIN32 -#include "sysemu/os-win32.h" -#endif - -#ifdef CONFIG_POSIX -#include "sysemu/os-posix.h" -#endif - -#ifndef O_LARGEFILE -#define O_LARGEFILE 0 -#endif -#ifndef O_BINARY -#define O_BINARY 0 -#endif -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif -#ifndef ENOMEDIUM -#define ENOMEDIUM ENODEV -#endif -#if !defined(ENOTSUP) -#define ENOTSUP 4096 -#endif -#if !defined(ECANCELED) -#define ECANCELED 4097 -#endif -#if !defined(EMEDIUMTYPE) -#define EMEDIUMTYPE 4098 -#endif -#ifndef TIME_MAX -#define TIME_MAX LONG_MAX -#endif - -/* HOST_LONG_BITS is the size of a native pointer in bits. */ -#if UINTPTR_MAX == UINT32_MAX -# define HOST_LONG_BITS 32 -#elif UINTPTR_MAX == UINT64_MAX -# define HOST_LONG_BITS 64 -#else -# error Unknown pointer size -#endif - -typedef int (*fprintf_function)(FILE *f, const char *fmt, ...) -    GCC_FMT_ATTR(2, 3); - -#ifdef _WIN32 -#define fsync _commit -#if !defined(lseek) -# define lseek _lseeki64 -#endif -int qemu_ftruncate64(int, int64_t); -#if !defined(ftruncate) -# define ftruncate qemu_ftruncate64 -#endif - -static inline char *realpath(const char *path, char *resolved_path) -{ -    _fullpath(resolved_path, path, _MAX_PATH); -    return resolved_path; -} -#endif - -/* icount */ -void configure_icount(const char *option); -extern int use_icount; - -#include "qemu/osdep.h" -#include "qemu/bswap.h" - -/* FIXME: Remove NEED_CPU_H.  */ -#ifdef NEED_CPU_H -#include "cpu.h" -#endif /* !defined(NEED_CPU_H) */ - -/* main function, renamed */ -#if defined(CONFIG_COCOA) -int qemu_main(int argc, char **argv, char **envp); -#endif - -void qemu_get_timedate(struct tm *tm, int offset); -int qemu_timedate_diff(struct tm *tm); - -#if !GLIB_CHECK_VERSION(2, 20, 0) -/* - * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly - * on older systems. - */ -static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) -{ -    GMainContext *ctx = g_main_context_default(); -    return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); -} -#endif - -/** - * is_help_option: - * @s: string to test - * - * Check whether @s is one of the standard strings which indicate - * that the user is asking for a list of the valid values for a - * command option like -cpu or -M. The current accepted strings - * are 'help' and '?'. '?' is deprecated (it is a shell wildcard - * which makes it annoying to use in a reliable way) but provided - * for backwards compatibility. - * - * Returns: true if @s is a request for a list. - */ -static inline bool is_help_option(const char *s) -{ -    return !strcmp(s, "?") || !strcmp(s, "help"); -} - -/* cutils.c */ -void pstrcpy(char *buf, int buf_size, const char *str); -void strpadcpy(char *buf, int buf_size, const char *str, char pad); -char *pstrcat(char *buf, int buf_size, const char *s); -int strstart(const char *str, const char *val, const char **ptr); -int stristart(const char *str, const char *val, const char **ptr); -int qemu_strnlen(const char *s, int max_len); -char *qemu_strsep(char **input, const char *delim); -time_t mktimegm(struct tm *tm); -int qemu_fls(int i); -int qemu_fdatasync(int fd); -int fcntl_setfl(int fd, int flag); -int qemu_parse_fd(const char *param); - -int parse_uint(const char *s, unsigned long long *value, char **endptr, -               int base); -int parse_uint_full(const char *s, unsigned long long *value, int base); - -/* - * strtosz() suffixes used to specify the default treatment of an - * argument passed to strtosz() without an explicit suffix. - * These should be defined using upper case characters in the range - * A-Z, as strtosz() will use qemu_toupper() on the given argument - * prior to comparison. - */ -#define STRTOSZ_DEFSUFFIX_EB	'E' -#define STRTOSZ_DEFSUFFIX_PB	'P' -#define STRTOSZ_DEFSUFFIX_TB	'T' -#define STRTOSZ_DEFSUFFIX_GB	'G' -#define STRTOSZ_DEFSUFFIX_MB	'M' -#define STRTOSZ_DEFSUFFIX_KB	'K' -#define STRTOSZ_DEFSUFFIX_B	'B' -int64_t strtosz(const char *nptr, char **end); -int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix); -int64_t strtosz_suffix_unit(const char *nptr, char **end, -                            const char default_suffix, int64_t unit); - -/* path.c */ -void init_paths(const char *prefix); -const char *path(const char *pathname); - -#define qemu_isalnum(c)		isalnum((unsigned char)(c)) -#define qemu_isalpha(c)		isalpha((unsigned char)(c)) -#define qemu_iscntrl(c)		iscntrl((unsigned char)(c)) -#define qemu_isdigit(c)		isdigit((unsigned char)(c)) -#define qemu_isgraph(c)		isgraph((unsigned char)(c)) -#define qemu_islower(c)		islower((unsigned char)(c)) -#define qemu_isprint(c)		isprint((unsigned char)(c)) -#define qemu_ispunct(c)		ispunct((unsigned char)(c)) -#define qemu_isspace(c)		isspace((unsigned char)(c)) -#define qemu_isupper(c)		isupper((unsigned char)(c)) -#define qemu_isxdigit(c)	isxdigit((unsigned char)(c)) -#define qemu_tolower(c)		tolower((unsigned char)(c)) -#define qemu_toupper(c)		toupper((unsigned char)(c)) -#define qemu_isascii(c)		isascii((unsigned char)(c)) -#define qemu_toascii(c)		toascii((unsigned char)(c)) - -void *qemu_oom_check(void *ptr); - -ssize_t qemu_write_full(int fd, const void *buf, size_t count) -    QEMU_WARN_UNUSED_RESULT; -ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags) -    QEMU_WARN_UNUSED_RESULT; -ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags) -    QEMU_WARN_UNUSED_RESULT; - -#ifndef _WIN32 -int qemu_pipe(int pipefd[2]); -/* like openpty() but also makes it raw; return master fd */ -int qemu_openpty_raw(int *aslave, char *pty_name); -#endif - -#ifdef _WIN32 -/* MinGW needs type casts for the 'buf' and 'optval' arguments. */ -#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \ -    getsockopt(sockfd, level, optname, (void *)optval, optlen) -#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \ -    setsockopt(sockfd, level, optname, (const void *)optval, optlen) -#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags) -#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \ -    sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen) -#else -#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \ -    getsockopt(sockfd, level, optname, optval, optlen) -#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \ -    setsockopt(sockfd, level, optname, optval, optlen) -#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags) -#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \ -    sendto(sockfd, buf, len, flags, destaddr, addrlen) -#endif - -/* Error handling.  */ - -void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); - -struct ParallelIOArg { -    void *buffer; -    int count; -}; - -typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size); - -typedef uint64_t pcibus_t; - -typedef enum LostTickPolicy { -    LOST_TICK_DISCARD, -    LOST_TICK_DELAY, -    LOST_TICK_MERGE, -    LOST_TICK_SLEW, -    LOST_TICK_MAX -} LostTickPolicy; - -typedef struct PCIHostDeviceAddress { -    unsigned int domain; -    unsigned int bus; -    unsigned int slot; -    unsigned int function; -} PCIHostDeviceAddress; - -void tcg_exec_init(unsigned long tb_size); -bool tcg_enabled(void); - -void cpu_exec_init_all(void); - -/* CPU save/load.  */ -#ifdef CPU_SAVE_VERSION -void cpu_save(QEMUFile *f, void *opaque); -int cpu_load(QEMUFile *f, void *opaque, int version_id); -#endif - -/* Unblock cpu */ -void qemu_cpu_kick_self(void); - -/* work queue */ -struct qemu_work_item { -    struct qemu_work_item *next; -    void (*func)(void *data); -    void *data; -    int done; -    bool free; -}; - - -/** - * Sends a (part of) iovec down a socket, yielding when the socket is full, or - * Receives data into a (part of) iovec from a socket, - * yielding when there is no data in the socket. - * The same interface as qemu_sendv_recvv(), with added yielding. - * XXX should mark these as coroutine_fn - */ -ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt, -                            size_t offset, size_t bytes, bool do_send); -#define qemu_co_recvv(sockfd, iov, iov_cnt, offset, bytes) \ -  qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, false) -#define qemu_co_sendv(sockfd, iov, iov_cnt, offset, bytes) \ -  qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, true) - -/** - * The same as above, but with just a single buffer - */ -ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send); -#define qemu_co_recv(sockfd, buf, bytes) \ -  qemu_co_send_recv(sockfd, buf, bytes, false) -#define qemu_co_send(sockfd, buf, bytes) \ -  qemu_co_send_recv(sockfd, buf, bytes, true) - -typedef struct QEMUIOVector { -    struct iovec *iov; -    int niov; -    int nalloc; -    size_t size; -} QEMUIOVector; - -void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint); -void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov); -void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); -void qemu_iovec_concat(QEMUIOVector *dst, -                       QEMUIOVector *src, size_t soffset, size_t sbytes); -void qemu_iovec_concat_iov(QEMUIOVector *dst, -                           struct iovec *src_iov, unsigned int src_cnt, -                           size_t soffset, size_t sbytes); -void qemu_iovec_destroy(QEMUIOVector *qiov); -void qemu_iovec_reset(QEMUIOVector *qiov); -size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset, -                         void *buf, size_t bytes); -size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset, -                           const void *buf, size_t bytes); -size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, -                         int fillc, size_t bytes); - -bool buffer_is_zero(const void *buf, size_t len); - -void qemu_progress_init(int enabled, float min_skip); -void qemu_progress_end(void); -void qemu_progress_print(float delta, int max); -const char *qemu_get_vm_name(void); - -#define QEMU_FILE_TYPE_BIOS   0 -#define QEMU_FILE_TYPE_KEYMAP 1 -char *qemu_find_file(int type, const char *name); - -/* OS specific functions */ -void os_setup_early_signal_handling(void); -char *os_find_datadir(const char *argv0); -void os_parse_cmd_args(int index, const char *optarg); -void os_pidfile_error(void); - -/* Convert a byte between binary and BCD.  */ -static inline uint8_t to_bcd(uint8_t val) -{ -    return ((val / 10) << 4) | (val % 10); -} - -static inline uint8_t from_bcd(uint8_t val) -{ -    return ((val >> 4) * 10) + (val & 0x0f); -} - -/* compute with 96 bit intermediate result: (a*b)/c */ -static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) -{ -    union { -        uint64_t ll; -        struct { -#ifdef HOST_WORDS_BIGENDIAN -            uint32_t high, low; -#else -            uint32_t low, high; -#endif -        } l; -    } u, res; -    uint64_t rl, rh; - -    u.ll = a; -    rl = (uint64_t)u.l.low * (uint64_t)b; -    rh = (uint64_t)u.l.high * (uint64_t)b; -    rh += (rl >> 32); -    res.l.high = rh / c; -    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c; -    return res.ll; -} - -/* Round number down to multiple */ -#define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m)) - -/* Round number up to multiple */ -#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m)) - -static inline bool is_power_of_2(uint64_t value) -{ -    if (!value) { -        return 0; -    } - -    return !(value & (value - 1)); -} - -/* round down to the nearest power of 2*/ -int64_t pow2floor(int64_t value); - -#include "qemu/module.h" - -/* - * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128) - * Input is limited to 14-bit numbers - */ - -int uleb128_encode_small(uint8_t *out, uint32_t n); -int uleb128_decode_small(const uint8_t *in, uint32_t *n); - -/* unicode.c */ -int mod_utf8_codepoint(const char *s, size_t n, char **end); - -/* - * Hexdump a buffer to a file. An optional string prefix is added to every line - */ - -void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); - -/* vector definitions */ -#ifdef __ALTIVEC__ -#include <altivec.h> -/* The altivec.h header says we're allowed to undef these for - * C++ compatibility.  Here we don't care about C++, but we - * undef them anyway to avoid namespace pollution. - */ -#undef vector -#undef pixel -#undef bool -#define VECTYPE        __vector unsigned char -#define SPLAT(p)       vec_splat(vec_ld(0, p), 0) -#define ALL_EQ(v1, v2) vec_all_eq(v1, v2) -/* altivec.h may redefine the bool macro as vector type. - * Reset it to POSIX semantics. */ -#define bool _Bool -#elif defined __SSE2__ -#include <emmintrin.h> -#define VECTYPE        __m128i -#define SPLAT(p)       _mm_set1_epi8(*(p)) -#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF) -#else -#define VECTYPE        unsigned long -#define SPLAT(p)       (*(p) * (~0UL / 255)) -#define ALL_EQ(v1, v2) ((v1) == (v2)) -#endif - -#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8 -static inline bool -can_use_buffer_find_nonzero_offset(const void *buf, size_t len) -{ -    return (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR -                   * sizeof(VECTYPE)) == 0 -            && ((uintptr_t) buf) % sizeof(VECTYPE) == 0); -} -size_t buffer_find_nonzero_offset(const void *buf, size_t len); - -/* - * helper to parse debug environment variables - */ -int parse_debug_env(const char *name, int max, int initial); - -#endif diff --git a/contrib/qemu/include/qemu/aes.h b/contrib/qemu/include/qemu/aes.h deleted file mode 100644 index e79c707436f..00000000000 --- a/contrib/qemu/include/qemu/aes.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef QEMU_AES_H -#define QEMU_AES_H - -#define AES_MAXNR 14 -#define AES_BLOCK_SIZE 16 - -struct aes_key_st { -    uint32_t rd_key[4 *(AES_MAXNR + 1)]; -    int rounds; -}; -typedef struct aes_key_st AES_KEY; - -int AES_set_encrypt_key(const unsigned char *userKey, const int bits, -	AES_KEY *key); -int AES_set_decrypt_key(const unsigned char *userKey, const int bits, -	AES_KEY *key); - -void AES_encrypt(const unsigned char *in, unsigned char *out, -	const AES_KEY *key); -void AES_decrypt(const unsigned char *in, unsigned char *out, -	const AES_KEY *key); -void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, -		     const unsigned long length, const AES_KEY *key, -		     unsigned char *ivec, const int enc); - -/* -AES_Te0[x] = S [x].[02, 01, 01, 03]; -AES_Te1[x] = S [x].[03, 02, 01, 01]; -AES_Te2[x] = S [x].[01, 03, 02, 01]; -AES_Te3[x] = S [x].[01, 01, 03, 02]; -AES_Te4[x] = S [x].[01, 01, 01, 01]; - -AES_Td0[x] = Si[x].[0e, 09, 0d, 0b]; -AES_Td1[x] = Si[x].[0b, 0e, 09, 0d]; -AES_Td2[x] = Si[x].[0d, 0b, 0e, 09]; -AES_Td3[x] = Si[x].[09, 0d, 0b, 0e]; -AES_Td4[x] = Si[x].[01, 01, 01, 01]; -*/ - -extern const uint32_t AES_Te0[256], AES_Te1[256], AES_Te2[256], -                      AES_Te3[256], AES_Te4[256]; -extern const uint32_t AES_Td0[256], AES_Td1[256], AES_Td2[256], -                      AES_Td3[256], AES_Td4[256]; - -#endif diff --git a/contrib/qemu/include/qemu/atomic.h b/contrib/qemu/include/qemu/atomic.h deleted file mode 100644 index 0aa89133018..00000000000 --- a/contrib/qemu/include/qemu/atomic.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Simple interface for atomic operations. - * - * Copyright (C) 2013 Red Hat, Inc. - * - * Author: Paolo Bonzini <pbonzini@redhat.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ - -#ifndef __QEMU_ATOMIC_H -#define __QEMU_ATOMIC_H 1 - -#include "qemu/compiler.h" - -/* For C11 atomic ops */ - -/* Compiler barrier */ -#define barrier()   ({ asm volatile("" ::: "memory"); (void)0; }) - -#ifndef __ATOMIC_RELAXED - -/* - * We use GCC builtin if it's available, as that can use mfence on - * 32-bit as well, e.g. if built with -march=pentium-m. However, on - * i386 the spec is buggy, and the implementation followed it until - * 4.3 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36793). - */ -#if defined(__i386__) || defined(__x86_64__) -#if !QEMU_GNUC_PREREQ(4, 4) -#if defined __x86_64__ -#define smp_mb()    ({ asm volatile("mfence" ::: "memory"); (void)0; }) -#else -#define smp_mb()    ({ asm volatile("lock; addl $0,0(%%esp) " ::: "memory"); (void)0; }) -#endif -#endif -#endif - - -#ifdef __alpha__ -#define smp_read_barrier_depends()   asm volatile("mb":::"memory") -#endif - -#if defined(__i386__) || defined(__x86_64__) || defined(__s390x__) - -/* - * Because of the strongly ordered storage model, wmb() and rmb() are nops - * here (a compiler barrier only).  QEMU doesn't do accesses to write-combining - * qemu memory or non-temporal load/stores from C code. - */ -#define smp_wmb()   barrier() -#define smp_rmb()   barrier() - -/* - * __sync_lock_test_and_set() is documented to be an acquire barrier only, - * but it is a full barrier at the hardware level.  Add a compiler barrier - * to make it a full barrier also at the compiler level. - */ -#define atomic_xchg(ptr, i)    (barrier(), __sync_lock_test_and_set(ptr, i)) - -/* - * Load/store with Java volatile semantics. - */ -#define atomic_mb_set(ptr, i)  ((void)atomic_xchg(ptr, i)) - -#elif defined(_ARCH_PPC) - -/* - * We use an eieio() for wmb() on powerpc.  This assumes we don't - * need to order cacheable and non-cacheable stores with respect to - * each other. - * - * smp_mb has the same problem as on x86 for not-very-new GCC - * (http://patchwork.ozlabs.org/patch/126184/, Nov 2011). - */ -#define smp_wmb()   ({ asm volatile("eieio" ::: "memory"); (void)0; }) -#if defined(__powerpc64__) -#define smp_rmb()   ({ asm volatile("lwsync" ::: "memory"); (void)0; }) -#else -#define smp_rmb()   ({ asm volatile("sync" ::: "memory"); (void)0; }) -#endif -#define smp_mb()    ({ asm volatile("sync" ::: "memory"); (void)0; }) - -#endif /* _ARCH_PPC */ - -#endif /* C11 atomics */ - -/* - * For (host) platforms we don't have explicit barrier definitions - * for, we use the gcc __sync_synchronize() primitive to generate a - * full barrier.  This should be safe on all platforms, though it may - * be overkill for smp_wmb() and smp_rmb(). - */ -#ifndef smp_mb -#define smp_mb()    __sync_synchronize() -#endif - -#ifndef smp_wmb -#ifdef __ATOMIC_RELEASE -#define smp_wmb()   __atomic_thread_fence(__ATOMIC_RELEASE) -#else -#define smp_wmb()   __sync_synchronize() -#endif -#endif - -#ifndef smp_rmb -#ifdef __ATOMIC_ACQUIRE -#define smp_rmb()   __atomic_thread_fence(__ATOMIC_ACQUIRE) -#else -#define smp_rmb()   __sync_synchronize() -#endif -#endif - -#ifndef smp_read_barrier_depends -#ifdef __ATOMIC_CONSUME -#define smp_read_barrier_depends()   __atomic_thread_fence(__ATOMIC_CONSUME) -#else -#define smp_read_barrier_depends()   barrier() -#endif -#endif - -#ifndef atomic_read -#define atomic_read(ptr)       (*(__typeof__(*ptr) *volatile) (ptr)) -#endif - -#ifndef atomic_set -#define atomic_set(ptr, i)     ((*(__typeof__(*ptr) *volatile) (ptr)) = (i)) -#endif - -/* These have the same semantics as Java volatile variables. - * See http://gee.cs.oswego.edu/dl/jmm/cookbook.html: - * "1. Issue a StoreStore barrier (wmb) before each volatile store." - *  2. Issue a StoreLoad barrier after each volatile store. - *     Note that you could instead issue one before each volatile load, but - *     this would be slower for typical programs using volatiles in which - *     reads greatly outnumber writes. Alternatively, if available, you - *     can implement volatile store as an atomic instruction (for example - *     XCHG on x86) and omit the barrier. This may be more efficient if - *     atomic instructions are cheaper than StoreLoad barriers. - *  3. Issue LoadLoad and LoadStore barriers after each volatile load." - * - * If you prefer to think in terms of "pairing" of memory barriers, - * an atomic_mb_read pairs with an atomic_mb_set. - * - * And for the few ia64 lovers that exist, an atomic_mb_read is a ld.acq, - * while an atomic_mb_set is a st.rel followed by a memory barrier. - * - * These are a bit weaker than __atomic_load/store with __ATOMIC_SEQ_CST - * (see docs/atomics.txt), and I'm not sure that __ATOMIC_ACQ_REL is enough. - * Just always use the barriers manually by the rules above. - */ -#ifndef atomic_mb_read -#define atomic_mb_read(ptr)    ({           \ -    typeof(*ptr) _val = atomic_read(ptr);   \ -    smp_rmb();                              \ -    _val;                                   \ -}) -#endif - -#ifndef atomic_mb_set -#define atomic_mb_set(ptr, i)  do {         \ -    smp_wmb();                              \ -    atomic_set(ptr, i);                     \ -    smp_mb();                               \ -} while (0) -#endif - -#ifndef atomic_xchg -#ifdef __ATOMIC_SEQ_CST -#define atomic_xchg(ptr, i)    ({                           \ -    typeof(*ptr) _new = (i), _old;                          \ -    __atomic_exchange(ptr, &_new, &_old, __ATOMIC_SEQ_CST); \ -    _old;                                                   \ -}) -#elif defined __clang__ -#define atomic_xchg(ptr, i)    __sync_exchange(ptr, i) -#else -/* __sync_lock_test_and_set() is documented to be an acquire barrier only.  */ -#define atomic_xchg(ptr, i)    (smp_mb(), __sync_lock_test_and_set(ptr, i)) -#endif -#endif - -/* Provide shorter names for GCC atomic builtins.  */ -#define atomic_fetch_inc(ptr)  __sync_fetch_and_add(ptr, 1) -#define atomic_fetch_dec(ptr)  __sync_fetch_and_add(ptr, -1) -#define atomic_fetch_add       __sync_fetch_and_add -#define atomic_fetch_sub       __sync_fetch_and_sub -#define atomic_fetch_and       __sync_fetch_and_and -#define atomic_fetch_or        __sync_fetch_and_or -#define atomic_cmpxchg         __sync_val_compare_and_swap - -/* And even shorter names that return void.  */ -#define atomic_inc(ptr)        ((void) __sync_fetch_and_add(ptr, 1)) -#define atomic_dec(ptr)        ((void) __sync_fetch_and_add(ptr, -1)) -#define atomic_add(ptr, n)     ((void) __sync_fetch_and_add(ptr, n)) -#define atomic_sub(ptr, n)     ((void) __sync_fetch_and_sub(ptr, n)) -#define atomic_and(ptr, n)     ((void) __sync_fetch_and_and(ptr, n)) -#define atomic_or(ptr, n)      ((void) __sync_fetch_and_or(ptr, n)) - -#endif diff --git a/contrib/qemu/include/qemu/bitmap.h b/contrib/qemu/include/qemu/bitmap.h deleted file mode 100644 index 308bbb71e9b..00000000000 --- a/contrib/qemu/include/qemu/bitmap.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Bitmap Module - * - * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com> - * - * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#ifndef BITMAP_H -#define BITMAP_H - -#include "qemu-common.h" -#include "qemu/bitops.h" - -/* - * The available bitmap operations and their rough meaning in the - * case that the bitmap is a single unsigned long are thus: - * - * Note that nbits should be always a compile time evaluable constant. - * Otherwise many inlines will generate horrible code. - * - * bitmap_zero(dst, nbits)			*dst = 0UL - * bitmap_fill(dst, nbits)			*dst = ~0UL - * bitmap_copy(dst, src, nbits)			*dst = *src - * bitmap_and(dst, src1, src2, nbits)		*dst = *src1 & *src2 - * bitmap_or(dst, src1, src2, nbits)		*dst = *src1 | *src2 - * bitmap_xor(dst, src1, src2, nbits)		*dst = *src1 ^ *src2 - * bitmap_andnot(dst, src1, src2, nbits)	*dst = *src1 & ~(*src2) - * bitmap_complement(dst, src, nbits)		*dst = ~(*src) - * bitmap_equal(src1, src2, nbits)		Are *src1 and *src2 equal? - * bitmap_intersects(src1, src2, nbits) 	Do *src1 and *src2 overlap? - * bitmap_empty(src, nbits)			Are all bits zero in *src? - * bitmap_full(src, nbits)			Are all bits set in *src? - * bitmap_set(dst, pos, nbits)			Set specified bit area - * bitmap_clear(dst, pos, nbits)		Clear specified bit area - * bitmap_find_next_zero_area(buf, len, pos, n, mask)	Find bit free area - */ - -/* - * Also the following operations apply to bitmaps. - * - * set_bit(bit, addr)			*addr |= bit - * clear_bit(bit, addr)			*addr &= ~bit - * change_bit(bit, addr)		*addr ^= bit - * test_bit(bit, addr)			Is bit set in *addr? - * test_and_set_bit(bit, addr)		Set bit and return old value - * test_and_clear_bit(bit, addr)	Clear bit and return old value - * test_and_change_bit(bit, addr)	Change bit and return old value - * find_first_zero_bit(addr, nbits)	Position first zero bit in *addr - * find_first_bit(addr, nbits)		Position first set bit in *addr - * find_next_zero_bit(addr, nbits, bit)	Position next zero bit in *addr >= bit - * find_next_bit(addr, nbits, bit)	Position next set bit in *addr >= bit - */ - -#define BITMAP_LAST_WORD_MASK(nbits)                                    \ -    (                                                                   \ -        ((nbits) % BITS_PER_LONG) ?                                     \ -        (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL                       \ -        ) - -#define DECLARE_BITMAP(name,bits)                  \ -	unsigned long name[BITS_TO_LONGS(bits)] - -#define small_nbits(nbits)                      \ -	((nbits) <= BITS_PER_LONG) - -int slow_bitmap_empty(const unsigned long *bitmap, int bits); -int slow_bitmap_full(const unsigned long *bitmap, int bits); -int slow_bitmap_equal(const unsigned long *bitmap1, -                   const unsigned long *bitmap2, int bits); -void slow_bitmap_complement(unsigned long *dst, const unsigned long *src, -                         int bits); -void slow_bitmap_shift_right(unsigned long *dst, -                          const unsigned long *src, int shift, int bits); -void slow_bitmap_shift_left(unsigned long *dst, -                         const unsigned long *src, int shift, int bits); -int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1, -                 const unsigned long *bitmap2, int bits); -void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1, -                 const unsigned long *bitmap2, int bits); -void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, -                  const unsigned long *bitmap2, int bits); -int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, -                    const unsigned long *bitmap2, int bits); -int slow_bitmap_intersects(const unsigned long *bitmap1, -			const unsigned long *bitmap2, int bits); - -static inline unsigned long *bitmap_new(int nbits) -{ -    int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); -    return g_malloc0(len); -} - -static inline void bitmap_zero(unsigned long *dst, int nbits) -{ -    if (small_nbits(nbits)) { -        *dst = 0UL; -    } else { -        int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); -        memset(dst, 0, len); -    } -} - -static inline void bitmap_fill(unsigned long *dst, int nbits) -{ -    size_t nlongs = BITS_TO_LONGS(nbits); -    if (!small_nbits(nbits)) { -        int len = (nlongs - 1) * sizeof(unsigned long); -        memset(dst, 0xff,  len); -    } -    dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); -} - -static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, -                               int nbits) -{ -    if (small_nbits(nbits)) { -        *dst = *src; -    } else { -        int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); -        memcpy(dst, src, len); -    } -} - -static inline int bitmap_and(unsigned long *dst, const unsigned long *src1, -                             const unsigned long *src2, int nbits) -{ -    if (small_nbits(nbits)) { -        return (*dst = *src1 & *src2) != 0; -    } -    return slow_bitmap_and(dst, src1, src2, nbits); -} - -static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, -			const unsigned long *src2, int nbits) -{ -    if (small_nbits(nbits)) { -        *dst = *src1 | *src2; -    } else { -        slow_bitmap_or(dst, src1, src2, nbits); -    } -} - -static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1, -			const unsigned long *src2, int nbits) -{ -    if (small_nbits(nbits)) { -        *dst = *src1 ^ *src2; -    } else { -        slow_bitmap_xor(dst, src1, src2, nbits); -    } -} - -static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1, -			const unsigned long *src2, int nbits) -{ -    if (small_nbits(nbits)) { -        return (*dst = *src1 & ~(*src2)) != 0; -    } -    return slow_bitmap_andnot(dst, src1, src2, nbits); -} - -static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, -			int nbits) -{ -    if (small_nbits(nbits)) { -        *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits); -    } else { -        slow_bitmap_complement(dst, src, nbits); -    } -} - -static inline int bitmap_equal(const unsigned long *src1, -			const unsigned long *src2, int nbits) -{ -    if (small_nbits(nbits)) { -        return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); -    } else { -        return slow_bitmap_equal(src1, src2, nbits); -    } -} - -static inline int bitmap_empty(const unsigned long *src, int nbits) -{ -    if (small_nbits(nbits)) { -        return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); -    } else { -        return slow_bitmap_empty(src, nbits); -    } -} - -static inline int bitmap_full(const unsigned long *src, int nbits) -{ -    if (small_nbits(nbits)) { -        return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); -    } else { -        return slow_bitmap_full(src, nbits); -    } -} - -static inline int bitmap_intersects(const unsigned long *src1, -			const unsigned long *src2, int nbits) -{ -    if (small_nbits(nbits)) { -        return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; -    } else { -        return slow_bitmap_intersects(src1, src2, nbits); -    } -} - -void bitmap_set(unsigned long *map, int i, int len); -void bitmap_clear(unsigned long *map, int start, int nr); -unsigned long bitmap_find_next_zero_area(unsigned long *map, -					 unsigned long size, -					 unsigned long start, -					 unsigned int nr, -					 unsigned long align_mask); - -#endif /* BITMAP_H */ diff --git a/contrib/qemu/include/qemu/bitops.h b/contrib/qemu/include/qemu/bitops.h deleted file mode 100644 index affcc969dcf..00000000000 --- a/contrib/qemu/include/qemu/bitops.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Bitops Module - * - * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com> - * - * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#ifndef BITOPS_H -#define BITOPS_H - -#include "qemu-common.h" -#include "host-utils.h" - -#define BITS_PER_BYTE           CHAR_BIT -#define BITS_PER_LONG           (sizeof (unsigned long) * BITS_PER_BYTE) - -#define BIT(nr)			(1UL << (nr)) -#define BIT_MASK(nr)		(1UL << ((nr) % BITS_PER_LONG)) -#define BIT_WORD(nr)		((nr) / BITS_PER_LONG) -#define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) - -/** - * set_bit - Set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - */ -static inline void set_bit(int nr, unsigned long *addr) -{ -	unsigned long mask = BIT_MASK(nr); -        unsigned long *p = addr + BIT_WORD(nr); - -	*p  |= mask; -} - -/** - * clear_bit - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - */ -static inline void clear_bit(int nr, unsigned long *addr) -{ -	unsigned long mask = BIT_MASK(nr); -        unsigned long *p = addr + BIT_WORD(nr); - -	*p &= ~mask; -} - -/** - * change_bit - Toggle a bit in memory - * @nr: Bit to change - * @addr: Address to start counting from - */ -static inline void change_bit(int nr, unsigned long *addr) -{ -	unsigned long mask = BIT_MASK(nr); -        unsigned long *p = addr + BIT_WORD(nr); - -	*p ^= mask; -} - -/** - * test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - */ -static inline int test_and_set_bit(int nr, unsigned long *addr) -{ -	unsigned long mask = BIT_MASK(nr); -        unsigned long *p = addr + BIT_WORD(nr); -	unsigned long old = *p; - -	*p = old | mask; -	return (old & mask) != 0; -} - -/** - * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to clear - * @addr: Address to count from - */ -static inline int test_and_clear_bit(int nr, unsigned long *addr) -{ -	unsigned long mask = BIT_MASK(nr); -        unsigned long *p = addr + BIT_WORD(nr); -	unsigned long old = *p; - -	*p = old & ~mask; -	return (old & mask) != 0; -} - -/** - * test_and_change_bit - Change a bit and return its old value - * @nr: Bit to change - * @addr: Address to count from - */ -static inline int test_and_change_bit(int nr, unsigned long *addr) -{ -	unsigned long mask = BIT_MASK(nr); -        unsigned long *p = addr + BIT_WORD(nr); -	unsigned long old = *p; - -	*p = old ^ mask; -	return (old & mask) != 0; -} - -/** - * test_bit - Determine whether a bit is set - * @nr: bit number to test - * @addr: Address to start counting from - */ -static inline int test_bit(int nr, const unsigned long *addr) -{ -	return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); -} - -/** - * find_last_bit - find the last set bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search - * - * Returns the bit number of the first set bit, or size. - */ -unsigned long find_last_bit(const unsigned long *addr, -                            unsigned long size); - -/** - * find_next_bit - find the next set bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The bitmap size in bits - */ -unsigned long find_next_bit(const unsigned long *addr, -				   unsigned long size, unsigned long offset); - -/** - * find_next_zero_bit - find the next cleared bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The bitmap size in bits - */ - -unsigned long find_next_zero_bit(const unsigned long *addr, -                                 unsigned long size, -                                 unsigned long offset); - -/** - * find_first_bit - find the first set bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search - * - * Returns the bit number of the first set bit. - */ -static inline unsigned long find_first_bit(const unsigned long *addr, -                                           unsigned long size) -{ -    return find_next_bit(addr, size, 0); -} - -/** - * find_first_zero_bit - find the first cleared bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search - * - * Returns the bit number of the first cleared bit. - */ -static inline unsigned long find_first_zero_bit(const unsigned long *addr, -                                                unsigned long size) -{ -    return find_next_zero_bit(addr, size, 0); -} - -static inline unsigned long hweight_long(unsigned long w) -{ -    unsigned long count; - -    for (count = 0; w; w >>= 1) { -        count += w & 1; -    } -    return count; -} - -/** - * extract32: - * @value: the value to extract the bit field from - * @start: the lowest bit in the bit field (numbered from 0) - * @length: the length of the bit field - * - * Extract from the 32 bit input @value the bit field specified by the - * @start and @length parameters, and return it. The bit field must - * lie entirely within the 32 bit word. It is valid to request that - * all 32 bits are returned (ie @length 32 and @start 0). - * - * Returns: the value of the bit field extracted from the input value. - */ -static inline uint32_t extract32(uint32_t value, int start, int length) -{ -    assert(start >= 0 && length > 0 && length <= 32 - start); -    return (value >> start) & (~0U >> (32 - length)); -} - -/** - * extract64: - * @value: the value to extract the bit field from - * @start: the lowest bit in the bit field (numbered from 0) - * @length: the length of the bit field - * - * Extract from the 64 bit input @value the bit field specified by the - * @start and @length parameters, and return it. The bit field must - * lie entirely within the 64 bit word. It is valid to request that - * all 64 bits are returned (ie @length 64 and @start 0). - * - * Returns: the value of the bit field extracted from the input value. - */ -static inline uint64_t extract64(uint64_t value, int start, int length) -{ -    assert(start >= 0 && length > 0 && length <= 64 - start); -    return (value >> start) & (~0ULL >> (64 - length)); -} - -/** - * deposit32: - * @value: initial value to insert bit field into - * @start: the lowest bit in the bit field (numbered from 0) - * @length: the length of the bit field - * @fieldval: the value to insert into the bit field - * - * Deposit @fieldval into the 32 bit @value at the bit field specified - * by the @start and @length parameters, and return the modified - * @value. Bits of @value outside the bit field are not modified. - * Bits of @fieldval above the least significant @length bits are - * ignored. The bit field must lie entirely within the 32 bit word. - * It is valid to request that all 32 bits are modified (ie @length - * 32 and @start 0). - * - * Returns: the modified @value. - */ -static inline uint32_t deposit32(uint32_t value, int start, int length, -                                 uint32_t fieldval) -{ -    uint32_t mask; -    assert(start >= 0 && length > 0 && length <= 32 - start); -    mask = (~0U >> (32 - length)) << start; -    return (value & ~mask) | ((fieldval << start) & mask); -} - -/** - * deposit64: - * @value: initial value to insert bit field into - * @start: the lowest bit in the bit field (numbered from 0) - * @length: the length of the bit field - * @fieldval: the value to insert into the bit field - * - * Deposit @fieldval into the 64 bit @value at the bit field specified - * by the @start and @length parameters, and return the modified - * @value. Bits of @value outside the bit field are not modified. - * Bits of @fieldval above the least significant @length bits are - * ignored. The bit field must lie entirely within the 64 bit word. - * It is valid to request that all 64 bits are modified (ie @length - * 64 and @start 0). - * - * Returns: the modified @value. - */ -static inline uint64_t deposit64(uint64_t value, int start, int length, -                                 uint64_t fieldval) -{ -    uint64_t mask; -    assert(start >= 0 && length > 0 && length <= 64 - start); -    mask = (~0ULL >> (64 - length)) << start; -    return (value & ~mask) | ((fieldval << start) & mask); -} - -#endif diff --git a/contrib/qemu/include/qemu/bswap.h b/contrib/qemu/include/qemu/bswap.h deleted file mode 100644 index bf6457b8c46..00000000000 --- a/contrib/qemu/include/qemu/bswap.h +++ /dev/null @@ -1,487 +0,0 @@ -#ifndef BSWAP_H -#define BSWAP_H - -#include "config-host.h" -#include <inttypes.h> -#include <limits.h> -#include <string.h> -#include "fpu/softfloat.h" - -#ifdef CONFIG_MACHINE_BSWAP_H -# include <sys/endian.h> -# include <sys/types.h> -# include <machine/bswap.h> -#elif defined(__FreeBSD__) -# include <sys/endian.h> -#elif defined(CONFIG_BYTESWAP_H) -#ifdef GF_DARWIN_HOST_OS -# include <libkern/OSByteOrder.h> -#define bswap_16(x) OSSwapInt16(x) -#define bswap_32(x) OSSwapInt32(x) -#define bswap_64(x) OSSwapInt64(x) -#else -# include <byteswap.h> -#endif - -static inline uint16_t bswap16(uint16_t x) -{ -    return bswap_16(x); -} - -static inline uint32_t bswap32(uint32_t x) -{ -    return bswap_32(x); -} - -static inline uint64_t bswap64(uint64_t x) -{ -    return bswap_64(x); -} -# else -static inline uint16_t bswap16(uint16_t x) -{ -    return (((x & 0x00ff) << 8) | -            ((x & 0xff00) >> 8)); -} - -static inline uint32_t bswap32(uint32_t x) -{ -    return (((x & 0x000000ffU) << 24) | -            ((x & 0x0000ff00U) <<  8) | -            ((x & 0x00ff0000U) >>  8) | -            ((x & 0xff000000U) >> 24)); -} - -static inline uint64_t bswap64(uint64_t x) -{ -    return (((x & 0x00000000000000ffULL) << 56) | -            ((x & 0x000000000000ff00ULL) << 40) | -            ((x & 0x0000000000ff0000ULL) << 24) | -            ((x & 0x00000000ff000000ULL) <<  8) | -            ((x & 0x000000ff00000000ULL) >>  8) | -            ((x & 0x0000ff0000000000ULL) >> 24) | -            ((x & 0x00ff000000000000ULL) >> 40) | -            ((x & 0xff00000000000000ULL) >> 56)); -} -#endif /* ! CONFIG_MACHINE_BSWAP_H */ - -static inline void bswap16s(uint16_t *s) -{ -    *s = bswap16(*s); -} - -static inline void bswap32s(uint32_t *s) -{ -    *s = bswap32(*s); -} - -static inline void bswap64s(uint64_t *s) -{ -    *s = bswap64(*s); -} - -#if defined(HOST_WORDS_BIGENDIAN) -#define be_bswap(v, size) (v) -#define le_bswap(v, size) glue(bswap, size)(v) -#define be_bswaps(v, size) -#define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0) -#else -#define le_bswap(v, size) (v) -#define be_bswap(v, size) glue(bswap, size)(v) -#define le_bswaps(v, size) -#define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0) -#endif - -#define CPU_CONVERT(endian, size, type)\ -static inline type endian ## size ## _to_cpu(type v)\ -{\ -    return glue(endian, _bswap)(v, size);\ -}\ -\ -static inline type cpu_to_ ## endian ## size(type v)\ -{\ -    return glue(endian, _bswap)(v, size);\ -}\ -\ -static inline void endian ## size ## _to_cpus(type *p)\ -{\ -    glue(endian, _bswaps)(p, size);\ -}\ -\ -static inline void cpu_to_ ## endian ## size ## s(type *p)\ -{\ -    glue(endian, _bswaps)(p, size);\ -}\ -\ -static inline type endian ## size ## _to_cpup(const type *p)\ -{\ -    return glue(glue(endian, size), _to_cpu)(*p);\ -}\ -\ -static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\ -{\ -    *p = glue(glue(cpu_to_, endian), size)(v);\ -} - -CPU_CONVERT(be, 16, uint16_t) -CPU_CONVERT(be, 32, uint32_t) -CPU_CONVERT(be, 64, uint64_t) - -CPU_CONVERT(le, 16, uint16_t) -CPU_CONVERT(le, 32, uint32_t) -CPU_CONVERT(le, 64, uint64_t) - -/* len must be one of 1, 2, 4 */ -static inline uint32_t qemu_bswap_len(uint32_t value, int len) -{ -    return bswap32(value) >> (32 - 8 * len); -} - -/* Unions for reinterpreting between floats and integers.  */ - -typedef union { -    float32 f; -    uint32_t l; -} CPU_FloatU; - -typedef union { -    float64 d; -#if defined(HOST_WORDS_BIGENDIAN) -    struct { -        uint32_t upper; -        uint32_t lower; -    } l; -#else -    struct { -        uint32_t lower; -        uint32_t upper; -    } l; -#endif -    uint64_t ll; -} CPU_DoubleU; - -typedef union { -     floatx80 d; -     struct { -         uint64_t lower; -         uint16_t upper; -     } l; -} CPU_LDoubleU; - -typedef union { -    float128 q; -#if defined(HOST_WORDS_BIGENDIAN) -    struct { -        uint32_t upmost; -        uint32_t upper; -        uint32_t lower; -        uint32_t lowest; -    } l; -    struct { -        uint64_t upper; -        uint64_t lower; -    } ll; -#else -    struct { -        uint32_t lowest; -        uint32_t lower; -        uint32_t upper; -        uint32_t upmost; -    } l; -    struct { -        uint64_t lower; -        uint64_t upper; -    } ll; -#endif -} CPU_QuadU; - -/* unaligned/endian-independent pointer access */ - -/* - * the generic syntax is: - * - * load: ld{type}{sign}{size}{endian}_p(ptr) - * - * store: st{type}{size}{endian}_p(ptr, val) - * - * Note there are small differences with the softmmu access API! - * - * type is: - * (empty): integer access - *   f    : float access - * - * sign is: - * (empty): for floats or 32 bit size - *   u    : unsigned - *   s    : signed - * - * size is: - *   b: 8 bits - *   w: 16 bits - *   l: 32 bits - *   q: 64 bits - * - * endian is: - * (empty): host endian - *   be   : big endian - *   le   : little endian - */ - -static inline int ldub_p(const void *ptr) -{ -    return *(uint8_t *)ptr; -} - -static inline int ldsb_p(const void *ptr) -{ -    return *(int8_t *)ptr; -} - -static inline void stb_p(void *ptr, int v) -{ -    *(uint8_t *)ptr = v; -} - -/* Any compiler worth its salt will turn these memcpy into native unaligned -   operations.  Thus we don't need to play games with packed attributes, or -   inline byte-by-byte stores.  */ - -static inline int lduw_p(const void *ptr) -{ -    uint16_t r; -    memcpy(&r, ptr, sizeof(r)); -    return r; -} - -static inline int ldsw_p(const void *ptr) -{ -    int16_t r; -    memcpy(&r, ptr, sizeof(r)); -    return r; -} - -static inline void stw_p(void *ptr, uint16_t v) -{ -    memcpy(ptr, &v, sizeof(v)); -} - -static inline int ldl_p(const void *ptr) -{ -    int32_t r; -    memcpy(&r, ptr, sizeof(r)); -    return r; -} - -static inline void stl_p(void *ptr, uint32_t v) -{ -    memcpy(ptr, &v, sizeof(v)); -} - -static inline uint64_t ldq_p(const void *ptr) -{ -    uint64_t r; -    memcpy(&r, ptr, sizeof(r)); -    return r; -} - -static inline void stq_p(void *ptr, uint64_t v) -{ -    memcpy(ptr, &v, sizeof(v)); -} - -static inline int lduw_le_p(const void *ptr) -{ -    return (uint16_t)le_bswap(lduw_p(ptr), 16); -} - -static inline int ldsw_le_p(const void *ptr) -{ -    return (int16_t)le_bswap(lduw_p(ptr), 16); -} - -static inline int ldl_le_p(const void *ptr) -{ -    return le_bswap(ldl_p(ptr), 32); -} - -static inline uint64_t ldq_le_p(const void *ptr) -{ -    return le_bswap(ldq_p(ptr), 64); -} - -static inline void stw_le_p(void *ptr, int v) -{ -    stw_p(ptr, le_bswap(v, 16)); -} - -static inline void stl_le_p(void *ptr, int v) -{ -    stl_p(ptr, le_bswap(v, 32)); -} - -static inline void stq_le_p(void *ptr, uint64_t v) -{ -    stq_p(ptr, le_bswap(v, 64)); -} - -/* float access */ - -static inline float32 ldfl_le_p(const void *ptr) -{ -    CPU_FloatU u; -    u.l = ldl_le_p(ptr); -    return u.f; -} - -static inline void stfl_le_p(void *ptr, float32 v) -{ -    CPU_FloatU u; -    u.f = v; -    stl_le_p(ptr, u.l); -} - -static inline float64 ldfq_le_p(const void *ptr) -{ -    CPU_DoubleU u; -    u.ll = ldq_le_p(ptr); -    return u.d; -} - -static inline void stfq_le_p(void *ptr, float64 v) -{ -    CPU_DoubleU u; -    u.d = v; -    stq_le_p(ptr, u.ll); -} - -static inline int lduw_be_p(const void *ptr) -{ -    return (uint16_t)be_bswap(lduw_p(ptr), 16); -} - -static inline int ldsw_be_p(const void *ptr) -{ -    return (int16_t)be_bswap(lduw_p(ptr), 16); -} - -static inline int ldl_be_p(const void *ptr) -{ -    return be_bswap(ldl_p(ptr), 32); -} - -static inline uint64_t ldq_be_p(const void *ptr) -{ -    return be_bswap(ldq_p(ptr), 64); -} - -static inline void stw_be_p(void *ptr, int v) -{ -    stw_p(ptr, be_bswap(v, 16)); -} - -static inline void stl_be_p(void *ptr, int v) -{ -    stl_p(ptr, be_bswap(v, 32)); -} - -static inline void stq_be_p(void *ptr, uint64_t v) -{ -    stq_p(ptr, be_bswap(v, 64)); -} - -/* float access */ - -static inline float32 ldfl_be_p(const void *ptr) -{ -    CPU_FloatU u; -    u.l = ldl_be_p(ptr); -    return u.f; -} - -static inline void stfl_be_p(void *ptr, float32 v) -{ -    CPU_FloatU u; -    u.f = v; -    stl_be_p(ptr, u.l); -} - -static inline float64 ldfq_be_p(const void *ptr) -{ -    CPU_DoubleU u; -    u.ll = ldq_be_p(ptr); -    return u.d; -} - -static inline void stfq_be_p(void *ptr, float64 v) -{ -    CPU_DoubleU u; -    u.d = v; -    stq_be_p(ptr, u.ll); -} - -/* Legacy unaligned versions.  Note that we never had a complete set.  */ - -static inline void cpu_to_le16wu(uint16_t *p, uint16_t v) -{ -    stw_le_p(p, v); -} - -static inline void cpu_to_le32wu(uint32_t *p, uint32_t v) -{ -    stl_le_p(p, v); -} - -static inline uint16_t le16_to_cpupu(const uint16_t *p) -{ -    return lduw_le_p(p); -} - -static inline uint32_t le32_to_cpupu(const uint32_t *p) -{ -    return ldl_le_p(p); -} - -static inline uint32_t be32_to_cpupu(const uint32_t *p) -{ -    return ldl_be_p(p); -} - -static inline void cpu_to_be16wu(uint16_t *p, uint16_t v) -{ -    stw_be_p(p, v); -} - -static inline void cpu_to_be32wu(uint32_t *p, uint32_t v) -{ -    stl_be_p(p, v); -} - -static inline void cpu_to_be64wu(uint64_t *p, uint64_t v) -{ -    stq_be_p(p, v); -} - -static inline void cpu_to_32wu(uint32_t *p, uint32_t v) -{ -    stl_p(p, v); -} - -static inline unsigned long leul_to_cpu(unsigned long v) -{ -    /* In order to break an include loop between here and -       qemu-common.h, don't rely on HOST_LONG_BITS.  */ -#if ULONG_MAX == UINT32_MAX -    return le_bswap(v, 32); -#elif ULONG_MAX == UINT64_MAX -    return le_bswap(v, 64); -#else -# error Unknown sizeof long -#endif -} - -#undef le_bswap -#undef be_bswap -#undef le_bswaps -#undef be_bswaps - -#endif /* BSWAP_H */ diff --git a/contrib/qemu/include/qemu/compiler.h b/contrib/qemu/include/qemu/compiler.h deleted file mode 100644 index 155b358964a..00000000000 --- a/contrib/qemu/include/qemu/compiler.h +++ /dev/null @@ -1,55 +0,0 @@ -/* public domain */ - -#ifndef COMPILER_H -#define COMPILER_H - -#include "config-host.h" - -/*---------------------------------------------------------------------------- -| The macro QEMU_GNUC_PREREQ tests for minimum version of the GNU C compiler. -| The code is a copy of SOFTFLOAT_GNUC_PREREQ, see softfloat-macros.h. -*----------------------------------------------------------------------------*/ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) -# define QEMU_GNUC_PREREQ(maj, min) \ -         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) -#else -# define QEMU_GNUC_PREREQ(maj, min) 0 -#endif - -#define QEMU_NORETURN __attribute__ ((__noreturn__)) - -#if QEMU_GNUC_PREREQ(3, 4) -#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define QEMU_WARN_UNUSED_RESULT -#endif - -#if defined(_WIN32) -# define QEMU_PACKED __attribute__((gcc_struct, packed)) -#else -# define QEMU_PACKED __attribute__((packed)) -#endif - -#define cat(x,y) x ## y -#define cat2(x,y) cat(x,y) -#define QEMU_BUILD_BUG_ON(x) \ -    typedef char cat2(qemu_build_bug_on__,__LINE__)[(x)?-1:1] __attribute__((unused)); - -#if defined __GNUC__ -# if !QEMU_GNUC_PREREQ(4, 4) -   /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ -#  define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) -# else -   /* Use gnu_printf when supported (qemu uses standard format strings). */ -#  define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) -#  if defined(_WIN32) -    /* Map __printf__ to __gnu_printf__ because we want standard format strings -     * even when MinGW or GLib include files use __printf__. */ -#   define __printf__ __gnu_printf__ -#  endif -# endif -#else -#define GCC_FMT_ATTR(n, m) -#endif - -#endif /* COMPILER_H */ diff --git a/contrib/qemu/include/qemu/error-report.h b/contrib/qemu/include/qemu/error-report.h deleted file mode 100644 index 3b098a91730..00000000000 --- a/contrib/qemu/include/qemu/error-report.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Error reporting - * - * Copyright (C) 2010 Red Hat Inc. - * - * Authors: - *  Markus Armbruster <armbru@redhat.com>, - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef QEMU_ERROR_H -#define QEMU_ERROR_H - -#include <stdarg.h> -#include <stdbool.h> -#include "qemu/compiler.h" - -typedef struct Location { -    /* all members are private to qemu-error.c */ -    enum { LOC_NONE, LOC_CMDLINE, LOC_FILE } kind; -    int num; -    const void *ptr; -    struct Location *prev; -} Location; - -Location *loc_push_restore(Location *loc); -Location *loc_push_none(Location *loc); -Location *loc_pop(Location *loc); -Location *loc_save(Location *loc); -void loc_restore(Location *loc); -void loc_set_none(void); -void loc_set_cmdline(char **argv, int idx, int cnt); -void loc_set_file(const char *fname, int lno); - -void error_vprintf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); -void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2); -void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2); -void error_print_loc(void); -void error_set_progname(const char *argv0); -void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); -const char *error_get_progname(void); -extern bool enable_timestamp_msg; - -#endif diff --git a/contrib/qemu/include/qemu/event_notifier.h b/contrib/qemu/include/qemu/event_notifier.h deleted file mode 100644 index 88b57af7ce8..00000000000 --- a/contrib/qemu/include/qemu/event_notifier.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * event notifier support - * - * Copyright Red Hat, Inc. 2010 - * - * Authors: - *  Michael S. Tsirkin <mst@redhat.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef QEMU_EVENT_NOTIFIER_H -#define QEMU_EVENT_NOTIFIER_H - -#include "qemu-common.h" - -#ifdef _WIN32 -#include <windows.h> -#endif - -struct EventNotifier { -#ifdef _WIN32 -    HANDLE event; -#else -    int rfd; -    int wfd; -#endif -}; - -typedef void EventNotifierHandler(EventNotifier *); - -int event_notifier_init(EventNotifier *, int active); -void event_notifier_cleanup(EventNotifier *); -int event_notifier_set(EventNotifier *); -int event_notifier_test_and_clear(EventNotifier *); -int event_notifier_set_handler(EventNotifier *, EventNotifierHandler *); - -#ifdef CONFIG_POSIX -void event_notifier_init_fd(EventNotifier *, int fd); -int event_notifier_get_fd(EventNotifier *); -#else -HANDLE event_notifier_get_handle(EventNotifier *); -#endif - -#endif diff --git a/contrib/qemu/include/qemu/hbitmap.h b/contrib/qemu/include/qemu/hbitmap.h deleted file mode 100644 index 550d7ce2c39..00000000000 --- a/contrib/qemu/include/qemu/hbitmap.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Hierarchical Bitmap Data Type - * - * Copyright Red Hat, Inc., 2012 - * - * Author: Paolo Bonzini <pbonzini@redhat.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or - * later.  See the COPYING file in the top-level directory. - */ - -#ifndef HBITMAP_H -#define HBITMAP_H 1 - -#include <limits.h> -#include <stdint.h> -#include <stdbool.h> -#include "bitops.h" -#include "host-utils.h" - -typedef struct HBitmap HBitmap; -typedef struct HBitmapIter HBitmapIter; - -#define BITS_PER_LEVEL         (BITS_PER_LONG == 32 ? 5 : 6) - -/* For 32-bit, the largest that fits in a 4 GiB address space. - * For 64-bit, the number of sectors in 1 PiB.  Good luck, in - * either case... :) - */ -#define HBITMAP_LOG_MAX_SIZE   (BITS_PER_LONG == 32 ? 34 : 41) - -/* We need to place a sentinel in level 0 to speed up iteration.  Thus, - * we do this instead of HBITMAP_LOG_MAX_SIZE / BITS_PER_LEVEL.  The - * difference is that it allocates an extra level when HBITMAP_LOG_MAX_SIZE - * is an exact multiple of BITS_PER_LEVEL. - */ -#define HBITMAP_LEVELS         ((HBITMAP_LOG_MAX_SIZE / BITS_PER_LEVEL) + 1) - -struct HBitmapIter { -    const HBitmap *hb; - -    /* Copied from hb for access in the inline functions (hb is opaque).  */ -    int granularity; - -    /* Entry offset into the last-level array of longs.  */ -    size_t pos; - -    /* The currently-active path in the tree.  Each item of cur[i] stores -     * the bits (i.e. the subtrees) yet to be processed under that node. -     */ -    unsigned long cur[HBITMAP_LEVELS]; -}; - -/** - * hbitmap_alloc: - * @size: Number of bits in the bitmap. - * @granularity: Granularity of the bitmap.  Aligned groups of 2^@granularity - * bits will be represented by a single bit.  Each operation on a - * range of bits first rounds the bits to determine which group they land - * in, and then affect the entire set; iteration will only visit the first - * bit of each group. - * - * Allocate a new HBitmap. - */ -HBitmap *hbitmap_alloc(uint64_t size, int granularity); - -/** - * hbitmap_empty: - * @hb: HBitmap to operate on. - * - * Return whether the bitmap is empty. - */ -bool hbitmap_empty(const HBitmap *hb); - -/** - * hbitmap_granularity: - * @hb: HBitmap to operate on. - * - * Return the granularity of the HBitmap. - */ -int hbitmap_granularity(const HBitmap *hb); - -/** - * hbitmap_count: - * @hb: HBitmap to operate on. - * - * Return the number of bits set in the HBitmap. - */ -uint64_t hbitmap_count(const HBitmap *hb); - -/** - * hbitmap_set: - * @hb: HBitmap to operate on. - * @start: First bit to set (0-based). - * @count: Number of bits to set. - * - * Set a consecutive range of bits in an HBitmap. - */ -void hbitmap_set(HBitmap *hb, uint64_t start, uint64_t count); - -/** - * hbitmap_reset: - * @hb: HBitmap to operate on. - * @start: First bit to reset (0-based). - * @count: Number of bits to reset. - * - * Reset a consecutive range of bits in an HBitmap. - */ -void hbitmap_reset(HBitmap *hb, uint64_t start, uint64_t count); - -/** - * hbitmap_get: - * @hb: HBitmap to operate on. - * @item: Bit to query (0-based). - * - * Return whether the @item-th bit in an HBitmap is set. - */ -bool hbitmap_get(const HBitmap *hb, uint64_t item); - -/** - * hbitmap_free: - * @hb: HBitmap to operate on. - * - * Free an HBitmap and all of its associated memory. - */ -void hbitmap_free(HBitmap *hb); - -/** - * hbitmap_iter_init: - * @hbi: HBitmapIter to initialize. - * @hb: HBitmap to iterate on. - * @first: First bit to visit (0-based, must be strictly less than the - * size of the bitmap). - * - * Set up @hbi to iterate on the HBitmap @hb.  hbitmap_iter_next will return - * the lowest-numbered bit that is set in @hb, starting at @first. - * - * Concurrent setting of bits is acceptable, and will at worst cause the - * iteration to miss some of those bits.  Resetting bits before the current - * position of the iterator is also okay.  However, concurrent resetting of - * bits can lead to unexpected behavior if the iterator has not yet reached - * those bits. - */ -void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first); - -/* hbitmap_iter_skip_words: - * @hbi: HBitmapIter to operate on. - * - * Internal function used by hbitmap_iter_next and hbitmap_iter_next_word. - */ -unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi); - -/** - * hbitmap_iter_next: - * @hbi: HBitmapIter to operate on. - * - * Return the next bit that is set in @hbi's associated HBitmap, - * or -1 if all remaining bits are zero. - */ -static inline int64_t hbitmap_iter_next(HBitmapIter *hbi) -{ -    unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1]; -    int64_t item; - -    if (cur == 0) { -        cur = hbitmap_iter_skip_words(hbi); -        if (cur == 0) { -            return -1; -        } -    } - -    /* The next call will resume work from the next bit.  */ -    hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1); -    item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur); - -    return item << hbi->granularity; -} - -/** - * hbitmap_iter_next_word: - * @hbi: HBitmapIter to operate on. - * @p_cur: Location where to store the next non-zero word. - * - * Return the index of the next nonzero word that is set in @hbi's - * associated HBitmap, and set *p_cur to the content of that word - * (bits before the index that was passed to hbitmap_iter_init are - * trimmed on the first call).  Return -1, and set *p_cur to zero, - * if all remaining words are zero. - */ -static inline size_t hbitmap_iter_next_word(HBitmapIter *hbi, unsigned long *p_cur) -{ -    unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1]; - -    if (cur == 0) { -        cur = hbitmap_iter_skip_words(hbi); -        if (cur == 0) { -            *p_cur = 0; -            return -1; -        } -    } - -    /* The next call will resume work from the next word.  */ -    hbi->cur[HBITMAP_LEVELS - 1] = 0; -    *p_cur = cur; -    return hbi->pos; -} - - -#endif diff --git a/contrib/qemu/include/qemu/host-utils.h b/contrib/qemu/include/qemu/host-utils.h deleted file mode 100644 index 0f688c1c00a..00000000000 --- a/contrib/qemu/include/qemu/host-utils.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Utility compute operations used by translated code. - * - * Copyright (c) 2007 Thiemo Seufer - * Copyright (c) 2007 Jocelyn Mayer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef HOST_UTILS_H -#define HOST_UTILS_H 1 - -#include "qemu/compiler.h"   /* QEMU_GNUC_PREREQ */ -#include <limits.h> - -#ifdef CONFIG_INT128 -static inline void mulu64(uint64_t *plow, uint64_t *phigh, -                          uint64_t a, uint64_t b) -{ -    __uint128_t r = (__uint128_t)a * b; -    *plow = r; -    *phigh = r >> 64; -} - -static inline void muls64(uint64_t *plow, uint64_t *phigh, -                          int64_t a, int64_t b) -{ -    __int128_t r = (__int128_t)a * b; -    *plow = r; -    *phigh = r >> 64; -} -#else -void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b); -void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b); -#endif - -/** - * clz32 - count leading zeros in a 32-bit value. - * @val: The value to search - * - * Returns 32 if the value is zero.  Note that the GCC builtin is - * undefined if the value is zero. - */ -static inline int clz32(uint32_t val) -{ -#if QEMU_GNUC_PREREQ(3, 4) -    return val ? __builtin_clz(val) : 32; -#else -    /* Binary search for the leading one bit.  */ -    int cnt = 0; - -    if (!(val & 0xFFFF0000U)) { -        cnt += 16; -        val <<= 16; -    } -    if (!(val & 0xFF000000U)) { -        cnt += 8; -        val <<= 8; -    } -    if (!(val & 0xF0000000U)) { -        cnt += 4; -        val <<= 4; -    } -    if (!(val & 0xC0000000U)) { -        cnt += 2; -        val <<= 2; -    } -    if (!(val & 0x80000000U)) { -        cnt++; -        val <<= 1; -    } -    if (!(val & 0x80000000U)) { -        cnt++; -    } -    return cnt; -#endif -} - -/** - * clo32 - count leading ones in a 32-bit value. - * @val: The value to search - * - * Returns 32 if the value is -1. - */ -static inline int clo32(uint32_t val) -{ -    return clz32(~val); -} - -/** - * clz64 - count leading zeros in a 64-bit value. - * @val: The value to search - * - * Returns 64 if the value is zero.  Note that the GCC builtin is - * undefined if the value is zero. - */ -static inline int clz64(uint64_t val) -{ -#if QEMU_GNUC_PREREQ(3, 4) -    return val ? __builtin_clzll(val) : 64; -#else -    int cnt = 0; - -    if (!(val >> 32)) { -        cnt += 32; -    } else { -        val >>= 32; -    } - -    return cnt + clz32(val); -#endif -} - -/** - * clo64 - count leading ones in a 64-bit value. - * @val: The value to search - * - * Returns 64 if the value is -1. - */ -static inline int clo64(uint64_t val) -{ -    return clz64(~val); -} - -/** - * ctz32 - count trailing zeros in a 32-bit value. - * @val: The value to search - * - * Returns 32 if the value is zero.  Note that the GCC builtin is - * undefined if the value is zero. - */ -static inline int ctz32(uint32_t val) -{ -#if QEMU_GNUC_PREREQ(3, 4) -    return val ? __builtin_ctz(val) : 32; -#else -    /* Binary search for the trailing one bit.  */ -    int cnt; - -    cnt = 0; -    if (!(val & 0x0000FFFFUL)) { -        cnt += 16; -        val >>= 16; -    } -    if (!(val & 0x000000FFUL)) { -        cnt += 8; -        val >>= 8; -    } -    if (!(val & 0x0000000FUL)) { -        cnt += 4; -        val >>= 4; -    } -    if (!(val & 0x00000003UL)) { -        cnt += 2; -        val >>= 2; -    } -    if (!(val & 0x00000001UL)) { -        cnt++; -        val >>= 1; -    } -    if (!(val & 0x00000001UL)) { -        cnt++; -    } - -    return cnt; -#endif -} - -/** - * cto32 - count trailing ones in a 32-bit value. - * @val: The value to search - * - * Returns 32 if the value is -1. - */ -static inline int cto32(uint32_t val) -{ -    return ctz32(~val); -} - -/** - * ctz64 - count trailing zeros in a 64-bit value. - * @val: The value to search - * - * Returns 64 if the value is zero.  Note that the GCC builtin is - * undefined if the value is zero. - */ -static inline int ctz64(uint64_t val) -{ -#if QEMU_GNUC_PREREQ(3, 4) -    return val ? __builtin_ctzll(val) : 64; -#else -    int cnt; - -    cnt = 0; -    if (!((uint32_t)val)) { -        cnt += 32; -        val >>= 32; -    } - -    return cnt + ctz32(val); -#endif -} - -/** - * ctz64 - count trailing ones in a 64-bit value. - * @val: The value to search - * - * Returns 64 if the value is -1. - */ -static inline int cto64(uint64_t val) -{ -    return ctz64(~val); -} - -/** - * ctpop8 - count the population of one bits in an 8-bit value. - * @val: The value to search - */ -static inline int ctpop8(uint8_t val) -{ -#if QEMU_GNUC_PREREQ(3, 4) -    return __builtin_popcount(val); -#else -    val = (val & 0x55) + ((val >> 1) & 0x55); -    val = (val & 0x33) + ((val >> 2) & 0x33); -    val = (val & 0x0f) + ((val >> 4) & 0x0f); - -    return val; -#endif -} - -/** - * ctpop16 - count the population of one bits in a 16-bit value. - * @val: The value to search - */ -static inline int ctpop16(uint16_t val) -{ -#if QEMU_GNUC_PREREQ(3, 4) -    return __builtin_popcount(val); -#else -    val = (val & 0x5555) + ((val >> 1) & 0x5555); -    val = (val & 0x3333) + ((val >> 2) & 0x3333); -    val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f); -    val = (val & 0x00ff) + ((val >> 8) & 0x00ff); - -    return val; -#endif -} - -/** - * ctpop32 - count the population of one bits in a 32-bit value. - * @val: The value to search - */ -static inline int ctpop32(uint32_t val) -{ -#if QEMU_GNUC_PREREQ(3, 4) -    return __builtin_popcount(val); -#else -    val = (val & 0x55555555) + ((val >>  1) & 0x55555555); -    val = (val & 0x33333333) + ((val >>  2) & 0x33333333); -    val = (val & 0x0f0f0f0f) + ((val >>  4) & 0x0f0f0f0f); -    val = (val & 0x00ff00ff) + ((val >>  8) & 0x00ff00ff); -    val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff); - -    return val; -#endif -} - -/** - * ctpop64 - count the population of one bits in a 64-bit value. - * @val: The value to search - */ -static inline int ctpop64(uint64_t val) -{ -#if QEMU_GNUC_PREREQ(3, 4) -    return __builtin_popcountll(val); -#else -    val = (val & 0x5555555555555555ULL) + ((val >>  1) & 0x5555555555555555ULL); -    val = (val & 0x3333333333333333ULL) + ((val >>  2) & 0x3333333333333333ULL); -    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) & 0x0f0f0f0f0f0f0f0fULL); -    val = (val & 0x00ff00ff00ff00ffULL) + ((val >>  8) & 0x00ff00ff00ff00ffULL); -    val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL); -    val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL); - -    return val; -#endif -} - -/* Host type specific sizes of these routines.  */ - -#if ULONG_MAX == UINT32_MAX -# define clzl   clz32 -# define ctzl   ctz32 -# define clol   clo32 -# define ctol   cto32 -# define ctpopl ctpop32 -#elif ULONG_MAX == UINT64_MAX -# define clzl   clz64 -# define ctzl   ctz64 -# define clol   clo64 -# define ctol   cto64 -# define ctpopl ctpop64 -#else -# error Unknown sizeof long -#endif - -#endif diff --git a/contrib/qemu/include/qemu/iov.h b/contrib/qemu/include/qemu/iov.h deleted file mode 100644 index 68d25f29b76..00000000000 --- a/contrib/qemu/include/qemu/iov.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Helpers for using (partial) iovecs. - * - * Copyright (C) 2010 Red Hat, Inc. - * - * Author(s): - *  Amit Shah <amit.shah@redhat.com> - *  Michael Tokarev <mjt@tls.msk.ru> - * - * This work is licensed under the terms of the GNU GPL, version 2.  See - * the COPYING file in the top-level directory. - */ - -#ifndef IOV_H -#define IOV_H - -#include "qemu-common.h" - -/** - * count and return data size, in bytes, of an iovec - * starting at `iov' of `iov_cnt' number of elements. - */ -size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt); - -/** - * Copy from single continuous buffer to scatter-gather vector of buffers - * (iovec) and back like memcpy() between two continuous memory regions. - * Data in single continuous buffer starting at address `buf' and - * `bytes' bytes long will be copied to/from an iovec `iov' with - * `iov_cnt' number of elements, starting at byte position `offset' - * within the iovec.  If the iovec does not contain enough space, - * only part of data will be copied, up to the end of the iovec. - * Number of bytes actually copied will be returned, which is - *  min(bytes, iov_size(iov)-offset) - * `Offset' must point to the inside of iovec. - * It is okay to use very large value for `bytes' since we're - * limited by the size of the iovec anyway, provided that the - * buffer pointed to by buf has enough space.  One possible - * such "large" value is -1 (sinice size_t is unsigned), - * so specifying `-1' as `bytes' means 'up to the end of iovec'. - */ -size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt, -                    size_t offset, const void *buf, size_t bytes); -size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, -                  size_t offset, void *buf, size_t bytes); - -/** - * Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements, - * starting at byte offset `start', to value `fillc', repeating it - * `bytes' number of times.  `Offset' must point to the inside of iovec. - * If `bytes' is large enough, only last bytes portion of iovec, - * up to the end of it, will be filled with the specified value. - * Function return actual number of bytes processed, which is - * min(size, iov_size(iov) - offset). - * Again, it is okay to use large value for `bytes' to mean "up to the end". - */ -size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt, -                  size_t offset, int fillc, size_t bytes); - -/* - * Send/recv data from/to iovec buffers directly - * - * `offset' bytes in the beginning of iovec buffer are skipped and - * next `bytes' bytes are used, which must be within data of iovec. - * - *   r = iov_send_recv(sockfd, iov, iovcnt, offset, bytes, true); - * - * is logically equivalent to - * - *   char *buf = malloc(bytes); - *   iov_to_buf(iov, iovcnt, offset, buf, bytes); - *   r = send(sockfd, buf, bytes, 0); - *   free(buf); - * - * For iov_send_recv() _whole_ area being sent or received - * should be within the iovec, not only beginning of it. - */ -ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, -                      size_t offset, size_t bytes, bool do_send); -#define iov_recv(sockfd, iov, iov_cnt, offset, bytes) \ -  iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, false) -#define iov_send(sockfd, iov, iov_cnt, offset, bytes) \ -  iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, true) - -/** - * Produce a text hexdump of iovec `iov' with `iov_cnt' number of elements - * in file `fp', prefixing each line with `prefix' and processing not more - * than `limit' data bytes. - */ -void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt, -                 FILE *fp, const char *prefix, size_t limit); - -/* - * Partial copy of vector from iov to dst_iov (data is not copied). - * dst_iov overlaps iov at a specified offset. - * size of dst_iov is at most bytes. dst vector count is returned. - */ -unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt, -                 const struct iovec *iov, unsigned int iov_cnt, -                 size_t offset, size_t bytes); - -/* - * Remove a given number of bytes from the front or back of a vector. - * This may update iov and/or iov_cnt to exclude iovec elements that are - * no longer required. - * - * The number of bytes actually discarded is returned.  This number may be - * smaller than requested if the vector is too small. - */ -size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt, -                         size_t bytes); -size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt, -                        size_t bytes); - -#endif diff --git a/contrib/qemu/include/qemu/main-loop.h b/contrib/qemu/include/qemu/main-loop.h deleted file mode 100644 index 6f0200a7acc..00000000000 --- a/contrib/qemu/include/qemu/main-loop.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * QEMU System Emulator - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef QEMU_MAIN_LOOP_H -#define QEMU_MAIN_LOOP_H 1 - -#include "block/aio.h" - -#define SIG_IPI SIGUSR1 - -/** - * qemu_init_main_loop: Set up the process so that it can run the main loop. - * - * This includes setting up signal handlers.  It should be called before - * any other threads are created.  In addition, threads other than the - * main one should block signals that are trapped by the main loop. - * For simplicity, you can consider these signals to be safe: SIGUSR1, - * SIGUSR2, thread signals (SIGFPE, SIGILL, SIGSEGV, SIGBUS) and real-time - * signals if available.  Remember that Windows in practice does not have - * signals, though. - * - * In the case of QEMU tools, this will also start/initialize timers. - */ -int qemu_init_main_loop(void); - -/** - * main_loop_wait: Run one iteration of the main loop. - * - * If @nonblocking is true, poll for events, otherwise suspend until - * one actually occurs.  The main loop usually consists of a loop that - * repeatedly calls main_loop_wait(false). - * - * Main loop services include file descriptor callbacks, bottom halves - * and timers (defined in qemu-timer.h).  Bottom halves are similar to timers - * that execute immediately, but have a lower overhead and scheduling them - * is wait-free, thread-safe and signal-safe. - * - * It is sometimes useful to put a whole program in a coroutine.  In this - * case, the coroutine actually should be started from within the main loop, - * so that the main loop can run whenever the coroutine yields.  To do this, - * you can use a bottom half to enter the coroutine as soon as the main loop - * starts: - * - *     void enter_co_bh(void *opaque) { - *         QEMUCoroutine *co = opaque; - *         qemu_coroutine_enter(co, NULL); - *     } - * - *     ... - *     QEMUCoroutine *co = qemu_coroutine_create(coroutine_entry); - *     QEMUBH *start_bh = qemu_bh_new(enter_co_bh, co); - *     qemu_bh_schedule(start_bh); - *     while (...) { - *         main_loop_wait(false); - *     } - * - * (In the future we may provide a wrapper for this). - * - * @nonblocking: Whether the caller should block until an event occurs. - */ -int main_loop_wait(int nonblocking); - -/** - * qemu_get_aio_context: Return the main loop's AioContext - */ -AioContext *qemu_get_aio_context(void); - -/** - * qemu_notify_event: Force processing of pending events. - * - * Similar to signaling a condition variable, qemu_notify_event forces - * main_loop_wait to look at pending events and exit.  The caller of - * main_loop_wait will usually call it again very soon, so qemu_notify_event - * also has the side effect of recalculating the sets of file descriptors - * that the main loop waits for. - * - * Calling qemu_notify_event is rarely necessary, because main loop - * services (bottom halves and timers) call it themselves.  One notable - * exception occurs when using qemu_set_fd_handler2 (see below). - */ -void qemu_notify_event(void); - -#ifdef _WIN32 -/* return TRUE if no sleep should be done afterwards */ -typedef int PollingFunc(void *opaque); - -/** - * qemu_add_polling_cb: Register a Windows-specific polling callback - * - * Currently, under Windows some events are polled rather than waited for. - * Polling callbacks do not ensure that @func is called timely, because - * the main loop might wait for an arbitrarily long time.  If possible, - * you should instead create a separate thread that does a blocking poll - * and set a Win32 event object.  The event can then be passed to - * qemu_add_wait_object. - * - * Polling callbacks really have nothing Windows specific in them, but - * as they are a hack and are currently not necessary under POSIX systems, - * they are only available when QEMU is running under Windows. - * - * @func: The function that does the polling, and returns 1 to force - * immediate completion of main_loop_wait. - * @opaque: A pointer-size value that is passed to @func. - */ -int qemu_add_polling_cb(PollingFunc *func, void *opaque); - -/** - * qemu_del_polling_cb: Unregister a Windows-specific polling callback - * - * This function removes a callback that was registered with - * qemu_add_polling_cb. - * - * @func: The function that was passed to qemu_add_polling_cb. - * @opaque: A pointer-size value that was passed to qemu_add_polling_cb. - */ -void qemu_del_polling_cb(PollingFunc *func, void *opaque); - -/* Wait objects handling */ -typedef void WaitObjectFunc(void *opaque); - -/** - * qemu_add_wait_object: Register a callback for a Windows handle - * - * Under Windows, the iohandler mechanism can only be used with sockets. - * QEMU must use the WaitForMultipleObjects API to wait on other handles. - * This function registers a #HANDLE with QEMU, so that it will be included - * in the main loop's calls to WaitForMultipleObjects.  When the handle - * is in a signaled state, QEMU will call @func. - * - * @handle: The Windows handle to be observed. - * @func: A function to be called when @handle is in a signaled state. - * @opaque: A pointer-size value that is passed to @func. - */ -int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); - -/** - * qemu_del_wait_object: Unregister a callback for a Windows handle - * - * This function removes a callback that was registered with - * qemu_add_wait_object. - * - * @func: The function that was passed to qemu_add_wait_object. - * @opaque: A pointer-size value that was passed to qemu_add_wait_object. - */ -void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); -#endif - -/* async I/O support */ - -typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); -typedef int IOCanReadHandler(void *opaque); - -/** - * qemu_set_fd_handler2: Register a file descriptor with the main loop - * - * This function tells the main loop to wake up whenever one of the - * following conditions is true: - * - * 1) if @fd_write is not %NULL, when the file descriptor is writable; - * - * 2) if @fd_read is not %NULL, when the file descriptor is readable. - * - * @fd_read_poll can be used to disable the @fd_read callback temporarily. - * This is useful to avoid calling qemu_set_fd_handler2 every time the - * client becomes interested in reading (or dually, stops being interested). - * A typical example is when @fd is a listening socket and you want to bound - * the number of active clients.  Remember to call qemu_notify_event whenever - * the condition may change from %false to %true. - * - * The callbacks that are set up by qemu_set_fd_handler2 are level-triggered. - * If @fd_read does not read from @fd, or @fd_write does not write to @fd - * until its buffers are full, they will be called again on the next - * iteration. - * - * @fd: The file descriptor to be observed.  Under Windows it must be - * a #SOCKET. - * - * @fd_read_poll: A function that returns 1 if the @fd_read callback - * should be fired.  If the function returns 0, the main loop will not - * end its iteration even if @fd becomes readable. - * - * @fd_read: A level-triggered callback that is fired if @fd is readable - * at the beginning of a main loop iteration, or if it becomes readable - * during one. - * - * @fd_write: A level-triggered callback that is fired when @fd is writable - * at the beginning of a main loop iteration, or if it becomes writable - * during one. - * - * @opaque: A pointer-sized value that is passed to @fd_read_poll, - * @fd_read and @fd_write. - */ -int qemu_set_fd_handler2(int fd, -                         IOCanReadHandler *fd_read_poll, -                         IOHandler *fd_read, -                         IOHandler *fd_write, -                         void *opaque); - -/** - * qemu_set_fd_handler: Register a file descriptor with the main loop - * - * This function tells the main loop to wake up whenever one of the - * following conditions is true: - * - * 1) if @fd_write is not %NULL, when the file descriptor is writable; - * - * 2) if @fd_read is not %NULL, when the file descriptor is readable. - * - * The callbacks that are set up by qemu_set_fd_handler are level-triggered. - * If @fd_read does not read from @fd, or @fd_write does not write to @fd - * until its buffers are full, they will be called again on the next - * iteration. - * - * @fd: The file descriptor to be observed.  Under Windows it must be - * a #SOCKET. - * - * @fd_read: A level-triggered callback that is fired if @fd is readable - * at the beginning of a main loop iteration, or if it becomes readable - * during one. - * - * @fd_write: A level-triggered callback that is fired when @fd is writable - * at the beginning of a main loop iteration, or if it becomes writable - * during one. - * - * @opaque: A pointer-sized value that is passed to @fd_read and @fd_write. - */ -int qemu_set_fd_handler(int fd, -                        IOHandler *fd_read, -                        IOHandler *fd_write, -                        void *opaque); - -#ifdef CONFIG_POSIX -/** - * qemu_add_child_watch: Register a child process for reaping. - * - * Under POSIX systems, a parent process must read the exit status of - * its child processes using waitpid, or the operating system will not - * free some of the resources attached to that process. - * - * This function directs the QEMU main loop to observe a child process - * and call waitpid as soon as it exits; the watch is then removed - * automatically.  It is useful whenever QEMU forks a child process - * but will find out about its termination by other means such as a - * "broken pipe". - * - * @pid: The pid that QEMU should observe. - */ -int qemu_add_child_watch(pid_t pid); -#endif - -/** - * qemu_mutex_lock_iothread: Lock the main loop mutex. - * - * This function locks the main loop mutex.  The mutex is taken by - * qemu_init_main_loop and always taken except while waiting on - * external events (such as with select).  The mutex should be taken - * by threads other than the main loop thread when calling - * qemu_bh_new(), qemu_set_fd_handler() and basically all other - * functions documented in this file. - * - * NOTE: tools currently are single-threaded and qemu_mutex_lock_iothread - * is a no-op there. - */ -void qemu_mutex_lock_iothread(void); - -/** - * qemu_mutex_unlock_iothread: Unlock the main loop mutex. - * - * This function unlocks the main loop mutex.  The mutex is taken by - * qemu_init_main_loop and always taken except while waiting on - * external events (such as with select).  The mutex should be unlocked - * as soon as possible by threads other than the main loop thread, - * because it prevents the main loop from processing callbacks, - * including timers and bottom halves. - * - * NOTE: tools currently are single-threaded and qemu_mutex_unlock_iothread - * is a no-op there. - */ -void qemu_mutex_unlock_iothread(void); - -/* internal interfaces */ - -void qemu_fd_register(int fd); -void qemu_iohandler_fill(GArray *pollfds); -void qemu_iohandler_poll(GArray *pollfds, int rc); - -QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque); -void qemu_bh_schedule_idle(QEMUBH *bh); - -#endif diff --git a/contrib/qemu/include/qemu/module.h b/contrib/qemu/include/qemu/module.h deleted file mode 100644 index c4ccd571664..00000000000 --- a/contrib/qemu/include/qemu/module.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * QEMU Module Infrastructure - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2.  See - * the COPYING file in the top-level directory. - * - */ - -#ifndef QEMU_MODULE_H -#define QEMU_MODULE_H - -/* This should not be used directly.  Use block_init etc. instead.  */ -#define module_init(function, type)                                         \ -static void __attribute__((constructor)) do_qemu_init_ ## function(void) {  \ -    register_module_init(function, type);                                   \ -} - -typedef enum { -    MODULE_INIT_BLOCK, -    MODULE_INIT_MACHINE, -    MODULE_INIT_QAPI, -    MODULE_INIT_QOM, -    MODULE_INIT_MAX -} module_init_type; - -#define block_init(function) module_init(function, MODULE_INIT_BLOCK) -#define machine_init(function) module_init(function, MODULE_INIT_MACHINE) -#define qapi_init(function) module_init(function, MODULE_INIT_QAPI) -#define type_init(function) module_init(function, MODULE_INIT_QOM) - -void register_module_init(void (*fn)(void), module_init_type type); - -void module_call_init(module_init_type type); - -#endif diff --git a/contrib/qemu/include/qemu/notify.h b/contrib/qemu/include/qemu/notify.h deleted file mode 100644 index a3d73e4bc76..00000000000 --- a/contrib/qemu/include/qemu/notify.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Notifier lists - * - * Copyright IBM, Corp. 2010 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2.  See - * the COPYING file in the top-level directory. - * - */ - -#ifndef QEMU_NOTIFY_H -#define QEMU_NOTIFY_H - -#include "qemu/queue.h" - -typedef struct Notifier Notifier; - -struct Notifier -{ -    void (*notify)(Notifier *notifier, void *data); -    QLIST_ENTRY(Notifier) node; -}; - -typedef struct NotifierList -{ -    QLIST_HEAD(, Notifier) notifiers; -} NotifierList; - -#define NOTIFIER_LIST_INITIALIZER(head) \ -    { QLIST_HEAD_INITIALIZER((head).notifiers) } - -void notifier_list_init(NotifierList *list); - -void notifier_list_add(NotifierList *list, Notifier *notifier); - -void notifier_remove(Notifier *notifier); - -void notifier_list_notify(NotifierList *list, void *data); - -/* Same as Notifier but allows .notify() to return errors */ -typedef struct NotifierWithReturn NotifierWithReturn; - -struct NotifierWithReturn { -    /** -     * Return 0 on success (next notifier will be invoked), otherwise -     * notifier_with_return_list_notify() will stop and return the value. -     */ -    int (*notify)(NotifierWithReturn *notifier, void *data); -    QLIST_ENTRY(NotifierWithReturn) node; -}; - -typedef struct NotifierWithReturnList { -    QLIST_HEAD(, NotifierWithReturn) notifiers; -} NotifierWithReturnList; - -#define NOTIFIER_WITH_RETURN_LIST_INITIALIZER(head) \ -    { QLIST_HEAD_INITIALIZER((head).notifiers) } - -void notifier_with_return_list_init(NotifierWithReturnList *list); - -void notifier_with_return_list_add(NotifierWithReturnList *list, -                                   NotifierWithReturn *notifier); - -void notifier_with_return_remove(NotifierWithReturn *notifier); - -int notifier_with_return_list_notify(NotifierWithReturnList *list, -                                     void *data); - -#endif diff --git a/contrib/qemu/include/qemu/option.h b/contrib/qemu/include/qemu/option.h deleted file mode 100644 index a83c700323e..00000000000 --- a/contrib/qemu/include/qemu/option.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Commandline option parsing functions - * - * Copyright (c) 2003-2008 Fabrice Bellard - * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef QEMU_OPTIONS_H -#define QEMU_OPTIONS_H - -#include <stdint.h> -#include "qemu/queue.h" -#include "qapi/error.h" -#include "qapi/qmp/qdict.h" - -enum QEMUOptionParType { -    OPT_FLAG, -    OPT_NUMBER, -    OPT_SIZE, -    OPT_STRING, -}; - -typedef struct QEMUOptionParameter { -    const char *name; -    enum QEMUOptionParType type; -    union { -        uint64_t n; -        char* s; -    } value; -    const char *help; -} QEMUOptionParameter; - - -const char *get_opt_name(char *buf, int buf_size, const char *p, char delim); -const char *get_opt_value(char *buf, int buf_size, const char *p); -int get_next_param_value(char *buf, int buf_size, -                         const char *tag, const char **pstr); -int get_param_value(char *buf, int buf_size, -                    const char *tag, const char *str); - - -/* - * The following functions take a parameter list as input. This is a pointer to - * the first element of a QEMUOptionParameter array which is terminated by an - * entry with entry->name == NULL. - */ - -QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list, -    const char *name); -int set_option_parameter(QEMUOptionParameter *list, const char *name, -    const char *value); -int set_option_parameter_int(QEMUOptionParameter *list, const char *name, -    uint64_t value); -QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest, -    QEMUOptionParameter *list); -QEMUOptionParameter *parse_option_parameters(const char *param, -    QEMUOptionParameter *list, QEMUOptionParameter *dest); -void free_option_parameters(QEMUOptionParameter *list); -void print_option_parameters(QEMUOptionParameter *list); -void print_option_help(QEMUOptionParameter *list); - -/* ------------------------------------------------------------------ */ - -typedef struct QemuOpt QemuOpt; -typedef struct QemuOpts QemuOpts; -typedef struct QemuOptsList QemuOptsList; - -enum QemuOptType { -    QEMU_OPT_STRING = 0,  /* no parsing (use string as-is)                        */ -    QEMU_OPT_BOOL,        /* on/off                                               */ -    QEMU_OPT_NUMBER,      /* simple number                                        */ -    QEMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */ -}; - -typedef struct QemuOptDesc { -    const char *name; -    enum QemuOptType type; -    const char *help; -} QemuOptDesc; - -struct QemuOptsList { -    const char *name; -    const char *implied_opt_name; -    bool merge_lists;  /* Merge multiple uses of option into a single list? */ -    QTAILQ_HEAD(, QemuOpts) head; -    QemuOptDesc desc[]; -}; - -const char *qemu_opt_get(QemuOpts *opts, const char *name); -/** - * qemu_opt_has_help_opt: - * @opts: options to search for a help request - * - * Check whether the options specified by @opts include one of the - * standard strings which indicate that the user is asking for a - * list of the valid values for a command line option (as defined - * by is_help_option()). - * - * Returns: true if @opts includes 'help' or equivalent. - */ -bool qemu_opt_has_help_opt(QemuOpts *opts); -bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval); -uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval); -uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval); -int qemu_opt_set(QemuOpts *opts, const char *name, const char *value); -void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value, -                      Error **errp); -int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val); -int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val); -typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque); -int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, -                     int abort_on_failure); - -QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id); -QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, -                           int fail_if_exists, Error **errp); -QemuOpts *qemu_opts_create_nofail(QemuOptsList *list); -void qemu_opts_reset(QemuOptsList *list); -void qemu_opts_loc_restore(QemuOpts *opts); -int qemu_opts_set(QemuOptsList *list, const char *id, -                  const char *name, const char *value); -const char *qemu_opts_id(QemuOpts *opts); -void qemu_opts_del(QemuOpts *opts); -void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp); -int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname); -QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int permit_abbrev); -void qemu_opts_set_defaults(QemuOptsList *list, const char *params, -                            int permit_abbrev); -QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict, -                               Error **errp); -QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict); -void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp); - -typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque); -int qemu_opts_print(QemuOpts *opts, void *dummy); -int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, -                      int abort_on_failure); - -#endif diff --git a/contrib/qemu/include/qemu/option_int.h b/contrib/qemu/include/qemu/option_int.h deleted file mode 100644 index 8212fa4a485..00000000000 --- a/contrib/qemu/include/qemu/option_int.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Commandline option parsing functions - * - * Copyright (c) 2003-2008 Fabrice Bellard - * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef QEMU_OPTIONS_INTERNAL_H -#define QEMU_OPTIONS_INTERNAL_H - -#include "qemu/option.h" -#include "qemu/error-report.h" - -struct QemuOpt { -    const char   *name; -    const char   *str; - -    const QemuOptDesc *desc; -    union { -        bool boolean; -        uint64_t uint; -    } value; - -    QemuOpts     *opts; -    QTAILQ_ENTRY(QemuOpt) next; -}; - -struct QemuOpts { -    char *id; -    QemuOptsList *list; -    Location loc; -    QTAILQ_HEAD(QemuOptHead, QemuOpt) head; -    QTAILQ_ENTRY(QemuOpts) next; -}; - -#endif diff --git a/contrib/qemu/include/qemu/osdep.h b/contrib/qemu/include/qemu/osdep.h deleted file mode 100644 index 26136f16ecd..00000000000 --- a/contrib/qemu/include/qemu/osdep.h +++ /dev/null @@ -1,218 +0,0 @@ -#ifndef QEMU_OSDEP_H -#define QEMU_OSDEP_H - -#include "config-host.h" -#include <stdarg.h> -#include <stddef.h> -#include <stdbool.h> -#include <sys/types.h> -#ifdef __OpenBSD__ -#include <sys/signal.h> -#endif - -#ifndef _WIN32 -#include <sys/wait.h> -#else -#define WIFEXITED(x)   1 -#define WEXITSTATUS(x) (x) -#endif - -#include <sys/time.h> - -#if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10 -/* [u]int_fast*_t not in <sys/int_types.h> */ -typedef unsigned char           uint_fast8_t; -typedef unsigned int            uint_fast16_t; -typedef signed int              int_fast16_t; -#endif - -#ifndef glue -#define xglue(x, y) x ## y -#define glue(x, y) xglue(x, y) -#define stringify(s)	tostring(s) -#define tostring(s)	#s -#endif - -#ifndef likely -#if __GNUC__ < 3 -#define __builtin_expect(x, n) (x) -#endif - -#define likely(x)   __builtin_expect(!!(x), 1) -#define unlikely(x)   __builtin_expect(!!(x), 0) -#endif - -#ifndef container_of -#define container_of(ptr, type, member) ({                      \ -        const typeof(((type *) 0)->member) *__mptr = (ptr);     \ -        (type *) ((char *) __mptr - offsetof(type, member));}) -#endif - -/* Convert from a base type to a parent type, with compile time checking.  */ -#ifdef __GNUC__ -#define DO_UPCAST(type, field, dev) ( __extension__ ( { \ -    char __attribute__((unused)) offset_must_be_zero[ \ -        -offsetof(type, field)]; \ -    container_of(dev, type, field);})) -#else -#define DO_UPCAST(type, field, dev) container_of(dev, type, field) -#endif - -#define typeof_field(type, field) typeof(((type *)0)->field) -#define type_check(t1,t2) ((t1*)0 - (t2*)0) - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef ROUND_UP -#define ROUND_UP(n,d) (((n) + (d) - 1) & -(d)) -#endif - -#ifndef DIV_ROUND_UP -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -#endif - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#endif - -#ifndef always_inline -#if !((__GNUC__ < 3) || defined(__APPLE__)) -#ifdef __OPTIMIZE__ -#undef inline -#define inline __attribute__ (( always_inline )) __inline__ -#endif -#endif -#else -#undef inline -#define inline always_inline -#endif - -#define qemu_printf printf - -int qemu_daemon(int nochdir, int noclose); -void *qemu_memalign(size_t alignment, size_t size); -void *qemu_anon_ram_alloc(size_t size); -void qemu_vfree(void *ptr); -void qemu_anon_ram_free(void *ptr, size_t size); - -#define QEMU_MADV_INVALID -1 - -#if defined(CONFIG_MADVISE) - -#define QEMU_MADV_WILLNEED  MADV_WILLNEED -#define QEMU_MADV_DONTNEED  MADV_DONTNEED -#ifdef MADV_DONTFORK -#define QEMU_MADV_DONTFORK  MADV_DONTFORK -#else -#define QEMU_MADV_DONTFORK  QEMU_MADV_INVALID -#endif -#ifdef MADV_MERGEABLE -#define QEMU_MADV_MERGEABLE MADV_MERGEABLE -#else -#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID -#endif -#ifdef MADV_DONTDUMP -#define QEMU_MADV_DONTDUMP MADV_DONTDUMP -#else -#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID -#endif -#ifdef MADV_HUGEPAGE -#define QEMU_MADV_HUGEPAGE MADV_HUGEPAGE -#else -#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID -#endif - -#elif defined(CONFIG_POSIX_MADVISE) - -#define QEMU_MADV_WILLNEED  POSIX_MADV_WILLNEED -#define QEMU_MADV_DONTNEED  POSIX_MADV_DONTNEED -#define QEMU_MADV_DONTFORK  QEMU_MADV_INVALID -#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID -#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID -#define QEMU_MADV_HUGEPAGE  QEMU_MADV_INVALID - -#else /* no-op */ - -#define QEMU_MADV_WILLNEED  QEMU_MADV_INVALID -#define QEMU_MADV_DONTNEED  QEMU_MADV_INVALID -#define QEMU_MADV_DONTFORK  QEMU_MADV_INVALID -#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID -#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID -#define QEMU_MADV_HUGEPAGE  QEMU_MADV_INVALID - -#endif - -int qemu_madvise(void *addr, size_t len, int advice); - -int qemu_open(const char *name, int flags, ...); -int qemu_close(int fd); - -#if defined(__HAIKU__) && defined(__i386__) -#define FMT_pid "%ld" -#elif defined(WIN64) -#define FMT_pid "%" PRId64 -#else -#define FMT_pid "%d" -#endif - -int qemu_create_pidfile(const char *filename); -int qemu_get_thread_id(void); - -#ifndef CONFIG_IOVEC -struct iovec { -    void *iov_base; -    size_t iov_len; -}; -/* - * Use the same value as Linux for now. - */ -#define IOV_MAX 1024 - -ssize_t readv(int fd, const struct iovec *iov, int iov_cnt); -ssize_t writev(int fd, const struct iovec *iov, int iov_cnt); -#else -#include <sys/uio.h> -#endif - -#ifdef _WIN32 -static inline void qemu_timersub(const struct timeval *val1, -                                 const struct timeval *val2, -                                 struct timeval *res) -{ -    res->tv_sec = val1->tv_sec - val2->tv_sec; -    if (val1->tv_usec < val2->tv_usec) { -        res->tv_sec--; -        res->tv_usec = val1->tv_usec - val2->tv_usec + 1000 * 1000; -    } else { -        res->tv_usec = val1->tv_usec - val2->tv_usec; -    } -} -#else -#define qemu_timersub timersub -#endif - -void qemu_set_cloexec(int fd); - -void qemu_set_version(const char *); -const char *qemu_get_version(void); - -void fips_set_state(bool requested); -bool fips_get_state(void); - -/* Return a dynamically allocated pathname denoting a file or directory that is - * appropriate for storing local state. - * - * @relative_pathname need not start with a directory separator; one will be - * added automatically. - * - * The caller is responsible for releasing the value returned with g_free() - * after use. - */ -char *qemu_get_local_state_pathname(const char *relative_pathname); - -#endif diff --git a/contrib/qemu/include/qemu/queue.h b/contrib/qemu/include/qemu/queue.h deleted file mode 100644 index d433b9017ce..00000000000 --- a/contrib/qemu/include/qemu/queue.h +++ /dev/null @@ -1,414 +0,0 @@ -/*      $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */ - -/* - * QEMU version: Copy from netbsd, removed debug code, removed some of - * the implementations.  Left in singly-linked lists, lists, simple - * queues, and tail queues. - */ - -/* - * Copyright (c) 1991, 1993 - *      The Regents of the University of California.  All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - *    notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - *    notice, this list of conditions and the following disclaimer in the - *    documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - *    may be used to endorse or promote products derived from this software - *    without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *      @(#)queue.h     8.5 (Berkeley) 8/20/94 - */ - -#ifndef QEMU_SYS_QUEUE_H_ -#define QEMU_SYS_QUEUE_H_ - -/* - * This file defines four types of data structures: singly-linked lists, - * lists, simple queues, and tail queues. - * - * A singly-linked list is headed by a single forward pointer. The - * elements are singly linked for minimum space and pointer manipulation - * overhead at the expense of O(n) removal for arbitrary elements. New - * elements can be added to the list after an existing element or at the - * head of the list.  Elements being removed from the head of the list - * should use the explicit macro for this purpose for optimum - * efficiency. A singly-linked list may only be traversed in the forward - * direction.  Singly-linked lists are ideal for applications with large - * datasets and few or no removals or for implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -#include "qemu/atomic.h" /* for smp_wmb() */ - -/* - * List definitions. - */ -#define QLIST_HEAD(name, type)                                          \ -struct name {                                                           \ -        struct type *lh_first;  /* first element */                     \ -} - -#define QLIST_HEAD_INITIALIZER(head)                                    \ -        { NULL } - -#define QLIST_ENTRY(type)                                               \ -struct {                                                                \ -        struct type *le_next;   /* next element */                      \ -        struct type **le_prev;  /* address of previous next element */  \ -} - -/* - * List functions. - */ -#define QLIST_INIT(head) do {                                           \ -        (head)->lh_first = NULL;                                        \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_AFTER(listelm, elm, field) do {                    \ -        if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \ -                (listelm)->field.le_next->field.le_prev =               \ -                    &(elm)->field.le_next;                              \ -        (listelm)->field.le_next = (elm);                               \ -        (elm)->field.le_prev = &(listelm)->field.le_next;               \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_BEFORE(listelm, elm, field) do {                   \ -        (elm)->field.le_prev = (listelm)->field.le_prev;                \ -        (elm)->field.le_next = (listelm);                               \ -        *(listelm)->field.le_prev = (elm);                              \ -        (listelm)->field.le_prev = &(elm)->field.le_next;               \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_HEAD(head, elm, field) do {                        \ -        if (((elm)->field.le_next = (head)->lh_first) != NULL)          \ -                (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ -        (head)->lh_first = (elm);                                       \ -        (elm)->field.le_prev = &(head)->lh_first;                       \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_HEAD_RCU(head, elm, field) do {                    \ -        (elm)->field.le_prev = &(head)->lh_first;                       \ -        (elm)->field.le_next = (head)->lh_first;                        \ -        smp_wmb(); /* fill elm before linking it */                     \ -        if ((head)->lh_first != NULL)  {                                \ -            (head)->lh_first->field.le_prev = &(elm)->field.le_next;    \ -        }                                                               \ -        (head)->lh_first = (elm);                                       \ -        smp_wmb();                                                      \ -} while (/* CONSTCOND*/0) - -#define QLIST_REMOVE(elm, field) do {                                   \ -        if ((elm)->field.le_next != NULL)                               \ -                (elm)->field.le_next->field.le_prev =                   \ -                    (elm)->field.le_prev;                               \ -        *(elm)->field.le_prev = (elm)->field.le_next;                   \ -} while (/*CONSTCOND*/0) - -#define QLIST_FOREACH(var, head, field)                                 \ -        for ((var) = ((head)->lh_first);                                \ -                (var);                                                  \ -                (var) = ((var)->field.le_next)) - -#define QLIST_FOREACH_SAFE(var, head, field, next_var)                  \ -        for ((var) = ((head)->lh_first);                                \ -                (var) && ((next_var) = ((var)->field.le_next), 1);      \ -                (var) = (next_var)) - -/* - * List access methods. - */ -#define QLIST_EMPTY(head)                ((head)->lh_first == NULL) -#define QLIST_FIRST(head)                ((head)->lh_first) -#define QLIST_NEXT(elm, field)           ((elm)->field.le_next) - - -/* - * Singly-linked List definitions. - */ -#define QSLIST_HEAD(name, type)                                          \ -struct name {                                                           \ -        struct type *slh_first; /* first element */                     \ -} - -#define QSLIST_HEAD_INITIALIZER(head)                                    \ -        { NULL } - -#define QSLIST_ENTRY(type)                                               \ -struct {                                                                \ -        struct type *sle_next;  /* next element */                      \ -} - -/* - * Singly-linked List functions. - */ -#define QSLIST_INIT(head) do {                                           \ -        (head)->slh_first = NULL;                                       \ -} while (/*CONSTCOND*/0) - -#define QSLIST_INSERT_AFTER(slistelm, elm, field) do {                   \ -        (elm)->field.sle_next = (slistelm)->field.sle_next;             \ -        (slistelm)->field.sle_next = (elm);                             \ -} while (/*CONSTCOND*/0) - -#define QSLIST_INSERT_HEAD(head, elm, field) do {                        \ -        (elm)->field.sle_next = (head)->slh_first;                      \ -        (head)->slh_first = (elm);                                      \ -} while (/*CONSTCOND*/0) - -#define QSLIST_REMOVE_HEAD(head, field) do {                             \ -        (head)->slh_first = (head)->slh_first->field.sle_next;          \ -} while (/*CONSTCOND*/0) - -#define QSLIST_REMOVE_AFTER(slistelm, field) do {                        \ -        (slistelm)->field.sle_next =                                    \ -            QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field);           \ -} while (/*CONSTCOND*/0) - -#define QSLIST_FOREACH(var, head, field)                                 \ -        for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) - -#define QSLIST_FOREACH_SAFE(var, head, field, tvar)                      \ -        for ((var) = QSLIST_FIRST((head));                               \ -            (var) && ((tvar) = QSLIST_NEXT((var), field), 1);            \ -            (var) = (tvar)) - -/* - * Singly-linked List access methods. - */ -#define QSLIST_EMPTY(head)       ((head)->slh_first == NULL) -#define QSLIST_FIRST(head)       ((head)->slh_first) -#define QSLIST_NEXT(elm, field)  ((elm)->field.sle_next) - - -/* - * Simple queue definitions. - */ -#define QSIMPLEQ_HEAD(name, type)                                       \ -struct name {                                                           \ -    struct type *sqh_first;    /* first element */                      \ -    struct type **sqh_last;    /* addr of last next element */          \ -} - -#define QSIMPLEQ_HEAD_INITIALIZER(head)                                 \ -    { NULL, &(head).sqh_first } - -#define QSIMPLEQ_ENTRY(type)                                            \ -struct {                                                                \ -    struct type *sqe_next;    /* next element */                        \ -} - -/* - * Simple queue functions. - */ -#define QSIMPLEQ_INIT(head) do {                                        \ -    (head)->sqh_first = NULL;                                           \ -    (head)->sqh_last = &(head)->sqh_first;                              \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do {                     \ -    if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)            \ -        (head)->sqh_last = &(elm)->field.sqe_next;                      \ -    (head)->sqh_first = (elm);                                          \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do {                     \ -    (elm)->field.sqe_next = NULL;                                       \ -    *(head)->sqh_last = (elm);                                          \ -    (head)->sqh_last = &(elm)->field.sqe_next;                          \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {           \ -    if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)    \ -        (head)->sqh_last = &(elm)->field.sqe_next;                      \ -    (listelm)->field.sqe_next = (elm);                                  \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_REMOVE_HEAD(head, field) do {                          \ -    if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\ -        (head)->sqh_last = &(head)->sqh_first;                          \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_REMOVE(head, elm, type, field) do {                    \ -    if ((head)->sqh_first == (elm)) {                                   \ -        QSIMPLEQ_REMOVE_HEAD((head), field);                            \ -    } else {                                                            \ -        struct type *curelm = (head)->sqh_first;                        \ -        while (curelm->field.sqe_next != (elm))                         \ -            curelm = curelm->field.sqe_next;                            \ -        if ((curelm->field.sqe_next =                                   \ -            curelm->field.sqe_next->field.sqe_next) == NULL)            \ -                (head)->sqh_last = &(curelm)->field.sqe_next;           \ -    }                                                                   \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_FOREACH(var, head, field)                              \ -    for ((var) = ((head)->sqh_first);                                   \ -        (var);                                                          \ -        (var) = ((var)->field.sqe_next)) - -#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next)                   \ -    for ((var) = ((head)->sqh_first);                                   \ -        (var) && ((next = ((var)->field.sqe_next)), 1);                 \ -        (var) = (next)) - -#define QSIMPLEQ_CONCAT(head1, head2) do {                              \ -    if (!QSIMPLEQ_EMPTY((head2))) {                                     \ -        *(head1)->sqh_last = (head2)->sqh_first;                        \ -        (head1)->sqh_last = (head2)->sqh_last;                          \ -        QSIMPLEQ_INIT((head2));                                         \ -    }                                                                   \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_LAST(head, type, field)                                \ -    (QSIMPLEQ_EMPTY((head)) ?                                           \ -        NULL :                                                          \ -            ((struct type *)(void *)                                    \ -        ((char *)((head)->sqh_last) - offsetof(struct type, field)))) - -/* - * Simple queue access methods. - */ -#define QSIMPLEQ_EMPTY(head)        ((head)->sqh_first == NULL) -#define QSIMPLEQ_FIRST(head)        ((head)->sqh_first) -#define QSIMPLEQ_NEXT(elm, field)   ((elm)->field.sqe_next) - - -/* - * Tail queue definitions. - */ -#define Q_TAILQ_HEAD(name, type, qual)                                  \ -struct name {                                                           \ -        qual type *tqh_first;           /* first element */             \ -        qual type *qual *tqh_last;      /* addr of last next element */ \ -} -#define QTAILQ_HEAD(name, type)  Q_TAILQ_HEAD(name, struct type,) - -#define QTAILQ_HEAD_INITIALIZER(head)                                   \ -        { NULL, &(head).tqh_first } - -#define Q_TAILQ_ENTRY(type, qual)                                       \ -struct {                                                                \ -        qual type *tqe_next;            /* next element */              \ -        qual type *qual *tqe_prev;      /* address of previous next element */\ -} -#define QTAILQ_ENTRY(type)       Q_TAILQ_ENTRY(struct type,) - -/* - * Tail queue functions. - */ -#define QTAILQ_INIT(head) do {                                          \ -        (head)->tqh_first = NULL;                                       \ -        (head)->tqh_last = &(head)->tqh_first;                          \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_HEAD(head, elm, field) do {                       \ -        if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \ -                (head)->tqh_first->field.tqe_prev =                     \ -                    &(elm)->field.tqe_next;                             \ -        else                                                            \ -                (head)->tqh_last = &(elm)->field.tqe_next;              \ -        (head)->tqh_first = (elm);                                      \ -        (elm)->field.tqe_prev = &(head)->tqh_first;                     \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_TAIL(head, elm, field) do {                       \ -        (elm)->field.tqe_next = NULL;                                   \ -        (elm)->field.tqe_prev = (head)->tqh_last;                       \ -        *(head)->tqh_last = (elm);                                      \ -        (head)->tqh_last = &(elm)->field.tqe_next;                      \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do {             \ -        if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ -                (elm)->field.tqe_next->field.tqe_prev =                 \ -                    &(elm)->field.tqe_next;                             \ -        else                                                            \ -                (head)->tqh_last = &(elm)->field.tqe_next;              \ -        (listelm)->field.tqe_next = (elm);                              \ -        (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do {                  \ -        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \ -        (elm)->field.tqe_next = (listelm);                              \ -        *(listelm)->field.tqe_prev = (elm);                             \ -        (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_REMOVE(head, elm, field) do {                            \ -        if (((elm)->field.tqe_next) != NULL)                            \ -                (elm)->field.tqe_next->field.tqe_prev =                 \ -                    (elm)->field.tqe_prev;                              \ -        else                                                            \ -                (head)->tqh_last = (elm)->field.tqe_prev;               \ -        *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_FOREACH(var, head, field)                                \ -        for ((var) = ((head)->tqh_first);                               \ -                (var);                                                  \ -                (var) = ((var)->field.tqe_next)) - -#define QTAILQ_FOREACH_SAFE(var, head, field, next_var)                 \ -        for ((var) = ((head)->tqh_first);                               \ -                (var) && ((next_var) = ((var)->field.tqe_next), 1);     \ -                (var) = (next_var)) - -#define QTAILQ_FOREACH_REVERSE(var, head, headname, field)              \ -        for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));    \ -                (var);                                                  \ -                (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) - -/* - * Tail queue access methods. - */ -#define QTAILQ_EMPTY(head)               ((head)->tqh_first == NULL) -#define QTAILQ_FIRST(head)               ((head)->tqh_first) -#define QTAILQ_NEXT(elm, field)          ((elm)->field.tqe_next) - -#define QTAILQ_LAST(head, headname) \ -        (*(((struct headname *)((head)->tqh_last))->tqh_last)) -#define QTAILQ_PREV(elm, headname, field) \ -        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#endif  /* !QEMU_SYS_QUEUE_H_ */ diff --git a/contrib/qemu/include/qemu/sockets.h b/contrib/qemu/include/qemu/sockets.h deleted file mode 100644 index c5174d76a70..00000000000 --- a/contrib/qemu/include/qemu/sockets.h +++ /dev/null @@ -1,83 +0,0 @@ -/* headers to use the BSD sockets */ -#ifndef QEMU_SOCKET_H -#define QEMU_SOCKET_H - -#ifdef _WIN32 -#include <windows.h> -#include <winsock2.h> -#include <ws2tcpip.h> - -#define socket_error() WSAGetLastError() - -int inet_aton(const char *cp, struct in_addr *ia); - -#else - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <sys/un.h> - -#define socket_error() errno -#define closesocket(s) close(s) - -#endif /* !_WIN32 */ - -#include "qemu/option.h" -#include "qapi/error.h" -#include "qapi/qmp/qerror.h" - -extern QemuOptsList socket_optslist; - -/* misc helpers */ -int qemu_socket(int domain, int type, int protocol); -int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -int socket_set_cork(int fd, int v); -int socket_set_nodelay(int fd); -void qemu_set_block(int fd); -void qemu_set_nonblock(int fd); -int send_all(int fd, const void *buf, int len1); -int recv_all(int fd, void *buf, int len1, bool single_read); - -/* callback function for nonblocking connect - * valid fd on success, negative error code on failure - */ -typedef void NonBlockingConnectHandler(int fd, void *opaque); - -InetSocketAddress *inet_parse(const char *str, Error **errp); -int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp); -int inet_listen(const char *str, char *ostr, int olen, -                int socktype, int port_offset, Error **errp); -int inet_connect_opts(QemuOpts *opts, Error **errp, -                      NonBlockingConnectHandler *callback, void *opaque); -int inet_connect(const char *str, Error **errp); -int inet_nonblocking_connect(const char *str, -                             NonBlockingConnectHandler *callback, -                             void *opaque, Error **errp); - -int inet_dgram_opts(QemuOpts *opts, Error **errp); -const char *inet_strfamily(int family); - -int unix_listen_opts(QemuOpts *opts, Error **errp); -int unix_listen(const char *path, char *ostr, int olen, Error **errp); -int unix_connect_opts(QemuOpts *opts, Error **errp, -                      NonBlockingConnectHandler *callback, void *opaque); -int unix_connect(const char *path, Error **errp); -int unix_nonblocking_connect(const char *str, -                             NonBlockingConnectHandler *callback, -                             void *opaque, Error **errp); - -SocketAddress *socket_parse(const char *str, Error **errp); -int socket_connect(SocketAddress *addr, Error **errp, -                   NonBlockingConnectHandler *callback, void *opaque); -int socket_listen(SocketAddress *addr, Error **errp); -int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp); - -/* Old, ipv4 only bits.  Don't use for new code. */ -int parse_host_port(struct sockaddr_in *saddr, const char *str); -int socket_init(void); - -#endif /* QEMU_SOCKET_H */ diff --git a/contrib/qemu/include/qemu/thread-posix.h b/contrib/qemu/include/qemu/thread-posix.h deleted file mode 100644 index 0f30dccb53c..00000000000 --- a/contrib/qemu/include/qemu/thread-posix.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __QEMU_THREAD_POSIX_H -#define __QEMU_THREAD_POSIX_H 1 -#include "pthread.h" -#include <semaphore.h> - -struct QemuMutex { -    pthread_mutex_t lock; -}; - -struct QemuCond { -    pthread_cond_t cond; -}; - -struct QemuSemaphore { -#if defined(__APPLE__) || defined(__NetBSD__) -    pthread_mutex_t lock; -    pthread_cond_t cond; -    int count; -#else -    sem_t sem; -#endif -}; - -struct QemuThread { -    pthread_t thread; -}; - -#endif diff --git a/contrib/qemu/include/qemu/thread.h b/contrib/qemu/include/qemu/thread.h deleted file mode 100644 index c02404b9fbf..00000000000 --- a/contrib/qemu/include/qemu/thread.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __QEMU_THREAD_H -#define __QEMU_THREAD_H 1 - -#include <inttypes.h> -#include <stdbool.h> - -typedef struct QemuMutex QemuMutex; -typedef struct QemuCond QemuCond; -typedef struct QemuSemaphore QemuSemaphore; -typedef struct QemuThread QemuThread; - -#ifdef _WIN32 -#include "qemu/thread-win32.h" -#else -#include "qemu/thread-posix.h" -#endif - -#define QEMU_THREAD_JOINABLE 0 -#define QEMU_THREAD_DETACHED 1 - -void qemu_mutex_init(QemuMutex *mutex); -void qemu_mutex_destroy(QemuMutex *mutex); -void qemu_mutex_lock(QemuMutex *mutex); -int qemu_mutex_trylock(QemuMutex *mutex); -void qemu_mutex_unlock(QemuMutex *mutex); - -#define rcu_read_lock() do { } while (0) -#define rcu_read_unlock() do { } while (0) - -void qemu_cond_init(QemuCond *cond); -void qemu_cond_destroy(QemuCond *cond); - -/* - * IMPORTANT: The implementation does not guarantee that pthread_cond_signal - * and pthread_cond_broadcast can be called except while the same mutex is - * held as in the corresponding pthread_cond_wait calls! - */ -void qemu_cond_signal(QemuCond *cond); -void qemu_cond_broadcast(QemuCond *cond); -void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex); - -void qemu_sem_init(QemuSemaphore *sem, int init); -void qemu_sem_post(QemuSemaphore *sem); -void qemu_sem_wait(QemuSemaphore *sem); -int qemu_sem_timedwait(QemuSemaphore *sem, int ms); -void qemu_sem_destroy(QemuSemaphore *sem); - -void qemu_thread_create(QemuThread *thread, -                        void *(*start_routine)(void *), -                        void *arg, int mode); -void *qemu_thread_join(QemuThread *thread); -void qemu_thread_get_self(QemuThread *thread); -bool qemu_thread_is_self(QemuThread *thread); -void qemu_thread_exit(void *retval); - -#endif diff --git a/contrib/qemu/include/qemu/timer.h b/contrib/qemu/include/qemu/timer.h deleted file mode 100644 index 9dd206ce7f4..00000000000 --- a/contrib/qemu/include/qemu/timer.h +++ /dev/null @@ -1,305 +0,0 @@ -#ifndef QEMU_TIMER_H -#define QEMU_TIMER_H - -#include "qemu-common.h" -#include "qemu/main-loop.h" -#include "qemu/notify.h" - -/* timers */ - -#define SCALE_MS 1000000 -#define SCALE_US 1000 -#define SCALE_NS 1 - -typedef struct QEMUClock QEMUClock; -typedef void QEMUTimerCB(void *opaque); - -/* The real time clock should be used only for stuff which does not -   change the virtual machine state, as it is run even if the virtual -   machine is stopped. The real time clock has a frequency of 1000 -   Hz. */ -extern QEMUClock *rt_clock; - -/* The virtual clock is only run during the emulation. It is stopped -   when the virtual machine is stopped. Virtual timers use a high -   precision clock, usually cpu cycles (use ticks_per_sec). */ -extern QEMUClock *vm_clock; - -/* The host clock should be use for device models that emulate accurate -   real time sources. It will continue to run when the virtual machine -   is suspended, and it will reflect system time changes the host may -   undergo (e.g. due to NTP). The host clock has the same precision as -   the virtual clock. */ -extern QEMUClock *host_clock; - -int64_t qemu_get_clock_ns(QEMUClock *clock); -int64_t qemu_clock_has_timers(QEMUClock *clock); -int64_t qemu_clock_expired(QEMUClock *clock); -int64_t qemu_clock_deadline(QEMUClock *clock); -void qemu_clock_enable(QEMUClock *clock, bool enabled); -void qemu_clock_warp(QEMUClock *clock); - -void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier); -void qemu_unregister_clock_reset_notifier(QEMUClock *clock, -                                          Notifier *notifier); - -QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale, -                          QEMUTimerCB *cb, void *opaque); -void qemu_free_timer(QEMUTimer *ts); -void qemu_del_timer(QEMUTimer *ts); -void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time); -void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time); -bool qemu_timer_pending(QEMUTimer *ts); -bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time); -uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts); - -void qemu_run_timers(QEMUClock *clock); -void qemu_run_all_timers(void); -void configure_alarms(char const *opt); -void init_clocks(void); -int init_timer_alarm(void); - -int64_t cpu_get_ticks(void); -void cpu_enable_ticks(void); -void cpu_disable_ticks(void); - -static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb, -                                           void *opaque) -{ -    return qemu_new_timer(clock, SCALE_NS, cb, opaque); -} - -static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock, QEMUTimerCB *cb, -                                           void *opaque) -{ -    return qemu_new_timer(clock, SCALE_MS, cb, opaque); -} - -static inline int64_t qemu_get_clock_ms(QEMUClock *clock) -{ -    return qemu_get_clock_ns(clock) / SCALE_MS; -} - -static inline int64_t get_ticks_per_sec(void) -{ -    return 1000000000LL; -} - -/* real time host monotonic timer */ -static inline int64_t get_clock_realtime(void) -{ -    struct timeval tv; - -    gettimeofday(&tv, NULL); -    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000); -} - -/* Warning: don't insert tracepoints into these functions, they are -   also used by simpletrace backend and tracepoints would cause -   an infinite recursion! */ -#ifdef _WIN32 -extern int64_t clock_freq; - -static inline int64_t get_clock(void) -{ -    LARGE_INTEGER ti; -    QueryPerformanceCounter(&ti); -    return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq); -} - -#else - -extern int use_rt_clock; - -static inline int64_t get_clock(void) -{ -#ifdef CLOCK_MONOTONIC -    if (use_rt_clock) { -        struct timespec ts; -        clock_gettime(CLOCK_MONOTONIC, &ts); -        return ts.tv_sec * 1000000000LL + ts.tv_nsec; -    } else -#endif -    { -        /* XXX: using gettimeofday leads to problems if the date -           changes, so it should be avoided. */ -        return get_clock_realtime(); -    } -} -#endif - -void qemu_get_timer(QEMUFile *f, QEMUTimer *ts); -void qemu_put_timer(QEMUFile *f, QEMUTimer *ts); - -/* icount */ -int64_t cpu_get_icount(void); -int64_t cpu_get_clock(void); - -/*******************************************/ -/* host CPU ticks (if available) */ - -#if defined(_ARCH_PPC) - -static inline int64_t cpu_get_real_ticks(void) -{ -    int64_t retval; -#ifdef _ARCH_PPC64 -    /* This reads timebase in one 64bit go and includes Cell workaround from: -       http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html -    */ -    __asm__ __volatile__ ("mftb    %0\n\t" -                          "cmpwi   %0,0\n\t" -                          "beq-    $-8" -                          : "=r" (retval)); -#else -    /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */ -    unsigned long junk; -    __asm__ __volatile__ ("mfspr   %1,269\n\t"  /* mftbu */ -                          "mfspr   %L0,268\n\t" /* mftb */ -                          "mfspr   %0,269\n\t"  /* mftbu */ -                          "cmpw    %0,%1\n\t" -                          "bne     $-16" -                          : "=r" (retval), "=r" (junk)); -#endif -    return retval; -} - -#elif defined(__i386__) - -static inline int64_t cpu_get_real_ticks(void) -{ -    int64_t val; -    asm volatile ("rdtsc" : "=A" (val)); -    return val; -} - -#elif defined(__x86_64__) - -static inline int64_t cpu_get_real_ticks(void) -{ -    uint32_t low,high; -    int64_t val; -    asm volatile("rdtsc" : "=a" (low), "=d" (high)); -    val = high; -    val <<= 32; -    val |= low; -    return val; -} - -#elif defined(__hppa__) - -static inline int64_t cpu_get_real_ticks(void) -{ -    int val; -    asm volatile ("mfctl %%cr16, %0" : "=r"(val)); -    return val; -} - -#elif defined(__ia64) - -static inline int64_t cpu_get_real_ticks(void) -{ -    int64_t val; -    asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory"); -    return val; -} - -#elif defined(__s390__) - -static inline int64_t cpu_get_real_ticks(void) -{ -    int64_t val; -    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc"); -    return val; -} - -#elif defined(__sparc__) - -static inline int64_t cpu_get_real_ticks (void) -{ -#if defined(_LP64) -    uint64_t        rval; -    asm volatile("rd %%tick,%0" : "=r"(rval)); -    return rval; -#else -    /* We need an %o or %g register for this.  For recent enough gcc -       there is an "h" constraint for that.  Don't bother with that.  */ -    union { -        uint64_t i64; -        struct { -            uint32_t high; -            uint32_t low; -        }       i32; -    } rval; -    asm volatile("rd %%tick,%%g1; srlx %%g1,32,%0; mov %%g1,%1" -                 : "=r"(rval.i32.high), "=r"(rval.i32.low) : : "g1"); -    return rval.i64; -#endif -} - -#elif defined(__mips__) && \ -    ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__)) -/* - * binutils wants to use rdhwr only on mips32r2 - * but as linux kernel emulate it, it's fine - * to use it. - * - */ -#define MIPS_RDHWR(rd, value) {                         \ -        __asm__ __volatile__ (".set   push\n\t"         \ -                              ".set mips32r2\n\t"       \ -                              "rdhwr  %0, "rd"\n\t"     \ -                              ".set   pop"              \ -                              : "=r" (value));          \ -    } - -static inline int64_t cpu_get_real_ticks(void) -{ -    /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */ -    uint32_t count; -    static uint32_t cyc_per_count = 0; - -    if (!cyc_per_count) { -        MIPS_RDHWR("$3", cyc_per_count); -    } - -    MIPS_RDHWR("$2", count); -    return (int64_t)(count * cyc_per_count); -} - -#elif defined(__alpha__) - -static inline int64_t cpu_get_real_ticks(void) -{ -    uint64_t cc; -    uint32_t cur, ofs; - -    asm volatile("rpcc %0" : "=r"(cc)); -    cur = cc; -    ofs = cc >> 32; -    return cur - ofs; -} - -#else -/* The host CPU doesn't have an easily accessible cycle counter. -   Just return a monotonically increasing value.  This will be -   totally wrong, but hopefully better than nothing.  */ -static inline int64_t cpu_get_real_ticks (void) -{ -    static int64_t ticks = 0; -    return ticks++; -} -#endif - -#ifdef CONFIG_PROFILER -static inline int64_t profile_getclock(void) -{ -    return cpu_get_real_ticks(); -} - -extern int64_t qemu_time, qemu_time_start; -extern int64_t tlb_flush_time; -extern int64_t dev_time; -#endif - -#endif diff --git a/contrib/qemu/include/qemu/typedefs.h b/contrib/qemu/include/qemu/typedefs.h deleted file mode 100644 index ac9f8d41a35..00000000000 --- a/contrib/qemu/include/qemu/typedefs.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef QEMU_TYPEDEFS_H -#define QEMU_TYPEDEFS_H - -/* A load of opaque types so that device init declarations don't have to -   pull in all the real definitions.  */ -typedef struct QEMUTimer QEMUTimer; -typedef struct QEMUFile QEMUFile; -typedef struct QEMUBH QEMUBH; - -struct Monitor; -typedef struct Monitor Monitor; -typedef struct MigrationParams MigrationParams; - -typedef struct Property Property; -typedef struct PropertyInfo PropertyInfo; -typedef struct CompatProperty CompatProperty; -typedef struct DeviceState DeviceState; -typedef struct BusState BusState; -typedef struct BusClass BusClass; - -typedef struct AddressSpace AddressSpace; -typedef struct MemoryRegion MemoryRegion; -typedef struct MemoryRegionSection MemoryRegionSection; - -typedef struct MemoryMappingList MemoryMappingList; - -typedef struct NICInfo NICInfo; -typedef struct HCIInfo HCIInfo; -typedef struct AudioState AudioState; -typedef struct BlockDriverState BlockDriverState; -typedef struct DriveInfo DriveInfo; -typedef struct DisplayState DisplayState; -typedef struct DisplayChangeListener DisplayChangeListener; -typedef struct DisplaySurface DisplaySurface; -typedef struct PixelFormat PixelFormat; -typedef struct QemuConsole QemuConsole; -typedef struct CharDriverState CharDriverState; -typedef struct MACAddr MACAddr; -typedef struct NetClientState NetClientState; -typedef struct i2c_bus i2c_bus; -typedef struct ISABus ISABus; -typedef struct ISADevice ISADevice; -typedef struct SMBusDevice SMBusDevice; -typedef struct PCIHostState PCIHostState; -typedef struct PCIExpressHost PCIExpressHost; -typedef struct PCIBus PCIBus; -typedef struct PCIDevice PCIDevice; -typedef struct PCIExpressDevice PCIExpressDevice; -typedef struct PCIBridge PCIBridge; -typedef struct PCIEAERMsg PCIEAERMsg; -typedef struct PCIEAERLog PCIEAERLog; -typedef struct PCIEAERErr PCIEAERErr; -typedef struct PCIEPort PCIEPort; -typedef struct PCIESlot PCIESlot; -typedef struct MSIMessage MSIMessage; -typedef struct SerialState SerialState; -typedef struct PCMCIACardState PCMCIACardState; -typedef struct MouseTransformInfo MouseTransformInfo; -typedef struct uWireSlave uWireSlave; -typedef struct I2SCodec I2SCodec; -typedef struct SSIBus SSIBus; -typedef struct EventNotifier EventNotifier; -typedef struct VirtIODevice VirtIODevice; -typedef struct QEMUSGList QEMUSGList; -typedef struct SHPCDevice SHPCDevice; -typedef struct FWCfgState FWCfgState; -typedef struct PcGuestInfo PcGuestInfo; - -#endif /* QEMU_TYPEDEFS_H */ diff --git a/contrib/qemu/include/sysemu/os-posix.h b/contrib/qemu/include/sysemu/os-posix.h deleted file mode 100644 index ac4a80e6d8c..00000000000 --- a/contrib/qemu/include/sysemu/os-posix.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * posix specific declarations - * - * Copyright (c) 2003-2008 Fabrice Bellard - * Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef QEMU_OS_POSIX_H -#define QEMU_OS_POSIX_H - -void os_set_line_buffering(void); -void os_set_proc_name(const char *s); -void os_setup_signal_handling(void); -void os_daemonize(void); -void os_setup_post(void); -int os_mlock(void); - -typedef struct timeval qemu_timeval; -#define qemu_gettimeofday(tp) gettimeofday(tp, NULL) - -#if !defined(CONFIG_UTIMENSAT) || defined(__FreeBSD__) || defined(__APPLE__) -#ifndef UTIME_NOW -# define UTIME_NOW     ((1l << 30) - 1l) -#endif -#ifndef UTIME_OMIT -# define UTIME_OMIT    ((1l << 30) - 2l) -#endif -#endif -typedef struct timespec qemu_timespec; -int qemu_utimens(const char *path, const qemu_timespec *times); - -bool is_daemonized(void); - -#endif diff --git a/contrib/qemu/include/sysemu/sysemu.h b/contrib/qemu/include/sysemu/sysemu.h deleted file mode 100644 index 3caeb66eb2f..00000000000 --- a/contrib/qemu/include/sysemu/sysemu.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef SYSEMU_H -#define SYSEMU_H -/* Misc. things related to the system emulator.  */ - -#include "qemu/typedefs.h" -#include "qemu/option.h" -#include "qemu/queue.h" -#include "qemu/timer.h" -#include "qapi-types.h" -#include "qemu/notify.h" -#include "qemu/main-loop.h" - -/* vl.c */ - -extern const char *bios_name; - -extern const char *qemu_name; -extern uint8_t qemu_uuid[]; -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" - -bool runstate_check(RunState state); -void runstate_set(RunState new_state); -int runstate_is_running(void); -bool runstate_needs_reset(void); -typedef struct vm_change_state_entry VMChangeStateEntry; -typedef void VMChangeStateHandler(void *opaque, int running, RunState state); - -VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb, -                                                     void *opaque); -void qemu_del_vm_change_state_handler(VMChangeStateEntry *e); -void vm_state_notify(int running, RunState state); - -#define VMRESET_SILENT   false -#define VMRESET_REPORT   true - -void vm_start(void); -int vm_stop(RunState state); -int vm_stop_force_state(RunState state); - -typedef enum WakeupReason { -    QEMU_WAKEUP_REASON_OTHER = 0, -    QEMU_WAKEUP_REASON_RTC, -    QEMU_WAKEUP_REASON_PMTIMER, -} WakeupReason; - -void qemu_system_reset_request(void); -void qemu_system_suspend_request(void); -void qemu_register_suspend_notifier(Notifier *notifier); -void qemu_system_wakeup_request(WakeupReason reason); -void qemu_system_wakeup_enable(WakeupReason reason, bool enabled); -void qemu_register_wakeup_notifier(Notifier *notifier); -void qemu_system_shutdown_request(void); -void qemu_system_powerdown_request(void); -void qemu_register_powerdown_notifier(Notifier *notifier); -void qemu_system_debug_request(void); -void qemu_system_vmstop_request(RunState reason); -int qemu_shutdown_requested_get(void); -int qemu_reset_requested_get(void); -void qemu_system_killed(int signal, pid_t pid); -void qemu_devices_reset(void); -void qemu_system_reset(bool report); - -void qemu_add_exit_notifier(Notifier *notify); -void qemu_remove_exit_notifier(Notifier *notify); - -void qemu_add_machine_init_done_notifier(Notifier *notify); - -void do_savevm(Monitor *mon, const QDict *qdict); -int load_vmstate(const char *name); -void do_delvm(Monitor *mon, const QDict *qdict); -void do_info_snapshots(Monitor *mon, const QDict *qdict); - -void qemu_announce_self(void); - -bool qemu_savevm_state_blocked(Error **errp); -void qemu_savevm_state_begin(QEMUFile *f, -                             const MigrationParams *params); -int qemu_savevm_state_iterate(QEMUFile *f); -void qemu_savevm_state_complete(QEMUFile *f); -void qemu_savevm_state_cancel(void); -uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size); -int qemu_loadvm_state(QEMUFile *f); - -/* SLIRP */ -void do_info_slirp(Monitor *mon); - -typedef enum DisplayType -{ -    DT_DEFAULT, -    DT_CURSES, -    DT_SDL, -    DT_GTK, -    DT_NOGRAPHIC, -    DT_NONE, -} DisplayType; - -extern int autostart; - -typedef enum { -    VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL, -} VGAInterfaceType; - -extern int vga_interface_type; -#define xenfb_enabled (vga_interface_type == VGA_XENFB) -#define qxl_enabled (vga_interface_type == VGA_QXL) - -extern int graphic_width; -extern int graphic_height; -extern int graphic_depth; -extern DisplayType display_type; -extern const char *keyboard_layout; -extern int win2k_install_hack; -extern int alt_grab; -extern int ctrl_grab; -extern int smp_cpus; -extern int max_cpus; -extern int cursor_hide; -extern int graphic_rotate; -extern int no_quit; -extern int no_shutdown; -extern int semihosting_enabled; -extern int old_param; -extern int boot_menu; -extern uint8_t *boot_splash_filedata; -extern size_t boot_splash_filedata_size; -extern uint8_t qemu_extra_params_fw[2]; -extern QEMUClock *rtc_clock; - -#define MAX_NODES 64 -#define MAX_CPUMASK_BITS 255 -extern int nb_numa_nodes; -extern uint64_t node_mem[MAX_NODES]; -extern unsigned long *node_cpumask[MAX_NODES]; - -#define MAX_OPTION_ROMS 16 -typedef struct QEMUOptionRom { -    const char *name; -    int32_t bootindex; -} QEMUOptionRom; -extern QEMUOptionRom option_rom[MAX_OPTION_ROMS]; -extern int nb_option_roms; - -#define MAX_PROM_ENVS 128 -extern const char *prom_envs[MAX_PROM_ENVS]; -extern unsigned int nb_prom_envs; - -/* pci-hotplug */ -void pci_device_hot_add(Monitor *mon, const QDict *qdict); -int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo); -void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict); - -/* generic hotplug */ -void drive_hot_add(Monitor *mon, const QDict *qdict); - -/* CPU hotplug */ -void qemu_register_cpu_added_notifier(Notifier *notifier); - -/* pcie aer error injection */ -void pcie_aer_inject_error_print(Monitor *mon, const QObject *data); -int do_pcie_aer_inject_error(Monitor *mon, -                             const QDict *qdict, QObject **ret_data); - -/* serial ports */ - -#define MAX_SERIAL_PORTS 4 - -extern CharDriverState *serial_hds[MAX_SERIAL_PORTS]; - -/* parallel ports */ - -#define MAX_PARALLEL_PORTS 3 - -extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; - -void do_usb_add(Monitor *mon, const QDict *qdict); -void do_usb_del(Monitor *mon, const QDict *qdict); -void usb_info(Monitor *mon, const QDict *qdict); - -void rtc_change_mon_event(struct tm *tm); - -void add_boot_device_path(int32_t bootindex, DeviceState *dev, -                          const char *suffix); -char *get_boot_devices_list(size_t *size); - -DeviceState *get_boot_device(uint32_t position); - -QemuOpts *qemu_get_machine_opts(void); - -bool usb_enabled(bool default_usb); - -extern QemuOptsList qemu_drive_opts; -extern QemuOptsList qemu_chardev_opts; -extern QemuOptsList qemu_device_opts; -extern QemuOptsList qemu_netdev_opts; -extern QemuOptsList qemu_net_opts; -extern QemuOptsList qemu_global_opts; -extern QemuOptsList qemu_mon_opts; - -#endif diff --git a/contrib/qemu/include/trace.h b/contrib/qemu/include/trace.h deleted file mode 100644 index c15f4981280..00000000000 --- a/contrib/qemu/include/trace.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef TRACE_H -#define TRACE_H - -#include "trace/generated-tracers.h" - -#endif  /* TRACE_H */ diff --git a/contrib/qemu/nop-symbols.c b/contrib/qemu/nop-symbols.c deleted file mode 100644 index ae93a3d3bef..00000000000 --- a/contrib/qemu/nop-symbols.c +++ /dev/null @@ -1,12 +0,0 @@ -int notifier_with_return_list_init () { return 0; } -int notifier_with_return_list_notify () { return 0; } -int notifier_with_return_list_add () { return 0; } -int notifier_list_init () { return 0; } -int notifier_list_notify () { return 0; } -int notifier_list_add () { return 0; } -int monitor_protocol_event () { return 0; } -int block_job_cancel_sync () { return 0; } -int block_job_iostatus_reset () { return 0; } -int vm_stop () { return 0; } -int qemu_get_aio_context () { return 0; } - diff --git a/contrib/qemu/qapi-types.h b/contrib/qemu/qapi-types.h deleted file mode 100644 index 082b06d1c2b..00000000000 --- a/contrib/qemu/qapi-types.h +++ /dev/null @@ -1,2746 +0,0 @@ -/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ - -/* - * schema-defined QAPI types - * - * Copyright IBM, Corp. 2011 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef QAPI_TYPES_H -#define QAPI_TYPES_H - -#include <stdbool.h> -#include <stdint.h> - - -#ifndef QAPI_TYPES_BUILTIN_STRUCT_DECL_H -#define QAPI_TYPES_BUILTIN_STRUCT_DECL_H - - -typedef struct strList -{ -    union { -        char * value; -        uint64_t padding; -    }; -    struct strList *next; -} strList; - -typedef struct intList -{ -    union { -        int64_t value; -        uint64_t padding; -    }; -    struct intList *next; -} intList; - -typedef struct numberList -{ -    union { -        double value; -        uint64_t padding; -    }; -    struct numberList *next; -} numberList; - -typedef struct boolList -{ -    union { -        bool value; -        uint64_t padding; -    }; -    struct boolList *next; -} boolList; - -typedef struct int8List -{ -    union { -        int8_t value; -        uint64_t padding; -    }; -    struct int8List *next; -} int8List; - -typedef struct int16List -{ -    union { -        int16_t value; -        uint64_t padding; -    }; -    struct int16List *next; -} int16List; - -typedef struct int32List -{ -    union { -        int32_t value; -        uint64_t padding; -    }; -    struct int32List *next; -} int32List; - -typedef struct int64List -{ -    union { -        int64_t value; -        uint64_t padding; -    }; -    struct int64List *next; -} int64List; - -typedef struct uint8List -{ -    union { -        uint8_t value; -        uint64_t padding; -    }; -    struct uint8List *next; -} uint8List; - -typedef struct uint16List -{ -    union { -        uint16_t value; -        uint64_t padding; -    }; -    struct uint16List *next; -} uint16List; - -typedef struct uint32List -{ -    union { -        uint32_t value; -        uint64_t padding; -    }; -    struct uint32List *next; -} uint32List; - -typedef struct uint64List -{ -    union { -        uint64_t value; -        uint64_t padding; -    }; -    struct uint64List *next; -} uint64List; - -#endif /* QAPI_TYPES_BUILTIN_STRUCT_DECL_H */ - - -extern const char *ErrorClass_lookup[]; -typedef enum ErrorClass -{ -    ERROR_CLASS_GENERIC_ERROR = 0, -    ERROR_CLASS_COMMAND_NOT_FOUND = 1, -    ERROR_CLASS_DEVICE_ENCRYPTED = 2, -    ERROR_CLASS_DEVICE_NOT_ACTIVE = 3, -    ERROR_CLASS_DEVICE_NOT_FOUND = 4, -    ERROR_CLASS_K_V_M_MISSING_CAP = 5, -    ERROR_CLASS_MAX = 6, -} ErrorClass; - -typedef struct ErrorClassList -{ -    ErrorClass value; -    struct ErrorClassList *next; -} ErrorClassList; - - -typedef struct NameInfo NameInfo; - -typedef struct NameInfoList -{ -    union { -        NameInfo *value; -        uint64_t padding; -    }; -    struct NameInfoList *next; -} NameInfoList; - - -typedef struct VersionInfo VersionInfo; - -typedef struct VersionInfoList -{ -    union { -        VersionInfo *value; -        uint64_t padding; -    }; -    struct VersionInfoList *next; -} VersionInfoList; - - -typedef struct KvmInfo KvmInfo; - -typedef struct KvmInfoList -{ -    union { -        KvmInfo *value; -        uint64_t padding; -    }; -    struct KvmInfoList *next; -} KvmInfoList; - -extern const char *RunState_lookup[]; -typedef enum RunState -{ -    RUN_STATE_DEBUG = 0, -    RUN_STATE_INMIGRATE = 1, -    RUN_STATE_INTERNAL_ERROR = 2, -    RUN_STATE_IO_ERROR = 3, -    RUN_STATE_PAUSED = 4, -    RUN_STATE_POSTMIGRATE = 5, -    RUN_STATE_PRELAUNCH = 6, -    RUN_STATE_FINISH_MIGRATE = 7, -    RUN_STATE_RESTORE_VM = 8, -    RUN_STATE_RUNNING = 9, -    RUN_STATE_SAVE_VM = 10, -    RUN_STATE_SHUTDOWN = 11, -    RUN_STATE_SUSPENDED = 12, -    RUN_STATE_WATCHDOG = 13, -    RUN_STATE_GUEST_PANICKED = 14, -    RUN_STATE_MAX = 15, -} RunState; - -typedef struct RunStateList -{ -    RunState value; -    struct RunStateList *next; -} RunStateList; - - -typedef struct SnapshotInfo SnapshotInfo; - -typedef struct SnapshotInfoList -{ -    union { -        SnapshotInfo *value; -        uint64_t padding; -    }; -    struct SnapshotInfoList *next; -} SnapshotInfoList; - - -typedef struct ImageInfo ImageInfo; - -typedef struct ImageInfoList -{ -    union { -        ImageInfo *value; -        uint64_t padding; -    }; -    struct ImageInfoList *next; -} ImageInfoList; - - -typedef struct ImageCheck ImageCheck; - -typedef struct ImageCheckList -{ -    union { -        ImageCheck *value; -        uint64_t padding; -    }; -    struct ImageCheckList *next; -} ImageCheckList; - - -typedef struct StatusInfo StatusInfo; - -typedef struct StatusInfoList -{ -    union { -        StatusInfo *value; -        uint64_t padding; -    }; -    struct StatusInfoList *next; -} StatusInfoList; - - -typedef struct UuidInfo UuidInfo; - -typedef struct UuidInfoList -{ -    union { -        UuidInfo *value; -        uint64_t padding; -    }; -    struct UuidInfoList *next; -} UuidInfoList; - - -typedef struct ChardevInfo ChardevInfo; - -typedef struct ChardevInfoList -{ -    union { -        ChardevInfo *value; -        uint64_t padding; -    }; -    struct ChardevInfoList *next; -} ChardevInfoList; - -extern const char *DataFormat_lookup[]; -typedef enum DataFormat -{ -    DATA_FORMAT_UTF8 = 0, -    DATA_FORMAT_BASE64 = 1, -    DATA_FORMAT_MAX = 2, -} DataFormat; - -typedef struct DataFormatList -{ -    DataFormat value; -    struct DataFormatList *next; -} DataFormatList; - - -typedef struct CommandInfo CommandInfo; - -typedef struct CommandInfoList -{ -    union { -        CommandInfo *value; -        uint64_t padding; -    }; -    struct CommandInfoList *next; -} CommandInfoList; - - -typedef struct EventInfo EventInfo; - -typedef struct EventInfoList -{ -    union { -        EventInfo *value; -        uint64_t padding; -    }; -    struct EventInfoList *next; -} EventInfoList; - - -typedef struct MigrationStats MigrationStats; - -typedef struct MigrationStatsList -{ -    union { -        MigrationStats *value; -        uint64_t padding; -    }; -    struct MigrationStatsList *next; -} MigrationStatsList; - - -typedef struct XBZRLECacheStats XBZRLECacheStats; - -typedef struct XBZRLECacheStatsList -{ -    union { -        XBZRLECacheStats *value; -        uint64_t padding; -    }; -    struct XBZRLECacheStatsList *next; -} XBZRLECacheStatsList; - - -typedef struct MigrationInfo MigrationInfo; - -typedef struct MigrationInfoList -{ -    union { -        MigrationInfo *value; -        uint64_t padding; -    }; -    struct MigrationInfoList *next; -} MigrationInfoList; - -extern const char *MigrationCapability_lookup[]; -typedef enum MigrationCapability -{ -    MIGRATION_CAPABILITY_XBZRLE = 0, -    MIGRATION_CAPABILITY_X_RDMA_PIN_ALL = 1, -    MIGRATION_CAPABILITY_AUTO_CONVERGE = 2, -    MIGRATION_CAPABILITY_MAX = 3, -} MigrationCapability; - -typedef struct MigrationCapabilityList -{ -    MigrationCapability value; -    struct MigrationCapabilityList *next; -} MigrationCapabilityList; - - -typedef struct MigrationCapabilityStatus MigrationCapabilityStatus; - -typedef struct MigrationCapabilityStatusList -{ -    union { -        MigrationCapabilityStatus *value; -        uint64_t padding; -    }; -    struct MigrationCapabilityStatusList *next; -} MigrationCapabilityStatusList; - - -typedef struct MouseInfo MouseInfo; - -typedef struct MouseInfoList -{ -    union { -        MouseInfo *value; -        uint64_t padding; -    }; -    struct MouseInfoList *next; -} MouseInfoList; - - -typedef struct CpuInfo CpuInfo; - -typedef struct CpuInfoList -{ -    union { -        CpuInfo *value; -        uint64_t padding; -    }; -    struct CpuInfoList *next; -} CpuInfoList; - - -typedef struct BlockDeviceInfo BlockDeviceInfo; - -typedef struct BlockDeviceInfoList -{ -    union { -        BlockDeviceInfo *value; -        uint64_t padding; -    }; -    struct BlockDeviceInfoList *next; -} BlockDeviceInfoList; - -extern const char *BlockDeviceIoStatus_lookup[]; -typedef enum BlockDeviceIoStatus -{ -    BLOCK_DEVICE_IO_STATUS_OK = 0, -    BLOCK_DEVICE_IO_STATUS_FAILED = 1, -    BLOCK_DEVICE_IO_STATUS_NOSPACE = 2, -    BLOCK_DEVICE_IO_STATUS_MAX = 3, -} BlockDeviceIoStatus; - -typedef struct BlockDeviceIoStatusList -{ -    BlockDeviceIoStatus value; -    struct BlockDeviceIoStatusList *next; -} BlockDeviceIoStatusList; - - -typedef struct BlockDirtyInfo BlockDirtyInfo; - -typedef struct BlockDirtyInfoList -{ -    union { -        BlockDirtyInfo *value; -        uint64_t padding; -    }; -    struct BlockDirtyInfoList *next; -} BlockDirtyInfoList; - - -typedef struct BlockInfo BlockInfo; - -typedef struct BlockInfoList -{ -    union { -        BlockInfo *value; -        uint64_t padding; -    }; -    struct BlockInfoList *next; -} BlockInfoList; - - -typedef struct BlockDeviceStats BlockDeviceStats; - -typedef struct BlockDeviceStatsList -{ -    union { -        BlockDeviceStats *value; -        uint64_t padding; -    }; -    struct BlockDeviceStatsList *next; -} BlockDeviceStatsList; - - -typedef struct BlockStats BlockStats; - -typedef struct BlockStatsList -{ -    union { -        BlockStats *value; -        uint64_t padding; -    }; -    struct BlockStatsList *next; -} BlockStatsList; - - -typedef struct VncClientInfo VncClientInfo; - -typedef struct VncClientInfoList -{ -    union { -        VncClientInfo *value; -        uint64_t padding; -    }; -    struct VncClientInfoList *next; -} VncClientInfoList; - - -typedef struct VncInfo VncInfo; - -typedef struct VncInfoList -{ -    union { -        VncInfo *value; -        uint64_t padding; -    }; -    struct VncInfoList *next; -} VncInfoList; - - -typedef struct SpiceChannel SpiceChannel; - -typedef struct SpiceChannelList -{ -    union { -        SpiceChannel *value; -        uint64_t padding; -    }; -    struct SpiceChannelList *next; -} SpiceChannelList; - -extern const char *SpiceQueryMouseMode_lookup[]; -typedef enum SpiceQueryMouseMode -{ -    SPICE_QUERY_MOUSE_MODE_CLIENT = 0, -    SPICE_QUERY_MOUSE_MODE_SERVER = 1, -    SPICE_QUERY_MOUSE_MODE_UNKNOWN = 2, -    SPICE_QUERY_MOUSE_MODE_MAX = 3, -} SpiceQueryMouseMode; - -typedef struct SpiceQueryMouseModeList -{ -    SpiceQueryMouseMode value; -    struct SpiceQueryMouseModeList *next; -} SpiceQueryMouseModeList; - - -typedef struct SpiceInfo SpiceInfo; - -typedef struct SpiceInfoList -{ -    union { -        SpiceInfo *value; -        uint64_t padding; -    }; -    struct SpiceInfoList *next; -} SpiceInfoList; - - -typedef struct BalloonInfo BalloonInfo; - -typedef struct BalloonInfoList -{ -    union { -        BalloonInfo *value; -        uint64_t padding; -    }; -    struct BalloonInfoList *next; -} BalloonInfoList; - - -typedef struct PciMemoryRange PciMemoryRange; - -typedef struct PciMemoryRangeList -{ -    union { -        PciMemoryRange *value; -        uint64_t padding; -    }; -    struct PciMemoryRangeList *next; -} PciMemoryRangeList; - - -typedef struct PciMemoryRegion PciMemoryRegion; - -typedef struct PciMemoryRegionList -{ -    union { -        PciMemoryRegion *value; -        uint64_t padding; -    }; -    struct PciMemoryRegionList *next; -} PciMemoryRegionList; - - -typedef struct PciBridgeInfo PciBridgeInfo; - -typedef struct PciBridgeInfoList -{ -    union { -        PciBridgeInfo *value; -        uint64_t padding; -    }; -    struct PciBridgeInfoList *next; -} PciBridgeInfoList; - - -typedef struct PciDeviceInfo PciDeviceInfo; - -typedef struct PciDeviceInfoList -{ -    union { -        PciDeviceInfo *value; -        uint64_t padding; -    }; -    struct PciDeviceInfoList *next; -} PciDeviceInfoList; - - -typedef struct PciInfo PciInfo; - -typedef struct PciInfoList -{ -    union { -        PciInfo *value; -        uint64_t padding; -    }; -    struct PciInfoList *next; -} PciInfoList; - -extern const char *BlockdevOnError_lookup[]; -typedef enum BlockdevOnError -{ -    BLOCKDEV_ON_ERROR_REPORT = 0, -    BLOCKDEV_ON_ERROR_IGNORE = 1, -    BLOCKDEV_ON_ERROR_ENOSPC = 2, -    BLOCKDEV_ON_ERROR_STOP = 3, -    BLOCKDEV_ON_ERROR_MAX = 4, -} BlockdevOnError; - -typedef struct BlockdevOnErrorList -{ -    BlockdevOnError value; -    struct BlockdevOnErrorList *next; -} BlockdevOnErrorList; - -extern const char *MirrorSyncMode_lookup[]; -typedef enum MirrorSyncMode -{ -    MIRROR_SYNC_MODE_TOP = 0, -    MIRROR_SYNC_MODE_FULL = 1, -    MIRROR_SYNC_MODE_NONE = 2, -    MIRROR_SYNC_MODE_MAX = 3, -} MirrorSyncMode; - -typedef struct MirrorSyncModeList -{ -    MirrorSyncMode value; -    struct MirrorSyncModeList *next; -} MirrorSyncModeList; - - -typedef struct BlockJobInfo BlockJobInfo; - -typedef struct BlockJobInfoList -{ -    union { -        BlockJobInfo *value; -        uint64_t padding; -    }; -    struct BlockJobInfoList *next; -} BlockJobInfoList; - -extern const char *NewImageMode_lookup[]; -typedef enum NewImageMode -{ -    NEW_IMAGE_MODE_EXISTING = 0, -    NEW_IMAGE_MODE_ABSOLUTE_PATHS = 1, -    NEW_IMAGE_MODE_MAX = 2, -} NewImageMode; - -typedef struct NewImageModeList -{ -    NewImageMode value; -    struct NewImageModeList *next; -} NewImageModeList; - - -typedef struct BlockdevSnapshot BlockdevSnapshot; - -typedef struct BlockdevSnapshotList -{ -    union { -        BlockdevSnapshot *value; -        uint64_t padding; -    }; -    struct BlockdevSnapshotList *next; -} BlockdevSnapshotList; - - -typedef struct DriveBackup DriveBackup; - -typedef struct DriveBackupList -{ -    union { -        DriveBackup *value; -        uint64_t padding; -    }; -    struct DriveBackupList *next; -} DriveBackupList; - - -typedef struct Abort Abort; - -typedef struct AbortList -{ -    union { -        Abort *value; -        uint64_t padding; -    }; -    struct AbortList *next; -} AbortList; - - -typedef struct TransactionAction TransactionAction; - -typedef struct TransactionActionList -{ -    union { -        TransactionAction *value; -        uint64_t padding; -    }; -    struct TransactionActionList *next; -} TransactionActionList; - -extern const char *TransactionActionKind_lookup[]; -typedef enum TransactionActionKind -{ -    TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC = 0, -    TRANSACTION_ACTION_KIND_DRIVE_BACKUP = 1, -    TRANSACTION_ACTION_KIND_ABORT = 2, -    TRANSACTION_ACTION_KIND_MAX = 3, -} TransactionActionKind; - - -typedef struct ObjectPropertyInfo ObjectPropertyInfo; - -typedef struct ObjectPropertyInfoList -{ -    union { -        ObjectPropertyInfo *value; -        uint64_t padding; -    }; -    struct ObjectPropertyInfoList *next; -} ObjectPropertyInfoList; - - -typedef struct ObjectTypeInfo ObjectTypeInfo; - -typedef struct ObjectTypeInfoList -{ -    union { -        ObjectTypeInfo *value; -        uint64_t padding; -    }; -    struct ObjectTypeInfoList *next; -} ObjectTypeInfoList; - - -typedef struct DevicePropertyInfo DevicePropertyInfo; - -typedef struct DevicePropertyInfoList -{ -    union { -        DevicePropertyInfo *value; -        uint64_t padding; -    }; -    struct DevicePropertyInfoList *next; -} DevicePropertyInfoList; - - -typedef struct NetdevNoneOptions NetdevNoneOptions; - -typedef struct NetdevNoneOptionsList -{ -    union { -        NetdevNoneOptions *value; -        uint64_t padding; -    }; -    struct NetdevNoneOptionsList *next; -} NetdevNoneOptionsList; - - -typedef struct NetLegacyNicOptions NetLegacyNicOptions; - -typedef struct NetLegacyNicOptionsList -{ -    union { -        NetLegacyNicOptions *value; -        uint64_t padding; -    }; -    struct NetLegacyNicOptionsList *next; -} NetLegacyNicOptionsList; - - -typedef struct String String; - -typedef struct StringList -{ -    union { -        String *value; -        uint64_t padding; -    }; -    struct StringList *next; -} StringList; - - -typedef struct NetdevUserOptions NetdevUserOptions; - -typedef struct NetdevUserOptionsList -{ -    union { -        NetdevUserOptions *value; -        uint64_t padding; -    }; -    struct NetdevUserOptionsList *next; -} NetdevUserOptionsList; - - -typedef struct NetdevTapOptions NetdevTapOptions; - -typedef struct NetdevTapOptionsList -{ -    union { -        NetdevTapOptions *value; -        uint64_t padding; -    }; -    struct NetdevTapOptionsList *next; -} NetdevTapOptionsList; - - -typedef struct NetdevSocketOptions NetdevSocketOptions; - -typedef struct NetdevSocketOptionsList -{ -    union { -        NetdevSocketOptions *value; -        uint64_t padding; -    }; -    struct NetdevSocketOptionsList *next; -} NetdevSocketOptionsList; - - -typedef struct NetdevVdeOptions NetdevVdeOptions; - -typedef struct NetdevVdeOptionsList -{ -    union { -        NetdevVdeOptions *value; -        uint64_t padding; -    }; -    struct NetdevVdeOptionsList *next; -} NetdevVdeOptionsList; - - -typedef struct NetdevDumpOptions NetdevDumpOptions; - -typedef struct NetdevDumpOptionsList -{ -    union { -        NetdevDumpOptions *value; -        uint64_t padding; -    }; -    struct NetdevDumpOptionsList *next; -} NetdevDumpOptionsList; - - -typedef struct NetdevBridgeOptions NetdevBridgeOptions; - -typedef struct NetdevBridgeOptionsList -{ -    union { -        NetdevBridgeOptions *value; -        uint64_t padding; -    }; -    struct NetdevBridgeOptionsList *next; -} NetdevBridgeOptionsList; - - -typedef struct NetdevHubPortOptions NetdevHubPortOptions; - -typedef struct NetdevHubPortOptionsList -{ -    union { -        NetdevHubPortOptions *value; -        uint64_t padding; -    }; -    struct NetdevHubPortOptionsList *next; -} NetdevHubPortOptionsList; - - -typedef struct NetClientOptions NetClientOptions; - -typedef struct NetClientOptionsList -{ -    union { -        NetClientOptions *value; -        uint64_t padding; -    }; -    struct NetClientOptionsList *next; -} NetClientOptionsList; - -extern const char *NetClientOptionsKind_lookup[]; -typedef enum NetClientOptionsKind -{ -    NET_CLIENT_OPTIONS_KIND_NONE = 0, -    NET_CLIENT_OPTIONS_KIND_NIC = 1, -    NET_CLIENT_OPTIONS_KIND_USER = 2, -    NET_CLIENT_OPTIONS_KIND_TAP = 3, -    NET_CLIENT_OPTIONS_KIND_SOCKET = 4, -    NET_CLIENT_OPTIONS_KIND_VDE = 5, -    NET_CLIENT_OPTIONS_KIND_DUMP = 6, -    NET_CLIENT_OPTIONS_KIND_BRIDGE = 7, -    NET_CLIENT_OPTIONS_KIND_HUBPORT = 8, -    NET_CLIENT_OPTIONS_KIND_MAX = 9, -} NetClientOptionsKind; - - -typedef struct NetLegacy NetLegacy; - -typedef struct NetLegacyList -{ -    union { -        NetLegacy *value; -        uint64_t padding; -    }; -    struct NetLegacyList *next; -} NetLegacyList; - - -typedef struct Netdev Netdev; - -typedef struct NetdevList -{ -    union { -        Netdev *value; -        uint64_t padding; -    }; -    struct NetdevList *next; -} NetdevList; - - -typedef struct InetSocketAddress InetSocketAddress; - -typedef struct InetSocketAddressList -{ -    union { -        InetSocketAddress *value; -        uint64_t padding; -    }; -    struct InetSocketAddressList *next; -} InetSocketAddressList; - - -typedef struct UnixSocketAddress UnixSocketAddress; - -typedef struct UnixSocketAddressList -{ -    union { -        UnixSocketAddress *value; -        uint64_t padding; -    }; -    struct UnixSocketAddressList *next; -} UnixSocketAddressList; - - -typedef struct SocketAddress SocketAddress; - -typedef struct SocketAddressList -{ -    union { -        SocketAddress *value; -        uint64_t padding; -    }; -    struct SocketAddressList *next; -} SocketAddressList; - -extern const char *SocketAddressKind_lookup[]; -typedef enum SocketAddressKind -{ -    SOCKET_ADDRESS_KIND_INET = 0, -    SOCKET_ADDRESS_KIND_UNIX = 1, -    SOCKET_ADDRESS_KIND_FD = 2, -    SOCKET_ADDRESS_KIND_MAX = 3, -} SocketAddressKind; - - -typedef struct MachineInfo MachineInfo; - -typedef struct MachineInfoList -{ -    union { -        MachineInfo *value; -        uint64_t padding; -    }; -    struct MachineInfoList *next; -} MachineInfoList; - - -typedef struct CpuDefinitionInfo CpuDefinitionInfo; - -typedef struct CpuDefinitionInfoList -{ -    union { -        CpuDefinitionInfo *value; -        uint64_t padding; -    }; -    struct CpuDefinitionInfoList *next; -} CpuDefinitionInfoList; - - -typedef struct AddfdInfo AddfdInfo; - -typedef struct AddfdInfoList -{ -    union { -        AddfdInfo *value; -        uint64_t padding; -    }; -    struct AddfdInfoList *next; -} AddfdInfoList; - - -typedef struct FdsetFdInfo FdsetFdInfo; - -typedef struct FdsetFdInfoList -{ -    union { -        FdsetFdInfo *value; -        uint64_t padding; -    }; -    struct FdsetFdInfoList *next; -} FdsetFdInfoList; - - -typedef struct FdsetInfo FdsetInfo; - -typedef struct FdsetInfoList -{ -    union { -        FdsetInfo *value; -        uint64_t padding; -    }; -    struct FdsetInfoList *next; -} FdsetInfoList; - - -typedef struct TargetInfo TargetInfo; - -typedef struct TargetInfoList -{ -    union { -        TargetInfo *value; -        uint64_t padding; -    }; -    struct TargetInfoList *next; -} TargetInfoList; - -extern const char *QKeyCode_lookup[]; -typedef enum QKeyCode -{ -    Q_KEY_CODE_SHIFT = 0, -    Q_KEY_CODE_SHIFT_R = 1, -    Q_KEY_CODE_ALT = 2, -    Q_KEY_CODE_ALT_R = 3, -    Q_KEY_CODE_ALTGR = 4, -    Q_KEY_CODE_ALTGR_R = 5, -    Q_KEY_CODE_CTRL = 6, -    Q_KEY_CODE_CTRL_R = 7, -    Q_KEY_CODE_MENU = 8, -    Q_KEY_CODE_ESC = 9, -    Q_KEY_CODE_1 = 10, -    Q_KEY_CODE_2 = 11, -    Q_KEY_CODE_3 = 12, -    Q_KEY_CODE_4 = 13, -    Q_KEY_CODE_5 = 14, -    Q_KEY_CODE_6 = 15, -    Q_KEY_CODE_7 = 16, -    Q_KEY_CODE_8 = 17, -    Q_KEY_CODE_9 = 18, -    Q_KEY_CODE_0 = 19, -    Q_KEY_CODE_MINUS = 20, -    Q_KEY_CODE_EQUAL = 21, -    Q_KEY_CODE_BACKSPACE = 22, -    Q_KEY_CODE_TAB = 23, -    Q_KEY_CODE_Q = 24, -    Q_KEY_CODE_W = 25, -    Q_KEY_CODE_E = 26, -    Q_KEY_CODE_R = 27, -    Q_KEY_CODE_T = 28, -    Q_KEY_CODE_Y = 29, -    Q_KEY_CODE_U = 30, -    Q_KEY_CODE_I = 31, -    Q_KEY_CODE_O = 32, -    Q_KEY_CODE_P = 33, -    Q_KEY_CODE_BRACKET_LEFT = 34, -    Q_KEY_CODE_BRACKET_RIGHT = 35, -    Q_KEY_CODE_RET = 36, -    Q_KEY_CODE_A = 37, -    Q_KEY_CODE_S = 38, -    Q_KEY_CODE_D = 39, -    Q_KEY_CODE_F = 40, -    Q_KEY_CODE_G = 41, -    Q_KEY_CODE_H = 42, -    Q_KEY_CODE_J = 43, -    Q_KEY_CODE_K = 44, -    Q_KEY_CODE_L = 45, -    Q_KEY_CODE_SEMICOLON = 46, -    Q_KEY_CODE_APOSTROPHE = 47, -    Q_KEY_CODE_GRAVE_ACCENT = 48, -    Q_KEY_CODE_BACKSLASH = 49, -    Q_KEY_CODE_Z = 50, -    Q_KEY_CODE_X = 51, -    Q_KEY_CODE_C = 52, -    Q_KEY_CODE_V = 53, -    Q_KEY_CODE_B = 54, -    Q_KEY_CODE_N = 55, -    Q_KEY_CODE_M = 56, -    Q_KEY_CODE_COMMA = 57, -    Q_KEY_CODE_DOT = 58, -    Q_KEY_CODE_SLASH = 59, -    Q_KEY_CODE_ASTERISK = 60, -    Q_KEY_CODE_SPC = 61, -    Q_KEY_CODE_CAPS_LOCK = 62, -    Q_KEY_CODE_F1 = 63, -    Q_KEY_CODE_F2 = 64, -    Q_KEY_CODE_F3 = 65, -    Q_KEY_CODE_F4 = 66, -    Q_KEY_CODE_F5 = 67, -    Q_KEY_CODE_F6 = 68, -    Q_KEY_CODE_F7 = 69, -    Q_KEY_CODE_F8 = 70, -    Q_KEY_CODE_F9 = 71, -    Q_KEY_CODE_F10 = 72, -    Q_KEY_CODE_NUM_LOCK = 73, -    Q_KEY_CODE_SCROLL_LOCK = 74, -    Q_KEY_CODE_KP_DIVIDE = 75, -    Q_KEY_CODE_KP_MULTIPLY = 76, -    Q_KEY_CODE_KP_SUBTRACT = 77, -    Q_KEY_CODE_KP_ADD = 78, -    Q_KEY_CODE_KP_ENTER = 79, -    Q_KEY_CODE_KP_DECIMAL = 80, -    Q_KEY_CODE_SYSRQ = 81, -    Q_KEY_CODE_KP_0 = 82, -    Q_KEY_CODE_KP_1 = 83, -    Q_KEY_CODE_KP_2 = 84, -    Q_KEY_CODE_KP_3 = 85, -    Q_KEY_CODE_KP_4 = 86, -    Q_KEY_CODE_KP_5 = 87, -    Q_KEY_CODE_KP_6 = 88, -    Q_KEY_CODE_KP_7 = 89, -    Q_KEY_CODE_KP_8 = 90, -    Q_KEY_CODE_KP_9 = 91, -    Q_KEY_CODE_LESS = 92, -    Q_KEY_CODE_F11 = 93, -    Q_KEY_CODE_F12 = 94, -    Q_KEY_CODE_PRINT = 95, -    Q_KEY_CODE_HOME = 96, -    Q_KEY_CODE_PGUP = 97, -    Q_KEY_CODE_PGDN = 98, -    Q_KEY_CODE_END = 99, -    Q_KEY_CODE_LEFT = 100, -    Q_KEY_CODE_UP = 101, -    Q_KEY_CODE_DOWN = 102, -    Q_KEY_CODE_RIGHT = 103, -    Q_KEY_CODE_INSERT = 104, -    Q_KEY_CODE_DELETE = 105, -    Q_KEY_CODE_STOP = 106, -    Q_KEY_CODE_AGAIN = 107, -    Q_KEY_CODE_PROPS = 108, -    Q_KEY_CODE_UNDO = 109, -    Q_KEY_CODE_FRONT = 110, -    Q_KEY_CODE_COPY = 111, -    Q_KEY_CODE_OPEN = 112, -    Q_KEY_CODE_PASTE = 113, -    Q_KEY_CODE_FIND = 114, -    Q_KEY_CODE_CUT = 115, -    Q_KEY_CODE_LF = 116, -    Q_KEY_CODE_HELP = 117, -    Q_KEY_CODE_META_L = 118, -    Q_KEY_CODE_META_R = 119, -    Q_KEY_CODE_COMPOSE = 120, -    Q_KEY_CODE_MAX = 121, -} QKeyCode; - -typedef struct QKeyCodeList -{ -    QKeyCode value; -    struct QKeyCodeList *next; -} QKeyCodeList; - - -typedef struct KeyValue KeyValue; - -typedef struct KeyValueList -{ -    union { -        KeyValue *value; -        uint64_t padding; -    }; -    struct KeyValueList *next; -} KeyValueList; - -extern const char *KeyValueKind_lookup[]; -typedef enum KeyValueKind -{ -    KEY_VALUE_KIND_NUMBER = 0, -    KEY_VALUE_KIND_QCODE = 1, -    KEY_VALUE_KIND_MAX = 2, -} KeyValueKind; - - -typedef struct ChardevFile ChardevFile; - -typedef struct ChardevFileList -{ -    union { -        ChardevFile *value; -        uint64_t padding; -    }; -    struct ChardevFileList *next; -} ChardevFileList; - - -typedef struct ChardevHostdev ChardevHostdev; - -typedef struct ChardevHostdevList -{ -    union { -        ChardevHostdev *value; -        uint64_t padding; -    }; -    struct ChardevHostdevList *next; -} ChardevHostdevList; - - -typedef struct ChardevSocket ChardevSocket; - -typedef struct ChardevSocketList -{ -    union { -        ChardevSocket *value; -        uint64_t padding; -    }; -    struct ChardevSocketList *next; -} ChardevSocketList; - - -typedef struct ChardevUdp ChardevUdp; - -typedef struct ChardevUdpList -{ -    union { -        ChardevUdp *value; -        uint64_t padding; -    }; -    struct ChardevUdpList *next; -} ChardevUdpList; - - -typedef struct ChardevMux ChardevMux; - -typedef struct ChardevMuxList -{ -    union { -        ChardevMux *value; -        uint64_t padding; -    }; -    struct ChardevMuxList *next; -} ChardevMuxList; - - -typedef struct ChardevStdio ChardevStdio; - -typedef struct ChardevStdioList -{ -    union { -        ChardevStdio *value; -        uint64_t padding; -    }; -    struct ChardevStdioList *next; -} ChardevStdioList; - - -typedef struct ChardevSpiceChannel ChardevSpiceChannel; - -typedef struct ChardevSpiceChannelList -{ -    union { -        ChardevSpiceChannel *value; -        uint64_t padding; -    }; -    struct ChardevSpiceChannelList *next; -} ChardevSpiceChannelList; - - -typedef struct ChardevSpicePort ChardevSpicePort; - -typedef struct ChardevSpicePortList -{ -    union { -        ChardevSpicePort *value; -        uint64_t padding; -    }; -    struct ChardevSpicePortList *next; -} ChardevSpicePortList; - - -typedef struct ChardevVC ChardevVC; - -typedef struct ChardevVCList -{ -    union { -        ChardevVC *value; -        uint64_t padding; -    }; -    struct ChardevVCList *next; -} ChardevVCList; - - -typedef struct ChardevMemory ChardevMemory; - -typedef struct ChardevMemoryList -{ -    union { -        ChardevMemory *value; -        uint64_t padding; -    }; -    struct ChardevMemoryList *next; -} ChardevMemoryList; - - -typedef struct ChardevDummy ChardevDummy; - -typedef struct ChardevDummyList -{ -    union { -        ChardevDummy *value; -        uint64_t padding; -    }; -    struct ChardevDummyList *next; -} ChardevDummyList; - - -typedef struct ChardevBackend ChardevBackend; - -typedef struct ChardevBackendList -{ -    union { -        ChardevBackend *value; -        uint64_t padding; -    }; -    struct ChardevBackendList *next; -} ChardevBackendList; - -extern const char *ChardevBackendKind_lookup[]; -typedef enum ChardevBackendKind -{ -    CHARDEV_BACKEND_KIND_FILE = 0, -    CHARDEV_BACKEND_KIND_SERIAL = 1, -    CHARDEV_BACKEND_KIND_PARALLEL = 2, -    CHARDEV_BACKEND_KIND_PIPE = 3, -    CHARDEV_BACKEND_KIND_SOCKET = 4, -    CHARDEV_BACKEND_KIND_UDP = 5, -    CHARDEV_BACKEND_KIND_PTY = 6, -    CHARDEV_BACKEND_KIND_NULL = 7, -    CHARDEV_BACKEND_KIND_MUX = 8, -    CHARDEV_BACKEND_KIND_MSMOUSE = 9, -    CHARDEV_BACKEND_KIND_BRAILLE = 10, -    CHARDEV_BACKEND_KIND_STDIO = 11, -    CHARDEV_BACKEND_KIND_CONSOLE = 12, -    CHARDEV_BACKEND_KIND_SPICEVMC = 13, -    CHARDEV_BACKEND_KIND_SPICEPORT = 14, -    CHARDEV_BACKEND_KIND_VC = 15, -    CHARDEV_BACKEND_KIND_MEMORY = 16, -    CHARDEV_BACKEND_KIND_MAX = 17, -} ChardevBackendKind; - - -typedef struct ChardevReturn ChardevReturn; - -typedef struct ChardevReturnList -{ -    union { -        ChardevReturn *value; -        uint64_t padding; -    }; -    struct ChardevReturnList *next; -} ChardevReturnList; - -extern const char *TpmModel_lookup[]; -typedef enum TpmModel -{ -    TPM_MODEL_TPM_TIS = 0, -    TPM_MODEL_MAX = 1, -} TpmModel; - -typedef struct TpmModelList -{ -    TpmModel value; -    struct TpmModelList *next; -} TpmModelList; - -extern const char *TpmType_lookup[]; -typedef enum TpmType -{ -    TPM_TYPE_PASSTHROUGH = 0, -    TPM_TYPE_MAX = 1, -} TpmType; - -typedef struct TpmTypeList -{ -    TpmType value; -    struct TpmTypeList *next; -} TpmTypeList; - - -typedef struct TPMPassthroughOptions TPMPassthroughOptions; - -typedef struct TPMPassthroughOptionsList -{ -    union { -        TPMPassthroughOptions *value; -        uint64_t padding; -    }; -    struct TPMPassthroughOptionsList *next; -} TPMPassthroughOptionsList; - - -typedef struct TpmTypeOptions TpmTypeOptions; - -typedef struct TpmTypeOptionsList -{ -    union { -        TpmTypeOptions *value; -        uint64_t padding; -    }; -    struct TpmTypeOptionsList *next; -} TpmTypeOptionsList; - -extern const char *TpmTypeOptionsKind_lookup[]; -typedef enum TpmTypeOptionsKind -{ -    TPM_TYPE_OPTIONS_KIND_PASSTHROUGH = 0, -    TPM_TYPE_OPTIONS_KIND_MAX = 1, -} TpmTypeOptionsKind; - - -typedef struct TPMInfo TPMInfo; - -typedef struct TPMInfoList -{ -    union { -        TPMInfo *value; -        uint64_t padding; -    }; -    struct TPMInfoList *next; -} TPMInfoList; - - -typedef struct AcpiTableOptions AcpiTableOptions; - -typedef struct AcpiTableOptionsList -{ -    union { -        AcpiTableOptions *value; -        uint64_t padding; -    }; -    struct AcpiTableOptionsList *next; -} AcpiTableOptionsList; - -extern const char *CommandLineParameterType_lookup[]; -typedef enum CommandLineParameterType -{ -    COMMAND_LINE_PARAMETER_TYPE_STRING = 0, -    COMMAND_LINE_PARAMETER_TYPE_BOOLEAN = 1, -    COMMAND_LINE_PARAMETER_TYPE_NUMBER = 2, -    COMMAND_LINE_PARAMETER_TYPE_SIZE = 3, -    COMMAND_LINE_PARAMETER_TYPE_MAX = 4, -} CommandLineParameterType; - -typedef struct CommandLineParameterTypeList -{ -    CommandLineParameterType value; -    struct CommandLineParameterTypeList *next; -} CommandLineParameterTypeList; - - -typedef struct CommandLineParameterInfo CommandLineParameterInfo; - -typedef struct CommandLineParameterInfoList -{ -    union { -        CommandLineParameterInfo *value; -        uint64_t padding; -    }; -    struct CommandLineParameterInfoList *next; -} CommandLineParameterInfoList; - - -typedef struct CommandLineOptionInfo CommandLineOptionInfo; - -typedef struct CommandLineOptionInfoList -{ -    union { -        CommandLineOptionInfo *value; -        uint64_t padding; -    }; -    struct CommandLineOptionInfoList *next; -} CommandLineOptionInfoList; - -extern const char *X86CPURegister32_lookup[]; -typedef enum X86CPURegister32 -{ -    X86_C_P_U_REGISTER32_EAX = 0, -    X86_C_P_U_REGISTER32_EBX = 1, -    X86_C_P_U_REGISTER32_ECX = 2, -    X86_C_P_U_REGISTER32_EDX = 3, -    X86_C_P_U_REGISTER32_ESP = 4, -    X86_C_P_U_REGISTER32_EBP = 5, -    X86_C_P_U_REGISTER32_ESI = 6, -    X86_C_P_U_REGISTER32_EDI = 7, -    X86_C_P_U_REGISTER32_MAX = 8, -} X86CPURegister32; - -typedef struct X86CPURegister32List -{ -    X86CPURegister32 value; -    struct X86CPURegister32List *next; -} X86CPURegister32List; - - -typedef struct X86CPUFeatureWordInfo X86CPUFeatureWordInfo; - -typedef struct X86CPUFeatureWordInfoList -{ -    union { -        X86CPUFeatureWordInfo *value; -        uint64_t padding; -    }; -    struct X86CPUFeatureWordInfoList *next; -} X86CPUFeatureWordInfoList; - -extern const char *RxState_lookup[]; -typedef enum RxState -{ -    RX_STATE_NORMAL = 0, -    RX_STATE_NONE = 1, -    RX_STATE_ALL = 2, -    RX_STATE_MAX = 3, -} RxState; - -typedef struct RxStateList -{ -    RxState value; -    struct RxStateList *next; -} RxStateList; - - -typedef struct RxFilterInfo RxFilterInfo; - -typedef struct RxFilterInfoList -{ -    union { -        RxFilterInfo *value; -        uint64_t padding; -    }; -    struct RxFilterInfoList *next; -} RxFilterInfoList; - -#ifndef QAPI_TYPES_BUILTIN_CLEANUP_DECL_H -#define QAPI_TYPES_BUILTIN_CLEANUP_DECL_H - -void qapi_free_strList(strList * obj); -void qapi_free_intList(intList * obj); -void qapi_free_numberList(numberList * obj); -void qapi_free_boolList(boolList * obj); -void qapi_free_int8List(int8List * obj); -void qapi_free_int16List(int16List * obj); -void qapi_free_int32List(int32List * obj); -void qapi_free_int64List(int64List * obj); -void qapi_free_uint8List(uint8List * obj); -void qapi_free_uint16List(uint16List * obj); -void qapi_free_uint32List(uint32List * obj); -void qapi_free_uint64List(uint64List * obj); - -#endif /* QAPI_TYPES_BUILTIN_CLEANUP_DECL_H */ - - -void qapi_free_ErrorClassList(ErrorClassList * obj); - -struct NameInfo -{ -    bool has_name; -    char * name; -}; - -void qapi_free_NameInfoList(NameInfoList * obj); -void qapi_free_NameInfo(NameInfo * obj); - -struct VersionInfo -{ -    struct  -    { -        int64_t major; -        int64_t minor; -        int64_t micro; -    } qemu; -    char * package; -}; - -void qapi_free_VersionInfoList(VersionInfoList * obj); -void qapi_free_VersionInfo(VersionInfo * obj); - -struct KvmInfo -{ -    bool enabled; -    bool present; -}; - -void qapi_free_KvmInfoList(KvmInfoList * obj); -void qapi_free_KvmInfo(KvmInfo * obj); - -void qapi_free_RunStateList(RunStateList * obj); - -struct SnapshotInfo -{ -    char * id; -    char * name; -    int64_t vm_state_size; -    int64_t date_sec; -    int64_t date_nsec; -    int64_t vm_clock_sec; -    int64_t vm_clock_nsec; -}; - -void qapi_free_SnapshotInfoList(SnapshotInfoList * obj); -void qapi_free_SnapshotInfo(SnapshotInfo * obj); - -struct ImageInfo -{ -    char * filename; -    char * format; -    bool has_dirty_flag; -    bool dirty_flag; -    bool has_actual_size; -    int64_t actual_size; -    int64_t virtual_size; -    bool has_cluster_size; -    int64_t cluster_size; -    bool has_encrypted; -    bool encrypted; -    bool has_backing_filename; -    char * backing_filename; -    bool has_full_backing_filename; -    char * full_backing_filename; -    bool has_backing_filename_format; -    char * backing_filename_format; -    bool has_snapshots; -    SnapshotInfoList * snapshots; -    bool has_backing_image; -    ImageInfo * backing_image; -}; - -void qapi_free_ImageInfoList(ImageInfoList * obj); -void qapi_free_ImageInfo(ImageInfo * obj); - -struct ImageCheck -{ -    char * filename; -    char * format; -    int64_t check_errors; -    bool has_image_end_offset; -    int64_t image_end_offset; -    bool has_corruptions; -    int64_t corruptions; -    bool has_leaks; -    int64_t leaks; -    bool has_corruptions_fixed; -    int64_t corruptions_fixed; -    bool has_leaks_fixed; -    int64_t leaks_fixed; -    bool has_total_clusters; -    int64_t total_clusters; -    bool has_allocated_clusters; -    int64_t allocated_clusters; -    bool has_fragmented_clusters; -    int64_t fragmented_clusters; -    bool has_compressed_clusters; -    int64_t compressed_clusters; -}; - -void qapi_free_ImageCheckList(ImageCheckList * obj); -void qapi_free_ImageCheck(ImageCheck * obj); - -struct StatusInfo -{ -    bool running; -    bool singlestep; -    RunState status; -}; - -void qapi_free_StatusInfoList(StatusInfoList * obj); -void qapi_free_StatusInfo(StatusInfo * obj); - -struct UuidInfo -{ -    char * UUID; -}; - -void qapi_free_UuidInfoList(UuidInfoList * obj); -void qapi_free_UuidInfo(UuidInfo * obj); - -struct ChardevInfo -{ -    char * label; -    char * filename; -}; - -void qapi_free_ChardevInfoList(ChardevInfoList * obj); -void qapi_free_ChardevInfo(ChardevInfo * obj); - -void qapi_free_DataFormatList(DataFormatList * obj); - -struct CommandInfo -{ -    char * name; -}; - -void qapi_free_CommandInfoList(CommandInfoList * obj); -void qapi_free_CommandInfo(CommandInfo * obj); - -struct EventInfo -{ -    char * name; -}; - -void qapi_free_EventInfoList(EventInfoList * obj); -void qapi_free_EventInfo(EventInfo * obj); - -struct MigrationStats -{ -    int64_t transferred; -    int64_t remaining; -    int64_t total; -    int64_t duplicate; -    int64_t skipped; -    int64_t normal; -    int64_t normal_bytes; -    int64_t dirty_pages_rate; -    double mbps; -}; - -void qapi_free_MigrationStatsList(MigrationStatsList * obj); -void qapi_free_MigrationStats(MigrationStats * obj); - -struct XBZRLECacheStats -{ -    int64_t cache_size; -    int64_t bytes; -    int64_t pages; -    int64_t cache_miss; -    int64_t overflow; -}; - -void qapi_free_XBZRLECacheStatsList(XBZRLECacheStatsList * obj); -void qapi_free_XBZRLECacheStats(XBZRLECacheStats * obj); - -struct MigrationInfo -{ -    bool has_status; -    char * status; -    bool has_ram; -    MigrationStats * ram; -    bool has_disk; -    MigrationStats * disk; -    bool has_xbzrle_cache; -    XBZRLECacheStats * xbzrle_cache; -    bool has_total_time; -    int64_t total_time; -    bool has_expected_downtime; -    int64_t expected_downtime; -    bool has_downtime; -    int64_t downtime; -}; - -void qapi_free_MigrationInfoList(MigrationInfoList * obj); -void qapi_free_MigrationInfo(MigrationInfo * obj); - -void qapi_free_MigrationCapabilityList(MigrationCapabilityList * obj); - -struct MigrationCapabilityStatus -{ -    MigrationCapability capability; -    bool state; -}; - -void qapi_free_MigrationCapabilityStatusList(MigrationCapabilityStatusList * obj); -void qapi_free_MigrationCapabilityStatus(MigrationCapabilityStatus * obj); - -struct MouseInfo -{ -    char * name; -    int64_t index; -    bool current; -    bool absolute; -}; - -void qapi_free_MouseInfoList(MouseInfoList * obj); -void qapi_free_MouseInfo(MouseInfo * obj); - -struct CpuInfo -{ -    int64_t CPU; -    bool current; -    bool halted; -    bool has_pc; -    int64_t pc; -    bool has_nip; -    int64_t nip; -    bool has_npc; -    int64_t npc; -    bool has_PC; -    int64_t PC; -    int64_t thread_id; -}; - -void qapi_free_CpuInfoList(CpuInfoList * obj); -void qapi_free_CpuInfo(CpuInfo * obj); - -struct BlockDeviceInfo -{ -    char * file; -    bool ro; -    char * drv; -    bool has_backing_file; -    char * backing_file; -    int64_t backing_file_depth; -    bool encrypted; -    bool encryption_key_missing; -    int64_t bps; -    int64_t bps_rd; -    int64_t bps_wr; -    int64_t iops; -    int64_t iops_rd; -    int64_t iops_wr; -    ImageInfo * image; -}; - -void qapi_free_BlockDeviceInfoList(BlockDeviceInfoList * obj); -void qapi_free_BlockDeviceInfo(BlockDeviceInfo * obj); - -void qapi_free_BlockDeviceIoStatusList(BlockDeviceIoStatusList * obj); - -struct BlockDirtyInfo -{ -    int64_t count; -    int64_t granularity; -}; - -void qapi_free_BlockDirtyInfoList(BlockDirtyInfoList * obj); -void qapi_free_BlockDirtyInfo(BlockDirtyInfo * obj); - -struct BlockInfo -{ -    char * device; -    char * type; -    bool removable; -    bool locked; -    bool has_inserted; -    BlockDeviceInfo * inserted; -    bool has_tray_open; -    bool tray_open; -    bool has_io_status; -    BlockDeviceIoStatus io_status; -    bool has_dirty; -    BlockDirtyInfo * dirty; -}; - -void qapi_free_BlockInfoList(BlockInfoList * obj); -void qapi_free_BlockInfo(BlockInfo * obj); - -struct BlockDeviceStats -{ -    int64_t rd_bytes; -    int64_t wr_bytes; -    int64_t rd_operations; -    int64_t wr_operations; -    int64_t flush_operations; -    int64_t flush_total_time_ns; -    int64_t wr_total_time_ns; -    int64_t rd_total_time_ns; -    int64_t wr_highest_offset; -}; - -void qapi_free_BlockDeviceStatsList(BlockDeviceStatsList * obj); -void qapi_free_BlockDeviceStats(BlockDeviceStats * obj); - -struct BlockStats -{ -    bool has_device; -    char * device; -    BlockDeviceStats * stats; -    bool has_parent; -    BlockStats * parent; -}; - -void qapi_free_BlockStatsList(BlockStatsList * obj); -void qapi_free_BlockStats(BlockStats * obj); - -struct VncClientInfo -{ -    char * host; -    char * family; -    char * service; -    bool has_x509_dname; -    char * x509_dname; -    bool has_sasl_username; -    char * sasl_username; -}; - -void qapi_free_VncClientInfoList(VncClientInfoList * obj); -void qapi_free_VncClientInfo(VncClientInfo * obj); - -struct VncInfo -{ -    bool enabled; -    bool has_host; -    char * host; -    bool has_family; -    char * family; -    bool has_service; -    char * service; -    bool has_auth; -    char * auth; -    bool has_clients; -    VncClientInfoList * clients; -}; - -void qapi_free_VncInfoList(VncInfoList * obj); -void qapi_free_VncInfo(VncInfo * obj); - -struct SpiceChannel -{ -    char * host; -    char * family; -    char * port; -    int64_t connection_id; -    int64_t channel_type; -    int64_t channel_id; -    bool tls; -}; - -void qapi_free_SpiceChannelList(SpiceChannelList * obj); -void qapi_free_SpiceChannel(SpiceChannel * obj); - -void qapi_free_SpiceQueryMouseModeList(SpiceQueryMouseModeList * obj); - -struct SpiceInfo -{ -    bool enabled; -    bool migrated; -    bool has_host; -    char * host; -    bool has_port; -    int64_t port; -    bool has_tls_port; -    int64_t tls_port; -    bool has_auth; -    char * auth; -    bool has_compiled_version; -    char * compiled_version; -    SpiceQueryMouseMode mouse_mode; -    bool has_channels; -    SpiceChannelList * channels; -}; - -void qapi_free_SpiceInfoList(SpiceInfoList * obj); -void qapi_free_SpiceInfo(SpiceInfo * obj); - -struct BalloonInfo -{ -    int64_t actual; -}; - -void qapi_free_BalloonInfoList(BalloonInfoList * obj); -void qapi_free_BalloonInfo(BalloonInfo * obj); - -struct PciMemoryRange -{ -    int64_t base; -    int64_t limit; -}; - -void qapi_free_PciMemoryRangeList(PciMemoryRangeList * obj); -void qapi_free_PciMemoryRange(PciMemoryRange * obj); - -struct PciMemoryRegion -{ -    int64_t bar; -    char * type; -    int64_t address; -    int64_t size; -    bool has_prefetch; -    bool prefetch; -    bool has_mem_type_64; -    bool mem_type_64; -}; - -void qapi_free_PciMemoryRegionList(PciMemoryRegionList * obj); -void qapi_free_PciMemoryRegion(PciMemoryRegion * obj); - -struct PciBridgeInfo -{ -    struct  -    { -        int64_t number; -        int64_t secondary; -        int64_t subordinate; -        PciMemoryRange * io_range; -        PciMemoryRange * memory_range; -        PciMemoryRange * prefetchable_range; -    } bus; -    bool has_devices; -    PciDeviceInfoList * devices; -}; - -void qapi_free_PciBridgeInfoList(PciBridgeInfoList * obj); -void qapi_free_PciBridgeInfo(PciBridgeInfo * obj); - -struct PciDeviceInfo -{ -    int64_t bus; -    int64_t slot; -    int64_t function; -    struct  -    { -        bool has_desc; -        char * desc; -        int64_t class; -    } class_info; -    struct  -    { -        int64_t device; -        int64_t vendor; -    } id; -    bool has_irq; -    int64_t irq; -    char * qdev_id; -    bool has_pci_bridge; -    PciBridgeInfo * pci_bridge; -    PciMemoryRegionList * regions; -}; - -void qapi_free_PciDeviceInfoList(PciDeviceInfoList * obj); -void qapi_free_PciDeviceInfo(PciDeviceInfo * obj); - -struct PciInfo -{ -    int64_t bus; -    PciDeviceInfoList * devices; -}; - -void qapi_free_PciInfoList(PciInfoList * obj); -void qapi_free_PciInfo(PciInfo * obj); - -void qapi_free_BlockdevOnErrorList(BlockdevOnErrorList * obj); - -void qapi_free_MirrorSyncModeList(MirrorSyncModeList * obj); - -struct BlockJobInfo -{ -    char * type; -    char * device; -    int64_t len; -    int64_t offset; -    bool busy; -    bool paused; -    int64_t speed; -    BlockDeviceIoStatus io_status; -}; - -void qapi_free_BlockJobInfoList(BlockJobInfoList * obj); -void qapi_free_BlockJobInfo(BlockJobInfo * obj); - -void qapi_free_NewImageModeList(NewImageModeList * obj); - -struct BlockdevSnapshot -{ -    char * device; -    char * snapshot_file; -    bool has_format; -    char * format; -    bool has_mode; -    NewImageMode mode; -}; - -void qapi_free_BlockdevSnapshotList(BlockdevSnapshotList * obj); -void qapi_free_BlockdevSnapshot(BlockdevSnapshot * obj); - -struct DriveBackup -{ -    char * device; -    char * target; -    bool has_format; -    char * format; -    MirrorSyncMode sync; -    bool has_mode; -    NewImageMode mode; -    bool has_speed; -    int64_t speed; -    bool has_on_source_error; -    BlockdevOnError on_source_error; -    bool has_on_target_error; -    BlockdevOnError on_target_error; -}; - -void qapi_free_DriveBackupList(DriveBackupList * obj); -void qapi_free_DriveBackup(DriveBackup * obj); - -struct Abort -{ -}; - -void qapi_free_AbortList(AbortList * obj); -void qapi_free_Abort(Abort * obj); - -struct TransactionAction -{ -    TransactionActionKind kind; -    union { -        void *data; -        BlockdevSnapshot * blockdev_snapshot_sync; -        DriveBackup * drive_backup; -        Abort * abort; -    }; -}; -void qapi_free_TransactionActionList(TransactionActionList * obj); -void qapi_free_TransactionAction(TransactionAction * obj); - -struct ObjectPropertyInfo -{ -    char * name; -    char * type; -}; - -void qapi_free_ObjectPropertyInfoList(ObjectPropertyInfoList * obj); -void qapi_free_ObjectPropertyInfo(ObjectPropertyInfo * obj); - -struct ObjectTypeInfo -{ -    char * name; -}; - -void qapi_free_ObjectTypeInfoList(ObjectTypeInfoList * obj); -void qapi_free_ObjectTypeInfo(ObjectTypeInfo * obj); - -struct DevicePropertyInfo -{ -    char * name; -    char * type; -}; - -void qapi_free_DevicePropertyInfoList(DevicePropertyInfoList * obj); -void qapi_free_DevicePropertyInfo(DevicePropertyInfo * obj); - -struct NetdevNoneOptions -{ -}; - -void qapi_free_NetdevNoneOptionsList(NetdevNoneOptionsList * obj); -void qapi_free_NetdevNoneOptions(NetdevNoneOptions * obj); - -struct NetLegacyNicOptions -{ -    bool has_netdev; -    char * netdev; -    bool has_macaddr; -    char * macaddr; -    bool has_model; -    char * model; -    bool has_addr; -    char * addr; -    bool has_vectors; -    uint32_t vectors; -}; - -void qapi_free_NetLegacyNicOptionsList(NetLegacyNicOptionsList * obj); -void qapi_free_NetLegacyNicOptions(NetLegacyNicOptions * obj); - -struct String -{ -    char * str; -}; - -void qapi_free_StringList(StringList * obj); -void qapi_free_String(String * obj); - -struct NetdevUserOptions -{ -    bool has_hostname; -    char * hostname; -    bool has_q_restrict; -    bool q_restrict; -    bool has_ip; -    char * ip; -    bool has_net; -    char * net; -    bool has_host; -    char * host; -    bool has_tftp; -    char * tftp; -    bool has_bootfile; -    char * bootfile; -    bool has_dhcpstart; -    char * dhcpstart; -    bool has_dns; -    char * dns; -    bool has_dnssearch; -    StringList * dnssearch; -    bool has_smb; -    char * smb; -    bool has_smbserver; -    char * smbserver; -    bool has_hostfwd; -    StringList * hostfwd; -    bool has_guestfwd; -    StringList * guestfwd; -}; - -void qapi_free_NetdevUserOptionsList(NetdevUserOptionsList * obj); -void qapi_free_NetdevUserOptions(NetdevUserOptions * obj); - -struct NetdevTapOptions -{ -    bool has_ifname; -    char * ifname; -    bool has_fd; -    char * fd; -    bool has_fds; -    char * fds; -    bool has_script; -    char * script; -    bool has_downscript; -    char * downscript; -    bool has_helper; -    char * helper; -    bool has_sndbuf; -    uint64_t sndbuf; -    bool has_vnet_hdr; -    bool vnet_hdr; -    bool has_vhost; -    bool vhost; -    bool has_vhostfd; -    char * vhostfd; -    bool has_vhostfds; -    char * vhostfds; -    bool has_vhostforce; -    bool vhostforce; -    bool has_queues; -    uint32_t queues; -}; - -void qapi_free_NetdevTapOptionsList(NetdevTapOptionsList * obj); -void qapi_free_NetdevTapOptions(NetdevTapOptions * obj); - -struct NetdevSocketOptions -{ -    bool has_fd; -    char * fd; -    bool has_listen; -    char * listen; -    bool has_connect; -    char * connect; -    bool has_mcast; -    char * mcast; -    bool has_localaddr; -    char * localaddr; -    bool has_udp; -    char * udp; -}; - -void qapi_free_NetdevSocketOptionsList(NetdevSocketOptionsList * obj); -void qapi_free_NetdevSocketOptions(NetdevSocketOptions * obj); - -struct NetdevVdeOptions -{ -    bool has_sock; -    char * sock; -    bool has_port; -    uint16_t port; -    bool has_group; -    char * group; -    bool has_mode; -    uint16_t mode; -}; - -void qapi_free_NetdevVdeOptionsList(NetdevVdeOptionsList * obj); -void qapi_free_NetdevVdeOptions(NetdevVdeOptions * obj); - -struct NetdevDumpOptions -{ -    bool has_len; -    uint64_t len; -    bool has_file; -    char * file; -}; - -void qapi_free_NetdevDumpOptionsList(NetdevDumpOptionsList * obj); -void qapi_free_NetdevDumpOptions(NetdevDumpOptions * obj); - -struct NetdevBridgeOptions -{ -    bool has_br; -    char * br; -    bool has_helper; -    char * helper; -}; - -void qapi_free_NetdevBridgeOptionsList(NetdevBridgeOptionsList * obj); -void qapi_free_NetdevBridgeOptions(NetdevBridgeOptions * obj); - -struct NetdevHubPortOptions -{ -    int32_t hubid; -}; - -void qapi_free_NetdevHubPortOptionsList(NetdevHubPortOptionsList * obj); -void qapi_free_NetdevHubPortOptions(NetdevHubPortOptions * obj); - -struct NetClientOptions -{ -    NetClientOptionsKind kind; -    union { -        void *data; -        NetdevNoneOptions * none; -        NetLegacyNicOptions * nic; -        NetdevUserOptions * user; -        NetdevTapOptions * tap; -        NetdevSocketOptions * socket; -        NetdevVdeOptions * vde; -        NetdevDumpOptions * dump; -        NetdevBridgeOptions * bridge; -        NetdevHubPortOptions * hubport; -    }; -}; -void qapi_free_NetClientOptionsList(NetClientOptionsList * obj); -void qapi_free_NetClientOptions(NetClientOptions * obj); - -struct NetLegacy -{ -    bool has_vlan; -    int32_t vlan; -    bool has_id; -    char * id; -    bool has_name; -    char * name; -    NetClientOptions * opts; -}; - -void qapi_free_NetLegacyList(NetLegacyList * obj); -void qapi_free_NetLegacy(NetLegacy * obj); - -struct Netdev -{ -    char * id; -    NetClientOptions * opts; -}; - -void qapi_free_NetdevList(NetdevList * obj); -void qapi_free_Netdev(Netdev * obj); - -struct InetSocketAddress -{ -    char * host; -    char * port; -    bool has_to; -    uint16_t to; -    bool has_ipv4; -    bool ipv4; -    bool has_ipv6; -    bool ipv6; -}; - -void qapi_free_InetSocketAddressList(InetSocketAddressList * obj); -void qapi_free_InetSocketAddress(InetSocketAddress * obj); - -struct UnixSocketAddress -{ -    char * path; -}; - -void qapi_free_UnixSocketAddressList(UnixSocketAddressList * obj); -void qapi_free_UnixSocketAddress(UnixSocketAddress * obj); - -struct SocketAddress -{ -    SocketAddressKind kind; -    union { -        void *data; -        InetSocketAddress * inet; -        UnixSocketAddress * q_unix; -        String * fd; -    }; -}; -void qapi_free_SocketAddressList(SocketAddressList * obj); -void qapi_free_SocketAddress(SocketAddress * obj); - -struct MachineInfo -{ -    char * name; -    bool has_alias; -    char * alias; -    bool has_is_default; -    bool is_default; -    int64_t cpu_max; -}; - -void qapi_free_MachineInfoList(MachineInfoList * obj); -void qapi_free_MachineInfo(MachineInfo * obj); - -struct CpuDefinitionInfo -{ -    char * name; -}; - -void qapi_free_CpuDefinitionInfoList(CpuDefinitionInfoList * obj); -void qapi_free_CpuDefinitionInfo(CpuDefinitionInfo * obj); - -struct AddfdInfo -{ -    int64_t fdset_id; -    int64_t fd; -}; - -void qapi_free_AddfdInfoList(AddfdInfoList * obj); -void qapi_free_AddfdInfo(AddfdInfo * obj); - -struct FdsetFdInfo -{ -    int64_t fd; -    bool has_opaque; -    char * opaque; -}; - -void qapi_free_FdsetFdInfoList(FdsetFdInfoList * obj); -void qapi_free_FdsetFdInfo(FdsetFdInfo * obj); - -struct FdsetInfo -{ -    int64_t fdset_id; -    FdsetFdInfoList * fds; -}; - -void qapi_free_FdsetInfoList(FdsetInfoList * obj); -void qapi_free_FdsetInfo(FdsetInfo * obj); - -struct TargetInfo -{ -    char * arch; -}; - -void qapi_free_TargetInfoList(TargetInfoList * obj); -void qapi_free_TargetInfo(TargetInfo * obj); - -void qapi_free_QKeyCodeList(QKeyCodeList * obj); - -struct KeyValue -{ -    KeyValueKind kind; -    union { -        void *data; -        int64_t number; -        QKeyCode qcode; -    }; -}; -void qapi_free_KeyValueList(KeyValueList * obj); -void qapi_free_KeyValue(KeyValue * obj); - -struct ChardevFile -{ -    bool has_in; -    char * in; -    char * out; -}; - -void qapi_free_ChardevFileList(ChardevFileList * obj); -void qapi_free_ChardevFile(ChardevFile * obj); - -struct ChardevHostdev -{ -    char * device; -}; - -void qapi_free_ChardevHostdevList(ChardevHostdevList * obj); -void qapi_free_ChardevHostdev(ChardevHostdev * obj); - -struct ChardevSocket -{ -    SocketAddress * addr; -    bool has_server; -    bool server; -    bool has_wait; -    bool wait; -    bool has_nodelay; -    bool nodelay; -    bool has_telnet; -    bool telnet; -}; - -void qapi_free_ChardevSocketList(ChardevSocketList * obj); -void qapi_free_ChardevSocket(ChardevSocket * obj); - -struct ChardevUdp -{ -    SocketAddress * remote; -    bool has_local; -    SocketAddress * local; -}; - -void qapi_free_ChardevUdpList(ChardevUdpList * obj); -void qapi_free_ChardevUdp(ChardevUdp * obj); - -struct ChardevMux -{ -    char * chardev; -}; - -void qapi_free_ChardevMuxList(ChardevMuxList * obj); -void qapi_free_ChardevMux(ChardevMux * obj); - -struct ChardevStdio -{ -    bool has_signal; -    bool signal; -}; - -void qapi_free_ChardevStdioList(ChardevStdioList * obj); -void qapi_free_ChardevStdio(ChardevStdio * obj); - -struct ChardevSpiceChannel -{ -    char * type; -}; - -void qapi_free_ChardevSpiceChannelList(ChardevSpiceChannelList * obj); -void qapi_free_ChardevSpiceChannel(ChardevSpiceChannel * obj); - -struct ChardevSpicePort -{ -    char * fqdn; -}; - -void qapi_free_ChardevSpicePortList(ChardevSpicePortList * obj); -void qapi_free_ChardevSpicePort(ChardevSpicePort * obj); - -struct ChardevVC -{ -    bool has_width; -    int64_t width; -    bool has_height; -    int64_t height; -    bool has_cols; -    int64_t cols; -    bool has_rows; -    int64_t rows; -}; - -void qapi_free_ChardevVCList(ChardevVCList * obj); -void qapi_free_ChardevVC(ChardevVC * obj); - -struct ChardevMemory -{ -    bool has_size; -    int64_t size; -}; - -void qapi_free_ChardevMemoryList(ChardevMemoryList * obj); -void qapi_free_ChardevMemory(ChardevMemory * obj); - -struct ChardevDummy -{ -}; - -void qapi_free_ChardevDummyList(ChardevDummyList * obj); -void qapi_free_ChardevDummy(ChardevDummy * obj); - -struct ChardevBackend -{ -    ChardevBackendKind kind; -    union { -        void *data; -        ChardevFile * file; -        ChardevHostdev * serial; -        ChardevHostdev * parallel; -        ChardevHostdev * pipe; -        ChardevSocket * socket; -        ChardevUdp * udp; -        ChardevDummy * pty; -        ChardevDummy * null; -        ChardevMux * mux; -        ChardevDummy * msmouse; -        ChardevDummy * braille; -        ChardevStdio * stdio; -        ChardevDummy * console; -        ChardevSpiceChannel * spicevmc; -        ChardevSpicePort * spiceport; -        ChardevVC * vc; -        ChardevMemory * memory; -    }; -}; -void qapi_free_ChardevBackendList(ChardevBackendList * obj); -void qapi_free_ChardevBackend(ChardevBackend * obj); - -struct ChardevReturn -{ -    bool has_pty; -    char * pty; -}; - -void qapi_free_ChardevReturnList(ChardevReturnList * obj); -void qapi_free_ChardevReturn(ChardevReturn * obj); - -void qapi_free_TpmModelList(TpmModelList * obj); - -void qapi_free_TpmTypeList(TpmTypeList * obj); - -struct TPMPassthroughOptions -{ -    bool has_path; -    char * path; -    bool has_cancel_path; -    char * cancel_path; -}; - -void qapi_free_TPMPassthroughOptionsList(TPMPassthroughOptionsList * obj); -void qapi_free_TPMPassthroughOptions(TPMPassthroughOptions * obj); - -struct TpmTypeOptions -{ -    TpmTypeOptionsKind kind; -    union { -        void *data; -        TPMPassthroughOptions * passthrough; -    }; -}; -void qapi_free_TpmTypeOptionsList(TpmTypeOptionsList * obj); -void qapi_free_TpmTypeOptions(TpmTypeOptions * obj); - -struct TPMInfo -{ -    char * id; -    TpmModel model; -    TpmTypeOptions * options; -}; - -void qapi_free_TPMInfoList(TPMInfoList * obj); -void qapi_free_TPMInfo(TPMInfo * obj); - -struct AcpiTableOptions -{ -    bool has_sig; -    char * sig; -    bool has_rev; -    uint8_t rev; -    bool has_oem_id; -    char * oem_id; -    bool has_oem_table_id; -    char * oem_table_id; -    bool has_oem_rev; -    uint32_t oem_rev; -    bool has_asl_compiler_id; -    char * asl_compiler_id; -    bool has_asl_compiler_rev; -    uint32_t asl_compiler_rev; -    bool has_file; -    char * file; -    bool has_data; -    char * data; -}; - -void qapi_free_AcpiTableOptionsList(AcpiTableOptionsList * obj); -void qapi_free_AcpiTableOptions(AcpiTableOptions * obj); - -void qapi_free_CommandLineParameterTypeList(CommandLineParameterTypeList * obj); - -struct CommandLineParameterInfo -{ -    char * name; -    CommandLineParameterType type; -    bool has_help; -    char * help; -}; - -void qapi_free_CommandLineParameterInfoList(CommandLineParameterInfoList * obj); -void qapi_free_CommandLineParameterInfo(CommandLineParameterInfo * obj); - -struct CommandLineOptionInfo -{ -    char * option; -    CommandLineParameterInfoList * parameters; -}; - -void qapi_free_CommandLineOptionInfoList(CommandLineOptionInfoList * obj); -void qapi_free_CommandLineOptionInfo(CommandLineOptionInfo * obj); - -void qapi_free_X86CPURegister32List(X86CPURegister32List * obj); - -struct X86CPUFeatureWordInfo -{ -    int64_t cpuid_input_eax; -    bool has_cpuid_input_ecx; -    int64_t cpuid_input_ecx; -    X86CPURegister32 cpuid_register; -    int64_t features; -}; - -void qapi_free_X86CPUFeatureWordInfoList(X86CPUFeatureWordInfoList * obj); -void qapi_free_X86CPUFeatureWordInfo(X86CPUFeatureWordInfo * obj); - -void qapi_free_RxStateList(RxStateList * obj); - -struct RxFilterInfo -{ -    char * name; -    bool promiscuous; -    RxState multicast; -    RxState unicast; -    bool broadcast_allowed; -    bool multicast_overflow; -    bool unicast_overflow; -    char * main_mac; -    intList * vlan_table; -    strList * unicast_table; -    strList * multicast_table; -}; - -void qapi_free_RxFilterInfoList(RxFilterInfoList * obj); -void qapi_free_RxFilterInfo(RxFilterInfo * obj); - -#endif diff --git a/contrib/qemu/qemu-coroutine-lock.c b/contrib/qemu/qemu-coroutine-lock.c deleted file mode 100644 index d9fea4989d4..00000000000 --- a/contrib/qemu/qemu-coroutine-lock.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * coroutine queues and locks - * - * Copyright (c) 2011 Kevin Wolf <kwolf@redhat.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "qemu-common.h" -#include "block/coroutine.h" -#include "block/coroutine_int.h" -#include "qemu/queue.h" -#include "trace.h" - -void qemu_co_queue_init(CoQueue *queue) -{ -    QTAILQ_INIT(&queue->entries); -} - -void coroutine_fn qemu_co_queue_wait(CoQueue *queue) -{ -    Coroutine *self = qemu_coroutine_self(); -    QTAILQ_INSERT_TAIL(&queue->entries, self, co_queue_next); -    qemu_coroutine_yield(); -    assert(qemu_in_coroutine()); -} - -void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue) -{ -    Coroutine *self = qemu_coroutine_self(); -    QTAILQ_INSERT_HEAD(&queue->entries, self, co_queue_next); -    qemu_coroutine_yield(); -    assert(qemu_in_coroutine()); -} - -/** - * qemu_co_queue_run_restart: - * - * Enter each coroutine that was previously marked for restart by - * qemu_co_queue_next() or qemu_co_queue_restart_all().  This function is - * invoked by the core coroutine code when the current coroutine yields or - * terminates. - */ -void qemu_co_queue_run_restart(Coroutine *co) -{ -    Coroutine *next; - -    trace_qemu_co_queue_run_restart(co); -    while ((next = QTAILQ_FIRST(&co->co_queue_wakeup))) { -        QTAILQ_REMOVE(&co->co_queue_wakeup, next, co_queue_next); -        qemu_coroutine_enter(next, NULL); -    } -} - -static bool qemu_co_queue_do_restart(CoQueue *queue, bool single) -{ -    Coroutine *self = qemu_coroutine_self(); -    Coroutine *next; - -    if (QTAILQ_EMPTY(&queue->entries)) { -        return false; -    } - -    while ((next = QTAILQ_FIRST(&queue->entries)) != NULL) { -        QTAILQ_REMOVE(&queue->entries, next, co_queue_next); -        QTAILQ_INSERT_TAIL(&self->co_queue_wakeup, next, co_queue_next); -        trace_qemu_co_queue_next(next); -        if (single) { -            break; -        } -    } -    return true; -} - -bool qemu_co_queue_next(CoQueue *queue) -{ -    return qemu_co_queue_do_restart(queue, true); -} - -void qemu_co_queue_restart_all(CoQueue *queue) -{ -    qemu_co_queue_do_restart(queue, false); -} - -bool qemu_co_queue_empty(CoQueue *queue) -{ -    return (QTAILQ_FIRST(&queue->entries) == NULL); -} - -void qemu_co_mutex_init(CoMutex *mutex) -{ -    memset(mutex, 0, sizeof(*mutex)); -    qemu_co_queue_init(&mutex->queue); -} - -void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex) -{ -    Coroutine *self = qemu_coroutine_self(); - -    trace_qemu_co_mutex_lock_entry(mutex, self); - -    while (mutex->locked) { -        qemu_co_queue_wait(&mutex->queue); -    } - -    mutex->locked = true; - -    trace_qemu_co_mutex_lock_return(mutex, self); -} - -void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex) -{ -    Coroutine *self = qemu_coroutine_self(); - -    trace_qemu_co_mutex_unlock_entry(mutex, self); - -    assert(mutex->locked == true); -    assert(qemu_in_coroutine()); - -    mutex->locked = false; -    qemu_co_queue_next(&mutex->queue); - -    trace_qemu_co_mutex_unlock_return(mutex, self); -} - -void qemu_co_rwlock_init(CoRwlock *lock) -{ -    memset(lock, 0, sizeof(*lock)); -    qemu_co_queue_init(&lock->queue); -} - -void qemu_co_rwlock_rdlock(CoRwlock *lock) -{ -    while (lock->writer) { -        qemu_co_queue_wait(&lock->queue); -    } -    lock->reader++; -} - -void qemu_co_rwlock_unlock(CoRwlock *lock) -{ -    assert(qemu_in_coroutine()); -    if (lock->writer) { -        lock->writer = false; -        qemu_co_queue_restart_all(&lock->queue); -    } else { -        lock->reader--; -        assert(lock->reader >= 0); -        /* Wakeup only one waiting writer */ -        if (!lock->reader) { -            qemu_co_queue_next(&lock->queue); -        } -    } -} - -void qemu_co_rwlock_wrlock(CoRwlock *lock) -{ -    while (lock->writer || lock->reader) { -        qemu_co_queue_wait(&lock->queue); -    } -    lock->writer = true; -} diff --git a/contrib/qemu/qemu-coroutine-sleep.c b/contrib/qemu/qemu-coroutine-sleep.c deleted file mode 100644 index 169ce5ccc92..00000000000 --- a/contrib/qemu/qemu-coroutine-sleep.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * QEMU coroutine sleep - * - * Copyright IBM, Corp. 2011 - * - * Authors: - *  Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "block/coroutine.h" -#include "qemu/timer.h" - -typedef struct CoSleepCB { -    QEMUTimer *ts; -    Coroutine *co; -} CoSleepCB; - -static void co_sleep_cb(void *opaque) -{ -    CoSleepCB *sleep_cb = opaque; - -    qemu_coroutine_enter(sleep_cb->co, NULL); -} - -void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns) -{ -    CoSleepCB sleep_cb = { -        .co = qemu_coroutine_self(), -    }; -    sleep_cb.ts = qemu_new_timer(clock, SCALE_NS, co_sleep_cb, &sleep_cb); -    qemu_mod_timer(sleep_cb.ts, qemu_get_clock_ns(clock) + ns); -    qemu_coroutine_yield(); -    qemu_del_timer(sleep_cb.ts); -    qemu_free_timer(sleep_cb.ts); -} diff --git a/contrib/qemu/qemu-coroutine.c b/contrib/qemu/qemu-coroutine.c deleted file mode 100644 index 5e19307eeda..00000000000 --- a/contrib/qemu/qemu-coroutine.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * QEMU coroutines - * - * Copyright IBM, Corp. 2011 - * - * Authors: - *  Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com> - *  Kevin Wolf         <kwolf@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "trace.h" -#include "qemu-common.h" -#include "qemu/thread.h" -#include "block/coroutine.h" -#include "block/coroutine_int.h" - -enum { -    /* Maximum free pool size prevents holding too many freed coroutines */ -    POOL_MAX_SIZE = 0, -}; - -/** Free list to speed up creation */ -static QemuMutex pool_lock; -static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool); -static unsigned int pool_size; - -Coroutine *qemu_coroutine_create(CoroutineEntry *entry) -{ -    Coroutine *co; - -    qemu_mutex_lock(&pool_lock); -    co = QSLIST_FIRST(&pool); -    if (co) { -        QSLIST_REMOVE_HEAD(&pool, pool_next); -        pool_size--; -    } -    qemu_mutex_unlock(&pool_lock); - -    if (!co) { -        co = qemu_coroutine_new(); -    } - -    co->entry = entry; -    QTAILQ_INIT(&co->co_queue_wakeup); -    return co; -} - -static void coroutine_delete(Coroutine *co) -{ -    qemu_mutex_lock(&pool_lock); -    if (pool_size < POOL_MAX_SIZE) { -        QSLIST_INSERT_HEAD(&pool, co, pool_next); -        co->caller = NULL; -        pool_size++; -        qemu_mutex_unlock(&pool_lock); -        return; -    } -    qemu_mutex_unlock(&pool_lock); - -    qemu_coroutine_delete(co); -} - -static void __attribute__((constructor)) coroutine_pool_init(void) -{ -    qemu_mutex_init(&pool_lock); -} - -static void __attribute__((destructor)) coroutine_pool_cleanup(void) -{ -    Coroutine *co; -    Coroutine *tmp; - -    QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) { -        QSLIST_REMOVE_HEAD(&pool, pool_next); -        qemu_coroutine_delete(co); -    } - -    qemu_mutex_destroy(&pool_lock); -} - -static void coroutine_swap(Coroutine *from, Coroutine *to) -{ -    CoroutineAction ret; - -    ret = qemu_coroutine_switch(from, to, COROUTINE_YIELD); - -    qemu_co_queue_run_restart(to); - -    switch (ret) { -    case COROUTINE_YIELD: -        return; -    case COROUTINE_TERMINATE: -        trace_qemu_coroutine_terminate(to); -        coroutine_delete(to); -        return; -    default: -        abort(); -    } -} - -void qemu_coroutine_enter(Coroutine *co, void *opaque) -{ -    Coroutine *self = qemu_coroutine_self(); - -    trace_qemu_coroutine_enter(self, co, opaque); - -    if (co->caller) { -        fprintf(stderr, "Co-routine re-entered recursively\n"); -        abort(); -    } - -    co->caller = self; -    co->entry_arg = opaque; -    coroutine_swap(self, co); -} - -void coroutine_fn qemu_coroutine_yield(void) -{ -    Coroutine *self = qemu_coroutine_self(); -    Coroutine *to = self->caller; - -    trace_qemu_coroutine_yield(self, to); - -    if (!to) { -        fprintf(stderr, "Co-routine is yielding to no one\n"); -        abort(); -    } - -    self->caller = NULL; -    coroutine_swap(self, to); -} diff --git a/contrib/qemu/qmp-commands.h b/contrib/qemu/qmp-commands.h deleted file mode 100644 index fcc0ff0f7f0..00000000000 --- a/contrib/qemu/qmp-commands.h +++ /dev/null @@ -1,204 +0,0 @@ -/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */ - -/* - * schema-defined QAPI function prototypes - * - * Copyright IBM, Corp. 2011 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef QMP_COMMANDS_H -#define QMP_COMMANDS_H - -#include "qapi-types.h" -#include "qapi/qmp/qdict.h" -#include "qapi/error.h" - -void qmp_add_client(const char * protocol, const char * fdname, bool has_skipauth, bool skipauth, bool has_tls, bool tls, Error **errp); -int qmp_marshal_input_add_client(Monitor *mon, const QDict *qdict, QObject **ret); -NameInfo * qmp_query_name(Error **errp); -int qmp_marshal_input_query_name(Monitor *mon, const QDict *qdict, QObject **ret); -VersionInfo * qmp_query_version(Error **errp); -int qmp_marshal_input_query_version(Monitor *mon, const QDict *qdict, QObject **ret); -KvmInfo * qmp_query_kvm(Error **errp); -int qmp_marshal_input_query_kvm(Monitor *mon, const QDict *qdict, QObject **ret); -StatusInfo * qmp_query_status(Error **errp); -int qmp_marshal_input_query_status(Monitor *mon, const QDict *qdict, QObject **ret); -UuidInfo * qmp_query_uuid(Error **errp); -int qmp_marshal_input_query_uuid(Monitor *mon, const QDict *qdict, QObject **ret); -ChardevInfoList * qmp_query_chardev(Error **errp); -int qmp_marshal_input_query_chardev(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_ringbuf_write(const char * device, const char * data, bool has_format, DataFormat format, Error **errp); -int qmp_marshal_input_ringbuf_write(Monitor *mon, const QDict *qdict, QObject **ret); -char * qmp_ringbuf_read(const char * device, int64_t size, bool has_format, DataFormat format, Error **errp); -int qmp_marshal_input_ringbuf_read(Monitor *mon, const QDict *qdict, QObject **ret); -CommandInfoList * qmp_query_commands(Error **errp); -int qmp_marshal_input_query_commands(Monitor *mon, const QDict *qdict, QObject **ret); -EventInfoList * qmp_query_events(Error **errp); -int qmp_marshal_input_query_events(Monitor *mon, const QDict *qdict, QObject **ret); -MigrationInfo * qmp_query_migrate(Error **errp); -int qmp_marshal_input_query_migrate(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_migrate_set_capabilities(MigrationCapabilityStatusList * capabilities, Error **errp); -int qmp_marshal_input_migrate_set_capabilities(Monitor *mon, const QDict *qdict, QObject **ret); -MigrationCapabilityStatusList * qmp_query_migrate_capabilities(Error **errp); -int qmp_marshal_input_query_migrate_capabilities(Monitor *mon, const QDict *qdict, QObject **ret); -MouseInfoList * qmp_query_mice(Error **errp); -int qmp_marshal_input_query_mice(Monitor *mon, const QDict *qdict, QObject **ret); -CpuInfoList * qmp_query_cpus(Error **errp); -int qmp_marshal_input_query_cpus(Monitor *mon, const QDict *qdict, QObject **ret); -BlockInfoList * qmp_query_block(Error **errp); -int qmp_marshal_input_query_block(Monitor *mon, const QDict *qdict, QObject **ret); -BlockStatsList * qmp_query_blockstats(Error **errp); -int qmp_marshal_input_query_blockstats(Monitor *mon, const QDict *qdict, QObject **ret); -VncInfo * qmp_query_vnc(Error **errp); -int qmp_marshal_input_query_vnc(Monitor *mon, const QDict *qdict, QObject **ret); -SpiceInfo * qmp_query_spice(Error **errp); -int qmp_marshal_input_query_spice(Monitor *mon, const QDict *qdict, QObject **ret); -BalloonInfo * qmp_query_balloon(Error **errp); -int qmp_marshal_input_query_balloon(Monitor *mon, const QDict *qdict, QObject **ret); -PciInfoList * qmp_query_pci(Error **errp); -int qmp_marshal_input_query_pci(Monitor *mon, const QDict *qdict, QObject **ret); -BlockJobInfoList * qmp_query_block_jobs(Error **errp); -int qmp_marshal_input_query_block_jobs(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_quit(Error **errp); -int qmp_marshal_input_quit(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_stop(Error **errp); -int qmp_marshal_input_stop(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_system_reset(Error **errp); -int qmp_marshal_input_system_reset(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_system_powerdown(Error **errp); -int qmp_marshal_input_system_powerdown(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_cpu(int64_t index, Error **errp); -int qmp_marshal_input_cpu(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_cpu_add(int64_t id, Error **errp); -int qmp_marshal_input_cpu_add(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_memsave(int64_t val, int64_t size, const char * filename, bool has_cpu_index, int64_t cpu_index, Error **errp); -int qmp_marshal_input_memsave(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_pmemsave(int64_t val, int64_t size, const char * filename, Error **errp); -int qmp_marshal_input_pmemsave(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_cont(Error **errp); -int qmp_marshal_input_cont(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_system_wakeup(Error **errp); -int qmp_marshal_input_system_wakeup(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_inject_nmi(Error **errp); -int qmp_marshal_input_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_set_link(const char * name, bool up, Error **errp); -int qmp_marshal_input_set_link(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_passwd(const char * device, const char * password, Error **errp); -int qmp_marshal_input_block_passwd(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_balloon(int64_t value, Error **errp); -int qmp_marshal_input_balloon(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_resize(const char * device, int64_t size, Error **errp); -int qmp_marshal_input_block_resize(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_transaction(TransactionActionList * actions, Error **errp); -int qmp_marshal_input_transaction(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_blockdev_snapshot_sync(const char * device, const char * snapshot_file, bool has_format, const char * format, bool has_mode, NewImageMode mode, Error **errp); -int qmp_marshal_input_blockdev_snapshot_sync(Monitor *mon, const QDict *qdict, QObject **ret); -char * qmp_human_monitor_command(const char * command_line, bool has_cpu_index, int64_t cpu_index, Error **errp); -int qmp_marshal_input_human_monitor_command(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_commit(const char * device, bool has_base, const char * base, const char * top, bool has_speed, int64_t speed, Error **errp); -int qmp_marshal_input_block_commit(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_drive_backup(const char * device, const char * target, bool has_format, const char * format, MirrorSyncMode sync, bool has_mode, NewImageMode mode, bool has_speed, int64_t speed, bool has_on_source_error, BlockdevOnError on_source_error, bool has_on_target_error, BlockdevOnError on_target_error, Error **errp); -int qmp_marshal_input_drive_backup(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_drive_mirror(const char * device, const char * target, bool has_format, const char * format, MirrorSyncMode sync, bool has_mode, NewImageMode mode, bool has_speed, int64_t speed, bool has_granularity, uint32_t granularity, bool has_buf_size, int64_t buf_size, bool has_on_source_error, BlockdevOnError on_source_error, bool has_on_target_error, BlockdevOnError on_target_error, Error **errp); -int qmp_marshal_input_drive_mirror(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_migrate_cancel(Error **errp); -int qmp_marshal_input_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_migrate_set_downtime(double value, Error **errp); -int qmp_marshal_input_migrate_set_downtime(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_migrate_set_speed(int64_t value, Error **errp); -int qmp_marshal_input_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_migrate_set_cache_size(int64_t value, Error **errp); -int qmp_marshal_input_migrate_set_cache_size(Monitor *mon, const QDict *qdict, QObject **ret); -int64_t qmp_query_migrate_cache_size(Error **errp); -int qmp_marshal_input_query_migrate_cache_size(Monitor *mon, const QDict *qdict, QObject **ret); -ObjectPropertyInfoList * qmp_qom_list(const char * path, Error **errp); -int qmp_marshal_input_qom_list(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_set_password(const char * protocol, const char * password, bool has_connected, const char * connected, Error **errp); -int qmp_marshal_input_set_password(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_expire_password(const char * protocol, const char * time, Error **errp); -int qmp_marshal_input_expire_password(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_eject(const char * device, bool has_force, bool force, Error **errp); -int qmp_marshal_input_eject(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_change_vnc_password(const char * password, Error **errp); -int qmp_marshal_input_change_vnc_password(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_change(const char * device, const char * target, bool has_arg, const char * arg, Error **errp); -int qmp_marshal_input_change(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_set_io_throttle(const char * device, int64_t bps, int64_t bps_rd, int64_t bps_wr, int64_t iops, int64_t iops_rd, int64_t iops_wr, Error **errp); -int qmp_marshal_input_block_set_io_throttle(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_stream(const char * device, bool has_base, const char * base, bool has_speed, int64_t speed, bool has_on_error, BlockdevOnError on_error, Error **errp); -int qmp_marshal_input_block_stream(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_job_set_speed(const char * device, int64_t speed, Error **errp); -int qmp_marshal_input_block_job_set_speed(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_job_cancel(const char * device, bool has_force, bool force, Error **errp); -int qmp_marshal_input_block_job_cancel(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_job_pause(const char * device, Error **errp); -int qmp_marshal_input_block_job_pause(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_job_resume(const char * device, Error **errp); -int qmp_marshal_input_block_job_resume(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_block_job_complete(const char * device, Error **errp); -int qmp_marshal_input_block_job_complete(Monitor *mon, const QDict *qdict, QObject **ret); -ObjectTypeInfoList * qmp_qom_list_types(bool has_implements, const char * implements, bool has_abstract, bool abstract, Error **errp); -int qmp_marshal_input_qom_list_types(Monitor *mon, const QDict *qdict, QObject **ret); -DevicePropertyInfoList * qmp_device_list_properties(const char * typename, Error **errp); -int qmp_marshal_input_device_list_properties(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_migrate(const char * uri, bool has_blk, bool blk, bool has_inc, bool inc, bool has_detach, bool detach, Error **errp); -int qmp_marshal_input_migrate(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_xen_save_devices_state(const char * filename, Error **errp); -int qmp_marshal_input_xen_save_devices_state(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_xen_set_global_dirty_log(bool enable, Error **errp); -int qmp_marshal_input_xen_set_global_dirty_log(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_device_del(const char * id, Error **errp); -int qmp_marshal_input_device_del(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_dump_guest_memory(bool paging, const char * protocol, bool has_begin, int64_t begin, bool has_length, int64_t length, Error **errp); -int qmp_marshal_input_dump_guest_memory(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_netdev_del(const char * id, Error **errp); -int qmp_marshal_input_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_getfd(const char * fdname, Error **errp); -int qmp_marshal_input_getfd(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_closefd(const char * fdname, Error **errp); -int qmp_marshal_input_closefd(Monitor *mon, const QDict *qdict, QObject **ret); -MachineInfoList * qmp_query_machines(Error **errp); -int qmp_marshal_input_query_machines(Monitor *mon, const QDict *qdict, QObject **ret); -CpuDefinitionInfoList * qmp_query_cpu_definitions(Error **errp); -int qmp_marshal_input_query_cpu_definitions(Monitor *mon, const QDict *qdict, QObject **ret); -AddfdInfo * qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque, const char * opaque, Error **errp); -int qmp_marshal_input_add_fd(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp); -int qmp_marshal_input_remove_fd(Monitor *mon, const QDict *qdict, QObject **ret); -FdsetInfoList * qmp_query_fdsets(Error **errp); -int qmp_marshal_input_query_fdsets(Monitor *mon, const QDict *qdict, QObject **ret); -TargetInfo * qmp_query_target(Error **errp); -int qmp_marshal_input_query_target(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_send_key(KeyValueList * keys, bool has_hold_time, int64_t hold_time, Error **errp); -int qmp_marshal_input_send_key(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_screendump(const char * filename, Error **errp); -int qmp_marshal_input_screendump(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_nbd_server_start(SocketAddress * addr, Error **errp); -int qmp_marshal_input_nbd_server_start(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_nbd_server_add(const char * device, bool has_writable, bool writable, Error **errp); -int qmp_marshal_input_nbd_server_add(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_nbd_server_stop(Error **errp); -int qmp_marshal_input_nbd_server_stop(Monitor *mon, const QDict *qdict, QObject **ret); -ChardevReturn * qmp_chardev_add(const char * id, ChardevBackend * backend, Error **errp); -int qmp_marshal_input_chardev_add(Monitor *mon, const QDict *qdict, QObject **ret); -void qmp_chardev_remove(const char * id, Error **errp); -int qmp_marshal_input_chardev_remove(Monitor *mon, const QDict *qdict, QObject **ret); -TpmModelList * qmp_query_tpm_models(Error **errp); -int qmp_marshal_input_query_tpm_models(Monitor *mon, const QDict *qdict, QObject **ret); -TpmTypeList * qmp_query_tpm_types(Error **errp); -int qmp_marshal_input_query_tpm_types(Monitor *mon, const QDict *qdict, QObject **ret); -TPMInfoList * qmp_query_tpm(Error **errp); -int qmp_marshal_input_query_tpm(Monitor *mon, const QDict *qdict, QObject **ret); -CommandLineOptionInfoList * qmp_query_command_line_options(bool has_option, const char * option, Error **errp); -int qmp_marshal_input_query_command_line_options(Monitor *mon, const QDict *qdict, QObject **ret); -RxFilterInfoList * qmp_query_rx_filter(bool has_name, const char * name, Error **errp); -int qmp_marshal_input_query_rx_filter(Monitor *mon, const QDict *qdict, QObject **ret); - -#endif diff --git a/contrib/qemu/qobject/json-lexer.c b/contrib/qemu/qobject/json-lexer.c deleted file mode 100644 index 440df60392b..00000000000 --- a/contrib/qemu/qobject/json-lexer.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * JSON lexer - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qint.h" -#include "qemu-common.h" -#include "qapi/qmp/json-lexer.h" - -#define MAX_TOKEN_SIZE (64ULL << 20) - -/* - * \"([^\\\"]|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*\" - * '([^\\']|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*' - * 0|([1-9][0-9]*(.[0-9]+)?([eE]([-+])?[0-9]+)) - * [{}\[\],:] - * [a-z]+ - * - */ - -enum json_lexer_state { -    IN_ERROR = 0, -    IN_DQ_UCODE3, -    IN_DQ_UCODE2, -    IN_DQ_UCODE1, -    IN_DQ_UCODE0, -    IN_DQ_STRING_ESCAPE, -    IN_DQ_STRING, -    IN_SQ_UCODE3, -    IN_SQ_UCODE2, -    IN_SQ_UCODE1, -    IN_SQ_UCODE0, -    IN_SQ_STRING_ESCAPE, -    IN_SQ_STRING, -    IN_ZERO, -    IN_DIGITS, -    IN_DIGIT, -    IN_EXP_E, -    IN_MANTISSA, -    IN_MANTISSA_DIGITS, -    IN_NONZERO_NUMBER, -    IN_NEG_NONZERO_NUMBER, -    IN_KEYWORD, -    IN_ESCAPE, -    IN_ESCAPE_L, -    IN_ESCAPE_LL, -    IN_ESCAPE_I, -    IN_ESCAPE_I6, -    IN_ESCAPE_I64, -    IN_WHITESPACE, -    IN_START, -}; - -#define TERMINAL(state) [0 ... 0x7F] = (state) - -/* Return whether TERMINAL is a terminal state and the transition to it -   from OLD_STATE required lookahead.  This happens whenever the table -   below uses the TERMINAL macro.  */ -#define TERMINAL_NEEDED_LOOKAHEAD(old_state, terminal) \ -            (json_lexer[(old_state)][0] == (terminal)) - -static const uint8_t json_lexer[][256] =  { -    /* double quote string */ -    [IN_DQ_UCODE3] = { -        ['0' ... '9'] = IN_DQ_STRING, -        ['a' ... 'f'] = IN_DQ_STRING, -        ['A' ... 'F'] = IN_DQ_STRING, -    }, -    [IN_DQ_UCODE2] = { -        ['0' ... '9'] = IN_DQ_UCODE3, -        ['a' ... 'f'] = IN_DQ_UCODE3, -        ['A' ... 'F'] = IN_DQ_UCODE3, -    }, -    [IN_DQ_UCODE1] = { -        ['0' ... '9'] = IN_DQ_UCODE2, -        ['a' ... 'f'] = IN_DQ_UCODE2, -        ['A' ... 'F'] = IN_DQ_UCODE2, -    }, -    [IN_DQ_UCODE0] = { -        ['0' ... '9'] = IN_DQ_UCODE1, -        ['a' ... 'f'] = IN_DQ_UCODE1, -        ['A' ... 'F'] = IN_DQ_UCODE1, -    }, -    [IN_DQ_STRING_ESCAPE] = { -        ['b'] = IN_DQ_STRING, -        ['f'] =  IN_DQ_STRING, -        ['n'] =  IN_DQ_STRING, -        ['r'] =  IN_DQ_STRING, -        ['t'] =  IN_DQ_STRING, -        ['/'] = IN_DQ_STRING, -        ['\\'] = IN_DQ_STRING, -        ['\''] = IN_DQ_STRING, -        ['\"'] = IN_DQ_STRING, -        ['u'] = IN_DQ_UCODE0, -    }, -    [IN_DQ_STRING] = { -        [1 ... 0xBF] = IN_DQ_STRING, -        [0xC2 ... 0xF4] = IN_DQ_STRING, -        ['\\'] = IN_DQ_STRING_ESCAPE, -        ['"'] = JSON_STRING, -    }, - -    /* single quote string */ -    [IN_SQ_UCODE3] = { -        ['0' ... '9'] = IN_SQ_STRING, -        ['a' ... 'f'] = IN_SQ_STRING, -        ['A' ... 'F'] = IN_SQ_STRING, -    }, -    [IN_SQ_UCODE2] = { -        ['0' ... '9'] = IN_SQ_UCODE3, -        ['a' ... 'f'] = IN_SQ_UCODE3, -        ['A' ... 'F'] = IN_SQ_UCODE3, -    }, -    [IN_SQ_UCODE1] = { -        ['0' ... '9'] = IN_SQ_UCODE2, -        ['a' ... 'f'] = IN_SQ_UCODE2, -        ['A' ... 'F'] = IN_SQ_UCODE2, -    }, -    [IN_SQ_UCODE0] = { -        ['0' ... '9'] = IN_SQ_UCODE1, -        ['a' ... 'f'] = IN_SQ_UCODE1, -        ['A' ... 'F'] = IN_SQ_UCODE1, -    }, -    [IN_SQ_STRING_ESCAPE] = { -        ['b'] = IN_SQ_STRING, -        ['f'] =  IN_SQ_STRING, -        ['n'] =  IN_SQ_STRING, -        ['r'] =  IN_SQ_STRING, -        ['t'] =  IN_SQ_STRING, -        ['/'] = IN_DQ_STRING, -        ['\\'] = IN_DQ_STRING, -        ['\''] = IN_SQ_STRING, -        ['\"'] = IN_SQ_STRING, -        ['u'] = IN_SQ_UCODE0, -    }, -    [IN_SQ_STRING] = { -        [1 ... 0xBF] = IN_SQ_STRING, -        [0xC2 ... 0xF4] = IN_SQ_STRING, -        ['\\'] = IN_SQ_STRING_ESCAPE, -        ['\''] = JSON_STRING, -    }, - -    /* Zero */ -    [IN_ZERO] = { -        TERMINAL(JSON_INTEGER), -        ['0' ... '9'] = IN_ERROR, -        ['.'] = IN_MANTISSA, -    }, - -    /* Float */ -    [IN_DIGITS] = { -        TERMINAL(JSON_FLOAT), -        ['0' ... '9'] = IN_DIGITS, -    }, - -    [IN_DIGIT] = { -        ['0' ... '9'] = IN_DIGITS, -    }, - -    [IN_EXP_E] = { -        ['-'] = IN_DIGIT, -        ['+'] = IN_DIGIT, -        ['0' ... '9'] = IN_DIGITS, -    }, - -    [IN_MANTISSA_DIGITS] = { -        TERMINAL(JSON_FLOAT), -        ['0' ... '9'] = IN_MANTISSA_DIGITS, -        ['e'] = IN_EXP_E, -        ['E'] = IN_EXP_E, -    }, - -    [IN_MANTISSA] = { -        ['0' ... '9'] = IN_MANTISSA_DIGITS, -    }, - -    /* Number */ -    [IN_NONZERO_NUMBER] = { -        TERMINAL(JSON_INTEGER), -        ['0' ... '9'] = IN_NONZERO_NUMBER, -        ['e'] = IN_EXP_E, -        ['E'] = IN_EXP_E, -        ['.'] = IN_MANTISSA, -    }, - -    [IN_NEG_NONZERO_NUMBER] = { -        ['0'] = IN_ZERO, -        ['1' ... '9'] = IN_NONZERO_NUMBER, -    }, - -    /* keywords */ -    [IN_KEYWORD] = { -        TERMINAL(JSON_KEYWORD), -        ['a' ... 'z'] = IN_KEYWORD, -    }, - -    /* whitespace */ -    [IN_WHITESPACE] = { -        TERMINAL(JSON_SKIP), -        [' '] = IN_WHITESPACE, -        ['\t'] = IN_WHITESPACE, -        ['\r'] = IN_WHITESPACE, -        ['\n'] = IN_WHITESPACE, -    },         - -    /* escape */ -    [IN_ESCAPE_LL] = { -        ['d'] = JSON_ESCAPE, -    }, - -    [IN_ESCAPE_L] = { -        ['d'] = JSON_ESCAPE, -        ['l'] = IN_ESCAPE_LL, -    }, - -    [IN_ESCAPE_I64] = { -        ['d'] = JSON_ESCAPE, -    }, - -    [IN_ESCAPE_I6] = { -        ['4'] = IN_ESCAPE_I64, -    }, - -    [IN_ESCAPE_I] = { -        ['6'] = IN_ESCAPE_I6, -    }, - -    [IN_ESCAPE] = { -        ['d'] = JSON_ESCAPE, -        ['i'] = JSON_ESCAPE, -        ['p'] = JSON_ESCAPE, -        ['s'] = JSON_ESCAPE, -        ['f'] = JSON_ESCAPE, -        ['l'] = IN_ESCAPE_L, -        ['I'] = IN_ESCAPE_I, -    }, - -    /* top level rule */ -    [IN_START] = { -        ['"'] = IN_DQ_STRING, -        ['\''] = IN_SQ_STRING, -        ['0'] = IN_ZERO, -        ['1' ... '9'] = IN_NONZERO_NUMBER, -        ['-'] = IN_NEG_NONZERO_NUMBER, -        ['{'] = JSON_OPERATOR, -        ['}'] = JSON_OPERATOR, -        ['['] = JSON_OPERATOR, -        [']'] = JSON_OPERATOR, -        [','] = JSON_OPERATOR, -        [':'] = JSON_OPERATOR, -        ['a' ... 'z'] = IN_KEYWORD, -        ['%'] = IN_ESCAPE, -        [' '] = IN_WHITESPACE, -        ['\t'] = IN_WHITESPACE, -        ['\r'] = IN_WHITESPACE, -        ['\n'] = IN_WHITESPACE, -    }, -}; - -void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func) -{ -    lexer->emit = func; -    lexer->state = IN_START; -    lexer->token = qstring_new(); -    lexer->x = lexer->y = 0; -} - -static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush) -{ -    int char_consumed, new_state; - -    lexer->x++; -    if (ch == '\n') { -        lexer->x = 0; -        lexer->y++; -    } - -    do { -        new_state = json_lexer[lexer->state][(uint8_t)ch]; -        char_consumed = !TERMINAL_NEEDED_LOOKAHEAD(lexer->state, new_state); -        if (char_consumed) { -            qstring_append_chr(lexer->token, ch); -        } - -        switch (new_state) { -        case JSON_OPERATOR: -        case JSON_ESCAPE: -        case JSON_INTEGER: -        case JSON_FLOAT: -        case JSON_KEYWORD: -        case JSON_STRING: -            lexer->emit(lexer, lexer->token, new_state, lexer->x, lexer->y); -            /* fall through */ -        case JSON_SKIP: -            QDECREF(lexer->token); -            lexer->token = qstring_new(); -            new_state = IN_START; -            break; -        case IN_ERROR: -            /* XXX: To avoid having previous bad input leaving the parser in an -             * unresponsive state where we consume unpredictable amounts of -             * subsequent "good" input, percolate this error state up to the -             * tokenizer/parser by forcing a NULL object to be emitted, then -             * reset state. -             * -             * Also note that this handling is required for reliable channel -             * negotiation between QMP and the guest agent, since chr(0xFF) -             * is placed at the beginning of certain events to ensure proper -             * delivery when the channel is in an unknown state. chr(0xFF) is -             * never a valid ASCII/UTF-8 sequence, so this should reliably -             * induce an error/flush state. -             */ -            lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y); -            QDECREF(lexer->token); -            lexer->token = qstring_new(); -            new_state = IN_START; -            lexer->state = new_state; -            return 0; -        default: -            break; -        } -        lexer->state = new_state; -    } while (!char_consumed && !flush); - -    /* Do not let a single token grow to an arbitrarily large size, -     * this is a security consideration. -     */ -    if (lexer->token->length > MAX_TOKEN_SIZE) { -        lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y); -        QDECREF(lexer->token); -        lexer->token = qstring_new(); -        lexer->state = IN_START; -    } - -    return 0; -} - -int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size) -{ -    size_t i; - -    for (i = 0; i < size; i++) { -        int err; - -        err = json_lexer_feed_char(lexer, buffer[i], false); -        if (err < 0) { -            return err; -        } -    } - -    return 0; -} - -int json_lexer_flush(JSONLexer *lexer) -{ -    return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0, true); -} - -void json_lexer_destroy(JSONLexer *lexer) -{ -    QDECREF(lexer->token); -} diff --git a/contrib/qemu/qobject/json-parser.c b/contrib/qemu/qobject/json-parser.c deleted file mode 100644 index e7947b340c1..00000000000 --- a/contrib/qemu/qobject/json-parser.c +++ /dev/null @@ -1,724 +0,0 @@ -/* - * JSON Parser  - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include <stdarg.h> - -#include "qemu-common.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qfloat.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/json-parser.h" -#include "qapi/qmp/json-lexer.h" -#include "qapi/qmp/qerror.h" - -typedef struct JSONParserContext -{ -    Error *err; -    struct { -        QObject **buf; -        size_t pos; -        size_t count; -    } tokens; -} JSONParserContext; - -#define BUG_ON(cond) assert(!(cond)) - -/** - * TODO - * - * 0) make errors meaningful again - * 1) add geometry information to tokens - * 3) should we return a parsed size? - * 4) deal with premature EOI - */ - -static QObject *parse_value(JSONParserContext *ctxt, va_list *ap); - -/** - * Token manipulators - * - * tokens are dictionaries that contain a type, a string value, and geometry information - * about a token identified by the lexer.  These are routines that make working with - * these objects a bit easier. - */ -static const char *token_get_value(QObject *obj) -{ -    return qdict_get_str(qobject_to_qdict(obj), "token"); -} - -static JSONTokenType token_get_type(QObject *obj) -{ -    return qdict_get_int(qobject_to_qdict(obj), "type"); -} - -static int token_is_operator(QObject *obj, char op) -{ -    const char *val; - -    if (token_get_type(obj) != JSON_OPERATOR) { -        return 0; -    } - -    val = token_get_value(obj); - -    return (val[0] == op) && (val[1] == 0); -} - -static int token_is_keyword(QObject *obj, const char *value) -{ -    if (token_get_type(obj) != JSON_KEYWORD) { -        return 0; -    } - -    return strcmp(token_get_value(obj), value) == 0; -} - -static int token_is_escape(QObject *obj, const char *value) -{ -    if (token_get_type(obj) != JSON_ESCAPE) { -        return 0; -    } - -    return (strcmp(token_get_value(obj), value) == 0); -} - -/** - * Error handler - */ -static void GCC_FMT_ATTR(3, 4) parse_error(JSONParserContext *ctxt, -                                           QObject *token, const char *msg, ...) -{ -    va_list ap; -    char message[1024]; -    va_start(ap, msg); -    vsnprintf(message, sizeof(message), msg, ap); -    va_end(ap); -    if (ctxt->err) { -        error_free(ctxt->err); -        ctxt->err = NULL; -    } -    error_set(&ctxt->err, QERR_JSON_PARSE_ERROR, message); -} - -/** - * String helpers - * - * These helpers are used to unescape strings. - */ -static void wchar_to_utf8(uint16_t wchar, char *buffer, size_t buffer_length) -{ -    if (wchar <= 0x007F) { -        BUG_ON(buffer_length < 2); - -        buffer[0] = wchar & 0x7F; -        buffer[1] = 0; -    } else if (wchar <= 0x07FF) { -        BUG_ON(buffer_length < 3); - -        buffer[0] = 0xC0 | ((wchar >> 6) & 0x1F); -        buffer[1] = 0x80 | (wchar & 0x3F); -        buffer[2] = 0; -    } else { -        BUG_ON(buffer_length < 4); - -        buffer[0] = 0xE0 | ((wchar >> 12) & 0x0F); -        buffer[1] = 0x80 | ((wchar >> 6) & 0x3F); -        buffer[2] = 0x80 | (wchar & 0x3F); -        buffer[3] = 0; -    } -} - -static int hex2decimal(char ch) -{ -    if (ch >= '0' && ch <= '9') { -        return (ch - '0'); -    } else if (ch >= 'a' && ch <= 'f') { -        return 10 + (ch - 'a'); -    } else if (ch >= 'A' && ch <= 'F') { -        return 10 + (ch - 'A'); -    } - -    return -1; -} - -/** - * parse_string(): Parse a json string and return a QObject - * - *  string - *      "" - *      " chars " - *  chars - *      char - *      char chars - *  char - *      any-Unicode-character- - *          except-"-or-\-or- - *          control-character - *      \" - *      \\ - *      \/ - *      \b - *      \f - *      \n - *      \r - *      \t - *      \u four-hex-digits  - */ -static QString *qstring_from_escaped_str(JSONParserContext *ctxt, QObject *token) -{ -    const char *ptr = token_get_value(token); -    QString *str; -    int double_quote = 1; - -    if (*ptr == '"') { -        double_quote = 1; -    } else { -        double_quote = 0; -    } -    ptr++; - -    str = qstring_new(); -    while (*ptr &&  -           ((double_quote && *ptr != '"') || (!double_quote && *ptr != '\''))) { -        if (*ptr == '\\') { -            ptr++; - -            switch (*ptr) { -            case '"': -                qstring_append(str, "\""); -                ptr++; -                break; -            case '\'': -                qstring_append(str, "'"); -                ptr++; -                break; -            case '\\': -                qstring_append(str, "\\"); -                ptr++; -                break; -            case '/': -                qstring_append(str, "/"); -                ptr++; -                break; -            case 'b': -                qstring_append(str, "\b"); -                ptr++; -                break; -            case 'f': -                qstring_append(str, "\f"); -                ptr++; -                break; -            case 'n': -                qstring_append(str, "\n"); -                ptr++; -                break; -            case 'r': -                qstring_append(str, "\r"); -                ptr++; -                break; -            case 't': -                qstring_append(str, "\t"); -                ptr++; -                break; -            case 'u': { -                uint16_t unicode_char = 0; -                char utf8_char[4]; -                int i = 0; - -                ptr++; - -                for (i = 0; i < 4; i++) { -                    if (qemu_isxdigit(*ptr)) { -                        unicode_char |= hex2decimal(*ptr) << ((3 - i) * 4); -                    } else { -                        parse_error(ctxt, token, -                                    "invalid hex escape sequence in string"); -                        goto out; -                    } -                    ptr++; -                } - -                wchar_to_utf8(unicode_char, utf8_char, sizeof(utf8_char)); -                qstring_append(str, utf8_char); -            }   break; -            default: -                parse_error(ctxt, token, "invalid escape sequence in string"); -                goto out; -            } -        } else { -            char dummy[2]; - -            dummy[0] = *ptr++; -            dummy[1] = 0; - -            qstring_append(str, dummy); -        } -    } - -    return str; - -out: -    QDECREF(str); -    return NULL; -} - -static QObject *parser_context_pop_token(JSONParserContext *ctxt) -{ -    QObject *token; -    g_assert(ctxt->tokens.pos < ctxt->tokens.count); -    token = ctxt->tokens.buf[ctxt->tokens.pos]; -    ctxt->tokens.pos++; -    return token; -} - -/* Note: parser_context_{peek|pop}_token do not increment the - * token object's refcount. In both cases the references will continue - * to be tracked and cleaned up in parser_context_free(), so do not - * attempt to free the token object. - */ -static QObject *parser_context_peek_token(JSONParserContext *ctxt) -{ -    QObject *token; -    g_assert(ctxt->tokens.pos < ctxt->tokens.count); -    token = ctxt->tokens.buf[ctxt->tokens.pos]; -    return token; -} - -static JSONParserContext parser_context_save(JSONParserContext *ctxt) -{ -    JSONParserContext saved_ctxt = {0}; -    saved_ctxt.tokens.pos = ctxt->tokens.pos; -    saved_ctxt.tokens.count = ctxt->tokens.count; -    saved_ctxt.tokens.buf = ctxt->tokens.buf; -    return saved_ctxt; -} - -static void parser_context_restore(JSONParserContext *ctxt, -                                   JSONParserContext saved_ctxt) -{ -    ctxt->tokens.pos = saved_ctxt.tokens.pos; -    ctxt->tokens.count = saved_ctxt.tokens.count; -    ctxt->tokens.buf = saved_ctxt.tokens.buf; -} - -static void tokens_append_from_iter(QObject *obj, void *opaque) -{ -    JSONParserContext *ctxt = opaque; -    g_assert(ctxt->tokens.pos < ctxt->tokens.count); -    ctxt->tokens.buf[ctxt->tokens.pos++] = obj; -    qobject_incref(obj); -} - -static JSONParserContext *parser_context_new(QList *tokens) -{ -    JSONParserContext *ctxt; -    size_t count; - -    if (!tokens) { -        return NULL; -    } - -    count = qlist_size(tokens); -    if (count == 0) { -        return NULL; -    } - -    ctxt = g_malloc0(sizeof(JSONParserContext)); -    ctxt->tokens.pos = 0; -    ctxt->tokens.count = count; -    ctxt->tokens.buf = g_malloc(count * sizeof(QObject *)); -    qlist_iter(tokens, tokens_append_from_iter, ctxt); -    ctxt->tokens.pos = 0; - -    return ctxt; -} - -/* to support error propagation, ctxt->err must be freed separately */ -static void parser_context_free(JSONParserContext *ctxt) -{ -    int i; -    if (ctxt) { -        for (i = 0; i < ctxt->tokens.count; i++) { -            qobject_decref(ctxt->tokens.buf[i]); -        } -        g_free(ctxt->tokens.buf); -        g_free(ctxt); -    } -} - -/** - * Parsing rules - */ -static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap) -{ -    QObject *key = NULL, *token = NULL, *value, *peek; -    JSONParserContext saved_ctxt = parser_context_save(ctxt); - -    peek = parser_context_peek_token(ctxt); -    if (peek == NULL) { -        parse_error(ctxt, NULL, "premature EOI"); -        goto out; -    } - -    key = parse_value(ctxt, ap); -    if (!key || qobject_type(key) != QTYPE_QSTRING) { -        parse_error(ctxt, peek, "key is not a string in object"); -        goto out; -    } - -    token = parser_context_pop_token(ctxt); -    if (token == NULL) { -        parse_error(ctxt, NULL, "premature EOI"); -        goto out; -    } - -    if (!token_is_operator(token, ':')) { -        parse_error(ctxt, token, "missing : in object pair"); -        goto out; -    } - -    value = parse_value(ctxt, ap); -    if (value == NULL) { -        parse_error(ctxt, token, "Missing value in dict"); -        goto out; -    } - -    qdict_put_obj(dict, qstring_get_str(qobject_to_qstring(key)), value); - -    qobject_decref(key); - -    return 0; - -out: -    parser_context_restore(ctxt, saved_ctxt); -    qobject_decref(key); - -    return -1; -} - -static QObject *parse_object(JSONParserContext *ctxt, va_list *ap) -{ -    QDict *dict = NULL; -    QObject *token, *peek; -    JSONParserContext saved_ctxt = parser_context_save(ctxt); - -    token = parser_context_pop_token(ctxt); -    if (token == NULL) { -        goto out; -    } - -    if (!token_is_operator(token, '{')) { -        goto out; -    } -    token = NULL; - -    dict = qdict_new(); - -    peek = parser_context_peek_token(ctxt); -    if (peek == NULL) { -        parse_error(ctxt, NULL, "premature EOI"); -        goto out; -    } - -    if (!token_is_operator(peek, '}')) { -        if (parse_pair(ctxt, dict, ap) == -1) { -            goto out; -        } - -        token = parser_context_pop_token(ctxt); -        if (token == NULL) { -            parse_error(ctxt, NULL, "premature EOI"); -            goto out; -        } - -        while (!token_is_operator(token, '}')) { -            if (!token_is_operator(token, ',')) { -                parse_error(ctxt, token, "expected separator in dict"); -                goto out; -            } -            token = NULL; - -            if (parse_pair(ctxt, dict, ap) == -1) { -                goto out; -            } - -            token = parser_context_pop_token(ctxt); -            if (token == NULL) { -                parse_error(ctxt, NULL, "premature EOI"); -                goto out; -            } -        } -        token = NULL; -    } else { -        token = parser_context_pop_token(ctxt); -        token = NULL; -    } - -    return QOBJECT(dict); - -out: -    parser_context_restore(ctxt, saved_ctxt); -    QDECREF(dict); -    return NULL; -} - -static QObject *parse_array(JSONParserContext *ctxt, va_list *ap) -{ -    QList *list = NULL; -    QObject *token, *peek; -    JSONParserContext saved_ctxt = parser_context_save(ctxt); - -    token = parser_context_pop_token(ctxt); -    if (token == NULL) { -        goto out; -    } - -    if (!token_is_operator(token, '[')) { -        token = NULL; -        goto out; -    } -    token = NULL; - -    list = qlist_new(); - -    peek = parser_context_peek_token(ctxt); -    if (peek == NULL) { -        parse_error(ctxt, NULL, "premature EOI"); -        goto out; -    } - -    if (!token_is_operator(peek, ']')) { -        QObject *obj; - -        obj = parse_value(ctxt, ap); -        if (obj == NULL) { -            parse_error(ctxt, token, "expecting value"); -            goto out; -        } - -        qlist_append_obj(list, obj); - -        token = parser_context_pop_token(ctxt); -        if (token == NULL) { -            parse_error(ctxt, NULL, "premature EOI"); -            goto out; -        } - -        while (!token_is_operator(token, ']')) { -            if (!token_is_operator(token, ',')) { -                parse_error(ctxt, token, "expected separator in list"); -                goto out; -            } - -            token = NULL; - -            obj = parse_value(ctxt, ap); -            if (obj == NULL) { -                parse_error(ctxt, token, "expecting value"); -                goto out; -            } - -            qlist_append_obj(list, obj); - -            token = parser_context_pop_token(ctxt); -            if (token == NULL) { -                parse_error(ctxt, NULL, "premature EOI"); -                goto out; -            } -        } - -        token = NULL; -    } else { -        token = parser_context_pop_token(ctxt); -        token = NULL; -    } - -    return QOBJECT(list); - -out: -    parser_context_restore(ctxt, saved_ctxt); -    QDECREF(list); -    return NULL; -} - -static QObject *parse_keyword(JSONParserContext *ctxt) -{ -    QObject *token, *ret; -    JSONParserContext saved_ctxt = parser_context_save(ctxt); - -    token = parser_context_pop_token(ctxt); -    if (token == NULL) { -        goto out; -    } - -    if (token_get_type(token) != JSON_KEYWORD) { -        goto out; -    } - -    if (token_is_keyword(token, "true")) { -        ret = QOBJECT(qbool_from_int(true)); -    } else if (token_is_keyword(token, "false")) { -        ret = QOBJECT(qbool_from_int(false)); -    } else { -        parse_error(ctxt, token, "invalid keyword `%s'", token_get_value(token)); -        goto out; -    } - -    return ret; - -out:  -    parser_context_restore(ctxt, saved_ctxt); - -    return NULL; -} - -static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap) -{ -    QObject *token = NULL, *obj; -    JSONParserContext saved_ctxt = parser_context_save(ctxt); - -    if (ap == NULL) { -        goto out; -    } - -    token = parser_context_pop_token(ctxt); -    if (token == NULL) { -        goto out; -    } - -    if (token_is_escape(token, "%p")) { -        obj = va_arg(*ap, QObject *); -    } else if (token_is_escape(token, "%i")) { -        obj = QOBJECT(qbool_from_int(va_arg(*ap, int))); -    } else if (token_is_escape(token, "%d")) { -        obj = QOBJECT(qint_from_int(va_arg(*ap, int))); -    } else if (token_is_escape(token, "%ld")) { -        obj = QOBJECT(qint_from_int(va_arg(*ap, long))); -    } else if (token_is_escape(token, "%lld") || -               token_is_escape(token, "%I64d")) { -        obj = QOBJECT(qint_from_int(va_arg(*ap, long long))); -    } else if (token_is_escape(token, "%s")) { -        obj = QOBJECT(qstring_from_str(va_arg(*ap, const char *))); -    } else if (token_is_escape(token, "%f")) { -        obj = QOBJECT(qfloat_from_double(va_arg(*ap, double))); -    } else { -        goto out; -    } - -    return obj; - -out: -    parser_context_restore(ctxt, saved_ctxt); - -    return NULL; -} - -static QObject *parse_literal(JSONParserContext *ctxt) -{ -    QObject *token, *obj; -    JSONParserContext saved_ctxt = parser_context_save(ctxt); - -    token = parser_context_pop_token(ctxt); -    if (token == NULL) { -        goto out; -    } - -    switch (token_get_type(token)) { -    case JSON_STRING: -        obj = QOBJECT(qstring_from_escaped_str(ctxt, token)); -        break; -    case JSON_INTEGER: { -        /* A possibility exists that this is a whole-valued float where the -         * fractional part was left out due to being 0 (.0). It's not a big -         * deal to treat these as ints in the parser, so long as users of the -         * resulting QObject know to expect a QInt in place of a QFloat in -         * cases like these. -         * -         * However, in some cases these values will overflow/underflow a -         * QInt/int64 container, thus we should assume these are to be handled -         * as QFloats/doubles rather than silently changing their values. -         * -         * strtoll() indicates these instances by setting errno to ERANGE -         */ -        int64_t value; - -        errno = 0; /* strtoll doesn't set errno on success */ -        value = strtoll(token_get_value(token), NULL, 10); -        if (errno != ERANGE) { -            obj = QOBJECT(qint_from_int(value)); -            break; -        } -        /* fall through to JSON_FLOAT */ -    } -    case JSON_FLOAT: -        /* FIXME dependent on locale */ -        obj = QOBJECT(qfloat_from_double(strtod(token_get_value(token), NULL))); -        break; -    default: -        goto out; -    } - -    return obj; - -out: -    parser_context_restore(ctxt, saved_ctxt); - -    return NULL; -} - -static QObject *parse_value(JSONParserContext *ctxt, va_list *ap) -{ -    QObject *obj; - -    obj = parse_object(ctxt, ap); -    if (obj == NULL) { -        obj = parse_array(ctxt, ap); -    } -    if (obj == NULL) { -        obj = parse_escape(ctxt, ap); -    } -    if (obj == NULL) { -        obj = parse_keyword(ctxt); -    }  -    if (obj == NULL) { -        obj = parse_literal(ctxt); -    } - -    return obj; -} - -QObject *json_parser_parse(QList *tokens, va_list *ap) -{ -    return json_parser_parse_err(tokens, ap, NULL); -} - -QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp) -{ -    JSONParserContext *ctxt = parser_context_new(tokens); -    QObject *result; - -    if (!ctxt) { -        return NULL; -    } - -    result = parse_value(ctxt, ap); - -    error_propagate(errp, ctxt->err); - -    parser_context_free(ctxt); - -    return result; -} diff --git a/contrib/qemu/qobject/json-streamer.c b/contrib/qemu/qobject/json-streamer.c deleted file mode 100644 index 1b2f9b1d107..00000000000 --- a/contrib/qemu/qobject/json-streamer.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * JSON streaming support - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qdict.h" -#include "qemu-common.h" -#include "qapi/qmp/json-lexer.h" -#include "qapi/qmp/json-streamer.h" - -#define MAX_TOKEN_SIZE (64ULL << 20) -#define MAX_NESTING (1ULL << 10) - -static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y) -{ -    JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer); -    QDict *dict; - -    if (type == JSON_OPERATOR) { -        switch (qstring_get_str(token)[0]) { -        case '{': -            parser->brace_count++; -            break; -        case '}': -            parser->brace_count--; -            break; -        case '[': -            parser->bracket_count++; -            break; -        case ']': -            parser->bracket_count--; -            break; -        default: -            break; -        } -    } - -    dict = qdict_new(); -    qdict_put(dict, "type", qint_from_int(type)); -    QINCREF(token); -    qdict_put(dict, "token", token); -    qdict_put(dict, "x", qint_from_int(x)); -    qdict_put(dict, "y", qint_from_int(y)); - -    parser->token_size += token->length; - -    qlist_append(parser->tokens, dict); - -    if (type == JSON_ERROR) { -        goto out_emit_bad; -    } else if (parser->brace_count < 0 || -        parser->bracket_count < 0 || -        (parser->brace_count == 0 && -         parser->bracket_count == 0)) { -        goto out_emit; -    } else if (parser->token_size > MAX_TOKEN_SIZE || -               parser->bracket_count > MAX_NESTING || -               parser->brace_count > MAX_NESTING) { -        /* Security consideration, we limit total memory allocated per object -         * and the maximum recursion depth that a message can force. -         */ -        goto out_emit; -    } - -    return; - -out_emit_bad: -    /* clear out token list and tell the parser to emit and error -     * indication by passing it a NULL list -     */ -    QDECREF(parser->tokens); -    parser->tokens = NULL; -out_emit: -    /* send current list of tokens to parser and reset tokenizer */ -    parser->brace_count = 0; -    parser->bracket_count = 0; -    parser->emit(parser, parser->tokens); -    if (parser->tokens) { -        QDECREF(parser->tokens); -    } -    parser->tokens = qlist_new(); -    parser->token_size = 0; -} - -void json_message_parser_init(JSONMessageParser *parser, -                              void (*func)(JSONMessageParser *, QList *)) -{ -    parser->emit = func; -    parser->brace_count = 0; -    parser->bracket_count = 0; -    parser->tokens = qlist_new(); -    parser->token_size = 0; - -    json_lexer_init(&parser->lexer, json_message_process_token); -} - -int json_message_parser_feed(JSONMessageParser *parser, -                             const char *buffer, size_t size) -{ -    return json_lexer_feed(&parser->lexer, buffer, size); -} - -int json_message_parser_flush(JSONMessageParser *parser) -{ -    return json_lexer_flush(&parser->lexer); -} - -void json_message_parser_destroy(JSONMessageParser *parser) -{ -    json_lexer_destroy(&parser->lexer); -    QDECREF(parser->tokens); -} diff --git a/contrib/qemu/qobject/qbool.c b/contrib/qemu/qobject/qbool.c deleted file mode 100644 index a3d2afa827f..00000000000 --- a/contrib/qemu/qobject/qbool.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * QBool Module - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qobject.h" -#include "qemu-common.h" - -static void qbool_destroy_obj(QObject *obj); - -static const QType qbool_type = { -    .code = QTYPE_QBOOL, -    .destroy = qbool_destroy_obj, -}; - -/** - * qbool_from_int(): Create a new QBool from an int - * - * Return strong reference. - */ -QBool *qbool_from_int(int value) -{ -    QBool *qb; - -    qb = g_malloc(sizeof(*qb)); -    qb->value = value; -    QOBJECT_INIT(qb, &qbool_type); - -    return qb; -} - -/** - * qbool_get_int(): Get the stored int - */ -int qbool_get_int(const QBool *qb) -{ -    return qb->value; -} - -/** - * qobject_to_qbool(): Convert a QObject into a QBool - */ -QBool *qobject_to_qbool(const QObject *obj) -{ -    if (qobject_type(obj) != QTYPE_QBOOL) -        return NULL; - -    return container_of(obj, QBool, base); -} - -/** - * qbool_destroy_obj(): Free all memory allocated by a - * QBool object - */ -static void qbool_destroy_obj(QObject *obj) -{ -    assert(obj != NULL); -    g_free(qobject_to_qbool(obj)); -} diff --git a/contrib/qemu/qobject/qdict.c b/contrib/qemu/qobject/qdict.c deleted file mode 100644 index ed381f9a507..00000000000 --- a/contrib/qemu/qobject/qdict.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * QDict Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qfloat.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qobject.h" -#include "qemu/queue.h" -#include "qemu-common.h" - -static void qdict_destroy_obj(QObject *obj); - -static const QType qdict_type = { -    .code = QTYPE_QDICT, -    .destroy = qdict_destroy_obj, -}; - -/** - * qdict_new(): Create a new QDict - * - * Return strong reference. - */ -QDict *qdict_new(void) -{ -    QDict *qdict; - -    qdict = g_malloc0(sizeof(*qdict)); -    QOBJECT_INIT(qdict, &qdict_type); - -    return qdict; -} - -/** - * qobject_to_qdict(): Convert a QObject into a QDict - */ -QDict *qobject_to_qdict(const QObject *obj) -{ -    if (qobject_type(obj) != QTYPE_QDICT) -        return NULL; - -    return container_of(obj, QDict, base); -} - -/** - * tdb_hash(): based on the hash agorithm from gdbm, via tdb - * (from module-init-tools) - */ -static unsigned int tdb_hash(const char *name) -{ -    unsigned value;	/* Used to compute the hash value.  */ -    unsigned   i;	/* Used to cycle through random values. */ - -    /* Set the initial value from the key size. */ -    for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++) -        value = (value + (((const unsigned char *)name)[i] << (i*5 % 24))); - -    return (1103515243 * value + 12345); -} - -/** - * alloc_entry(): allocate a new QDictEntry - */ -static QDictEntry *alloc_entry(const char *key, QObject *value) -{ -    QDictEntry *entry; - -    entry = g_malloc0(sizeof(*entry)); -    entry->key = g_strdup(key); -    entry->value = value; - -    return entry; -} - -/** - * qdict_entry_value(): Return qdict entry value - * - * Return weak reference. - */ -QObject *qdict_entry_value(const QDictEntry *entry) -{ -    return entry->value; -} - -/** - * qdict_entry_key(): Return qdict entry key - * - * Return a *pointer* to the string, it has to be duplicated before being - * stored. - */ -const char *qdict_entry_key(const QDictEntry *entry) -{ -    return entry->key; -} - -/** - * qdict_find(): List lookup function - */ -static QDictEntry *qdict_find(const QDict *qdict, -                              const char *key, unsigned int bucket) -{ -    QDictEntry *entry; - -    QLIST_FOREACH(entry, &qdict->table[bucket], next) -        if (!strcmp(entry->key, key)) -            return entry; - -    return NULL; -} - -/** - * qdict_put_obj(): Put a new QObject into the dictionary - * - * Insert the pair 'key:value' into 'qdict', if 'key' already exists - * its 'value' will be replaced. - * - * This is done by freeing the reference to the stored QObject and - * storing the new one in the same entry. - * - * NOTE: ownership of 'value' is transferred to the QDict - */ -void qdict_put_obj(QDict *qdict, const char *key, QObject *value) -{ -    unsigned int bucket; -    QDictEntry *entry; - -    bucket = tdb_hash(key) % QDICT_BUCKET_MAX; -    entry = qdict_find(qdict, key, bucket); -    if (entry) { -        /* replace key's value */ -        qobject_decref(entry->value); -        entry->value = value; -    } else { -        /* allocate a new entry */ -        entry = alloc_entry(key, value); -        QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next); -        qdict->size++; -    } -} - -/** - * qdict_get(): Lookup for a given 'key' - * - * Return a weak reference to the QObject associated with 'key' if - * 'key' is present in the dictionary, NULL otherwise. - */ -QObject *qdict_get(const QDict *qdict, const char *key) -{ -    QDictEntry *entry; - -    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX); -    return (entry == NULL ? NULL : entry->value); -} - -/** - * qdict_haskey(): Check if 'key' exists - * - * Return 1 if 'key' exists in the dict, 0 otherwise - */ -int qdict_haskey(const QDict *qdict, const char *key) -{ -    unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX; -    return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1); -} - -/** - * qdict_size(): Return the size of the dictionary - */ -size_t qdict_size(const QDict *qdict) -{ -    return qdict->size; -} - -/** - * qdict_get_obj(): Get a QObject of a specific type - */ -static QObject *qdict_get_obj(const QDict *qdict, const char *key, -                              qtype_code type) -{ -    QObject *obj; - -    obj = qdict_get(qdict, key); -    assert(obj != NULL); -    assert(qobject_type(obj) == type); - -    return obj; -} - -/** - * qdict_get_double(): Get an number mapped by 'key' - * - * This function assumes that 'key' exists and it stores a - * QFloat or QInt object. - * - * Return number mapped by 'key'. - */ -double qdict_get_double(const QDict *qdict, const char *key) -{ -    QObject *obj = qdict_get(qdict, key); - -    assert(obj); -    switch (qobject_type(obj)) { -    case QTYPE_QFLOAT: -        return qfloat_get_double(qobject_to_qfloat(obj)); -    case QTYPE_QINT: -        return qint_get_int(qobject_to_qint(obj)); -    default: -        abort(); -    } -} - -/** - * qdict_get_int(): Get an integer mapped by 'key' - * - * This function assumes that 'key' exists and it stores a - * QInt object. - * - * Return integer mapped by 'key'. - */ -int64_t qdict_get_int(const QDict *qdict, const char *key) -{ -    QObject *obj = qdict_get_obj(qdict, key, QTYPE_QINT); -    return qint_get_int(qobject_to_qint(obj)); -} - -/** - * qdict_get_bool(): Get a bool mapped by 'key' - * - * This function assumes that 'key' exists and it stores a - * QBool object. - * - * Return bool mapped by 'key'. - */ -int qdict_get_bool(const QDict *qdict, const char *key) -{ -    QObject *obj = qdict_get_obj(qdict, key, QTYPE_QBOOL); -    return qbool_get_int(qobject_to_qbool(obj)); -} - -/** - * qdict_get_qlist(): Get the QList mapped by 'key' - * - * This function assumes that 'key' exists and it stores a - * QList object. - * - * Return QList mapped by 'key'. - */ -QList *qdict_get_qlist(const QDict *qdict, const char *key) -{ -    return qobject_to_qlist(qdict_get_obj(qdict, key, QTYPE_QLIST)); -} - -/** - * qdict_get_qdict(): Get the QDict mapped by 'key' - * - * This function assumes that 'key' exists and it stores a - * QDict object. - * - * Return QDict mapped by 'key'. - */ -QDict *qdict_get_qdict(const QDict *qdict, const char *key) -{ -    return qobject_to_qdict(qdict_get_obj(qdict, key, QTYPE_QDICT)); -} - -/** - * qdict_get_str(): Get a pointer to the stored string mapped - * by 'key' - * - * This function assumes that 'key' exists and it stores a - * QString object. - * - * Return pointer to the string mapped by 'key'. - */ -const char *qdict_get_str(const QDict *qdict, const char *key) -{ -    QObject *obj = qdict_get_obj(qdict, key, QTYPE_QSTRING); -    return qstring_get_str(qobject_to_qstring(obj)); -} - -/** - * qdict_get_try_int(): Try to get integer mapped by 'key' - * - * Return integer mapped by 'key', if it is not present in - * the dictionary or if the stored object is not of QInt type - * 'def_value' will be returned. - */ -int64_t qdict_get_try_int(const QDict *qdict, const char *key, -                          int64_t def_value) -{ -    QObject *obj; - -    obj = qdict_get(qdict, key); -    if (!obj || qobject_type(obj) != QTYPE_QINT) -        return def_value; - -    return qint_get_int(qobject_to_qint(obj)); -} - -/** - * qdict_get_try_bool(): Try to get a bool mapped by 'key' - * - * Return bool mapped by 'key', if it is not present in the - * dictionary or if the stored object is not of QBool type - * 'def_value' will be returned. - */ -int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value) -{ -    QObject *obj; - -    obj = qdict_get(qdict, key); -    if (!obj || qobject_type(obj) != QTYPE_QBOOL) -        return def_value; - -    return qbool_get_int(qobject_to_qbool(obj)); -} - -/** - * qdict_get_try_str(): Try to get a pointer to the stored string - * mapped by 'key' - * - * Return a pointer to the string mapped by 'key', if it is not present - * in the dictionary or if the stored object is not of QString type - * NULL will be returned. - */ -const char *qdict_get_try_str(const QDict *qdict, const char *key) -{ -    QObject *obj; - -    obj = qdict_get(qdict, key); -    if (!obj || qobject_type(obj) != QTYPE_QSTRING) -        return NULL; - -    return qstring_get_str(qobject_to_qstring(obj)); -} - -/** - * qdict_iter(): Iterate over all the dictionary's stored values. - * - * This function allows the user to provide an iterator, which will be - * called for each stored value in the dictionary. - */ -void qdict_iter(const QDict *qdict, -                void (*iter)(const char *key, QObject *obj, void *opaque), -                void *opaque) -{ -    int i; -    QDictEntry *entry; - -    for (i = 0; i < QDICT_BUCKET_MAX; i++) { -        QLIST_FOREACH(entry, &qdict->table[i], next) -            iter(entry->key, entry->value, opaque); -    } -} - -static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket) -{ -    int i; - -    for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) { -        if (!QLIST_EMPTY(&qdict->table[i])) { -            return QLIST_FIRST(&qdict->table[i]); -        } -    } - -    return NULL; -} - -/** - * qdict_first(): Return first qdict entry for iteration. - */ -const QDictEntry *qdict_first(const QDict *qdict) -{ -    return qdict_next_entry(qdict, 0); -} - -/** - * qdict_next(): Return next qdict entry in an iteration. - */ -const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry) -{ -    QDictEntry *ret; - -    ret = QLIST_NEXT(entry, next); -    if (!ret) { -        unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX; -        ret = qdict_next_entry(qdict, bucket + 1); -    } - -    return ret; -} - -/** - * qdict_clone_shallow(): Clones a given QDict. Its entries are not copied, but - * another reference is added. - */ -QDict *qdict_clone_shallow(const QDict *src) -{ -    QDict *dest; -    QDictEntry *entry; -    int i; - -    dest = qdict_new(); - -    for (i = 0; i < QDICT_BUCKET_MAX; i++) { -        QLIST_FOREACH(entry, &src->table[i], next) { -            qobject_incref(entry->value); -            qdict_put_obj(dest, entry->key, entry->value); -        } -    } - -    return dest; -} - -/** - * qentry_destroy(): Free all the memory allocated by a QDictEntry - */ -static void qentry_destroy(QDictEntry *e) -{ -    assert(e != NULL); -    assert(e->key != NULL); -    assert(e->value != NULL); - -    qobject_decref(e->value); -    g_free(e->key); -    g_free(e); -} - -/** - * qdict_del(): Delete a 'key:value' pair from the dictionary - * - * This will destroy all data allocated by this entry. - */ -void qdict_del(QDict *qdict, const char *key) -{ -    QDictEntry *entry; - -    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX); -    if (entry) { -        QLIST_REMOVE(entry, next); -        qentry_destroy(entry); -        qdict->size--; -    } -} - -/** - * qdict_destroy_obj(): Free all the memory allocated by a QDict - */ -static void qdict_destroy_obj(QObject *obj) -{ -    int i; -    QDict *qdict; - -    assert(obj != NULL); -    qdict = qobject_to_qdict(obj); - -    for (i = 0; i < QDICT_BUCKET_MAX; i++) { -        QDictEntry *entry = QLIST_FIRST(&qdict->table[i]); -        while (entry) { -            QDictEntry *tmp = QLIST_NEXT(entry, next); -            QLIST_REMOVE(entry, next); -            qentry_destroy(entry); -            entry = tmp; -        } -    } - -    g_free(qdict); -} diff --git a/contrib/qemu/qobject/qerror.c b/contrib/qemu/qobject/qerror.c deleted file mode 100644 index 3aee1cf6a69..00000000000 --- a/contrib/qemu/qobject/qerror.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * QError Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#include "monitor/monitor.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qerror.h" -#include "qemu-common.h" - -static void qerror_destroy_obj(QObject *obj); - -static const QType qerror_type = { -    .code = QTYPE_QERROR, -    .destroy = qerror_destroy_obj, -}; - -/** - * qerror_new(): Create a new QError - * - * Return strong reference. - */ -static QError *qerror_new(void) -{ -    QError *qerr; - -    qerr = g_malloc0(sizeof(*qerr)); -    QOBJECT_INIT(qerr, &qerror_type); - -    return qerr; -} - -/** - * qerror_from_info(): Create a new QError from error information - * - * Return strong reference. - */ -static QError *qerror_from_info(ErrorClass err_class, const char *fmt, -                                va_list *va) -{ -    QError *qerr; - -    qerr = qerror_new(); -    loc_save(&qerr->loc); - -    qerr->err_msg = g_strdup_vprintf(fmt, *va); -    qerr->err_class = err_class; - -    return qerr; -} - -/** - * qerror_human(): Format QError data into human-readable string. - */ -QString *qerror_human(const QError *qerror) -{ -    return qstring_from_str(qerror->err_msg); -} - -/** - * qerror_print(): Print QError data - * - * This function will print the member 'desc' of the specified QError object, - * it uses error_report() for this, so that the output is routed to the right - * place (ie. stderr or Monitor's device). - */ -static void qerror_print(QError *qerror) -{ -    QString *qstring = qerror_human(qerror); -    loc_push_restore(&qerror->loc); -    error_report("%s", qstring_get_str(qstring)); -    loc_pop(&qerror->loc); -    QDECREF(qstring); -} - -void qerror_report(ErrorClass eclass, const char *fmt, ...) -{ -    va_list va; -    QError *qerror; - -    va_start(va, fmt); -    qerror = qerror_from_info(eclass, fmt, &va); -    va_end(va); - -    if (monitor_cur_is_qmp()) { -        monitor_set_error(cur_mon, qerror); -    } else { -        qerror_print(qerror); -        QDECREF(qerror); -    } -} - -/* Evil... */ -struct Error -{ -    char *msg; -    ErrorClass err_class; -}; - -void qerror_report_err(Error *err) -{ -    QError *qerr; - -    qerr = qerror_new(); -    loc_save(&qerr->loc); -    qerr->err_msg = g_strdup(err->msg); -    qerr->err_class = err->err_class; - -    if (monitor_cur_is_qmp()) { -        monitor_set_error(cur_mon, qerr); -    } else { -        qerror_print(qerr); -        QDECREF(qerr); -    } -} - -void assert_no_error(Error *err) -{ -    if (err) { -        qerror_report_err(err); -        abort(); -    } -} - -/** - * qobject_to_qerror(): Convert a QObject into a QError - */ -static QError *qobject_to_qerror(const QObject *obj) -{ -    if (qobject_type(obj) != QTYPE_QERROR) { -        return NULL; -    } - -    return container_of(obj, QError, base); -} - -/** - * qerror_destroy_obj(): Free all memory allocated by a QError - */ -static void qerror_destroy_obj(QObject *obj) -{ -    QError *qerr; - -    assert(obj != NULL); -    qerr = qobject_to_qerror(obj); - -    g_free(qerr->err_msg); -    g_free(qerr); -} diff --git a/contrib/qemu/qobject/qfloat.c b/contrib/qemu/qobject/qfloat.c deleted file mode 100644 index 7de0992dba7..00000000000 --- a/contrib/qemu/qobject/qfloat.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * QFloat Module - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qapi/qmp/qfloat.h" -#include "qapi/qmp/qobject.h" -#include "qemu-common.h" - -static void qfloat_destroy_obj(QObject *obj); - -static const QType qfloat_type = { -    .code = QTYPE_QFLOAT, -    .destroy = qfloat_destroy_obj, -}; - -/** - * qfloat_from_int(): Create a new QFloat from a float - * - * Return strong reference. - */ -QFloat *qfloat_from_double(double value) -{ -    QFloat *qf; - -    qf = g_malloc(sizeof(*qf)); -    qf->value = value; -    QOBJECT_INIT(qf, &qfloat_type); - -    return qf; -} - -/** - * qfloat_get_double(): Get the stored float - */ -double qfloat_get_double(const QFloat *qf) -{ -    return qf->value; -} - -/** - * qobject_to_qfloat(): Convert a QObject into a QFloat - */ -QFloat *qobject_to_qfloat(const QObject *obj) -{ -    if (qobject_type(obj) != QTYPE_QFLOAT) -        return NULL; - -    return container_of(obj, QFloat, base); -} - -/** - * qfloat_destroy_obj(): Free all memory allocated by a - * QFloat object - */ -static void qfloat_destroy_obj(QObject *obj) -{ -    assert(obj != NULL); -    g_free(qobject_to_qfloat(obj)); -} diff --git a/contrib/qemu/qobject/qint.c b/contrib/qemu/qobject/qint.c deleted file mode 100644 index 86b9b04f0b6..00000000000 --- a/contrib/qemu/qobject/qint.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * QInt Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qobject.h" -#include "qemu-common.h" - -static void qint_destroy_obj(QObject *obj); - -static const QType qint_type = { -    .code = QTYPE_QINT, -    .destroy = qint_destroy_obj, -}; - -/** - * qint_from_int(): Create a new QInt from an int64_t - * - * Return strong reference. - */ -QInt *qint_from_int(int64_t value) -{ -    QInt *qi; - -    qi = g_malloc(sizeof(*qi)); -    qi->value = value; -    QOBJECT_INIT(qi, &qint_type); - -    return qi; -} - -/** - * qint_get_int(): Get the stored integer - */ -int64_t qint_get_int(const QInt *qi) -{ -    return qi->value; -} - -/** - * qobject_to_qint(): Convert a QObject into a QInt - */ -QInt *qobject_to_qint(const QObject *obj) -{ -    if (qobject_type(obj) != QTYPE_QINT) -        return NULL; - -    return container_of(obj, QInt, base); -} - -/** - * qint_destroy_obj(): Free all memory allocated by a - * QInt object - */ -static void qint_destroy_obj(QObject *obj) -{ -    assert(obj != NULL); -    g_free(qobject_to_qint(obj)); -} diff --git a/contrib/qemu/qobject/qjson.c b/contrib/qemu/qobject/qjson.c deleted file mode 100644 index 19085a1bb7f..00000000000 --- a/contrib/qemu/qobject/qjson.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * QObject JSON integration - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "qapi/qmp/json-lexer.h" -#include "qapi/qmp/json-parser.h" -#include "qapi/qmp/json-streamer.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qfloat.h" -#include "qapi/qmp/qdict.h" - -typedef struct JSONParsingState -{ -    JSONMessageParser parser; -    va_list *ap; -    QObject *result; -} JSONParsingState; - -static void parse_json(JSONMessageParser *parser, QList *tokens) -{ -    JSONParsingState *s = container_of(parser, JSONParsingState, parser); -    s->result = json_parser_parse(tokens, s->ap); -} - -QObject *qobject_from_jsonv(const char *string, va_list *ap) -{ -    JSONParsingState state = {}; - -    state.ap = ap; - -    json_message_parser_init(&state.parser, parse_json); -    json_message_parser_feed(&state.parser, string, strlen(string)); -    json_message_parser_flush(&state.parser); -    json_message_parser_destroy(&state.parser); - -    return state.result; -} - -QObject *qobject_from_json(const char *string) -{ -    return qobject_from_jsonv(string, NULL); -} - -/* - * IMPORTANT: This function aborts on error, thus it must not - * be used with untrusted arguments. - */ -QObject *qobject_from_jsonf(const char *string, ...) -{ -    QObject *obj; -    va_list ap; - -    va_start(ap, string); -    obj = qobject_from_jsonv(string, &ap); -    va_end(ap); - -    assert(obj != NULL); -    return obj; -} - -typedef struct ToJsonIterState -{ -    int indent; -    int pretty; -    int count; -    QString *str; -} ToJsonIterState; - -static void to_json(const QObject *obj, QString *str, int pretty, int indent); - -static void to_json_dict_iter(const char *key, QObject *obj, void *opaque) -{ -    ToJsonIterState *s = opaque; -    QString *qkey; -    int j; - -    if (s->count) -        qstring_append(s->str, ", "); - -    if (s->pretty) { -        qstring_append(s->str, "\n"); -        for (j = 0 ; j < s->indent ; j++) -            qstring_append(s->str, "    "); -    } - -    qkey = qstring_from_str(key); -    to_json(QOBJECT(qkey), s->str, s->pretty, s->indent); -    QDECREF(qkey); - -    qstring_append(s->str, ": "); -    to_json(obj, s->str, s->pretty, s->indent); -    s->count++; -} - -static void to_json_list_iter(QObject *obj, void *opaque) -{ -    ToJsonIterState *s = opaque; -    int j; - -    if (s->count) -        qstring_append(s->str, ", "); - -    if (s->pretty) { -        qstring_append(s->str, "\n"); -        for (j = 0 ; j < s->indent ; j++) -            qstring_append(s->str, "    "); -    } - -    to_json(obj, s->str, s->pretty, s->indent); -    s->count++; -} - -static void to_json(const QObject *obj, QString *str, int pretty, int indent) -{ -    switch (qobject_type(obj)) { -    case QTYPE_QINT: { -        QInt *val = qobject_to_qint(obj); -        char buffer[1024]; - -        snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val)); -        qstring_append(str, buffer); -        break; -    } -    case QTYPE_QSTRING: { -        QString *val = qobject_to_qstring(obj); -        const char *ptr; -        int cp; -        char buf[16]; -        char *end; - -        ptr = qstring_get_str(val); -        qstring_append(str, "\""); - -        for (; *ptr; ptr = end) { -            cp = mod_utf8_codepoint(ptr, 6, &end); -            switch (cp) { -            case '\"': -                qstring_append(str, "\\\""); -                break; -            case '\\': -                qstring_append(str, "\\\\"); -                break; -            case '\b': -                qstring_append(str, "\\b"); -                break; -            case '\f': -                qstring_append(str, "\\f"); -                break; -            case '\n': -                qstring_append(str, "\\n"); -                break; -            case '\r': -                qstring_append(str, "\\r"); -                break; -            case '\t': -                qstring_append(str, "\\t"); -                break; -            default: -                if (cp < 0) { -                    cp = 0xFFFD; /* replacement character */ -                } -                if (cp > 0xFFFF) { -                    /* beyond BMP; need a surrogate pair */ -                    snprintf(buf, sizeof(buf), "\\u%04X\\u%04X", -                             0xD800 + ((cp - 0x10000) >> 10), -                             0xDC00 + ((cp - 0x10000) & 0x3FF)); -                } else if (cp < 0x20 || cp >= 0x7F) { -                    snprintf(buf, sizeof(buf), "\\u%04X", cp); -                } else { -                    buf[0] = cp; -                    buf[1] = 0; -                } -                qstring_append(str, buf); -            } -        }; - -        qstring_append(str, "\""); -        break; -    } -    case QTYPE_QDICT: { -        ToJsonIterState s; -        QDict *val = qobject_to_qdict(obj); - -        s.count = 0; -        s.str = str; -        s.indent = indent + 1; -        s.pretty = pretty; -        qstring_append(str, "{"); -        qdict_iter(val, to_json_dict_iter, &s); -        if (pretty) { -            int j; -            qstring_append(str, "\n"); -            for (j = 0 ; j < indent ; j++) -                qstring_append(str, "    "); -        } -        qstring_append(str, "}"); -        break; -    } -    case QTYPE_QLIST: { -        ToJsonIterState s; -        QList *val = qobject_to_qlist(obj); - -        s.count = 0; -        s.str = str; -        s.indent = indent + 1; -        s.pretty = pretty; -        qstring_append(str, "["); -        qlist_iter(val, (void *)to_json_list_iter, &s); -        if (pretty) { -            int j; -            qstring_append(str, "\n"); -            for (j = 0 ; j < indent ; j++) -                qstring_append(str, "    "); -        } -        qstring_append(str, "]"); -        break; -    } -    case QTYPE_QFLOAT: { -        QFloat *val = qobject_to_qfloat(obj); -        char buffer[1024]; -        int len; - -        len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val)); -        while (len > 0 && buffer[len - 1] == '0') { -            len--; -        } - -        if (len && buffer[len - 1] == '.') { -            buffer[len - 1] = 0; -        } else { -            buffer[len] = 0; -        } -         -        qstring_append(str, buffer); -        break; -    } -    case QTYPE_QBOOL: { -        QBool *val = qobject_to_qbool(obj); - -        if (qbool_get_int(val)) { -            qstring_append(str, "true"); -        } else { -            qstring_append(str, "false"); -        } -        break; -    } -    case QTYPE_QERROR: -        /* XXX: should QError be emitted? */ -    case QTYPE_NONE: -        break; -    } -} - -QString *qobject_to_json(const QObject *obj) -{ -    QString *str = qstring_new(); - -    to_json(obj, str, 0, 0); - -    return str; -} - -QString *qobject_to_json_pretty(const QObject *obj) -{ -    QString *str = qstring_new(); - -    to_json(obj, str, 1, 0); - -    return str; -} diff --git a/contrib/qemu/qobject/qlist.c b/contrib/qemu/qobject/qlist.c deleted file mode 100644 index 1ced0de58e2..00000000000 --- a/contrib/qemu/qobject/qlist.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * QList Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qobject.h" -#include "qemu/queue.h" -#include "qemu-common.h" - -static void qlist_destroy_obj(QObject *obj); - -static const QType qlist_type = { -    .code = QTYPE_QLIST, -    .destroy = qlist_destroy_obj, -}; -  -/** - * qlist_new(): Create a new QList - * - * Return strong reference. - */ -QList *qlist_new(void) -{ -    QList *qlist; - -    qlist = g_malloc(sizeof(*qlist)); -    QTAILQ_INIT(&qlist->head); -    QOBJECT_INIT(qlist, &qlist_type); - -    return qlist; -} - -static void qlist_copy_elem(QObject *obj, void *opaque) -{ -    QList *dst = opaque; - -    qobject_incref(obj); -    qlist_append_obj(dst, obj); -} - -QList *qlist_copy(QList *src) -{ -    QList *dst = qlist_new(); - -    qlist_iter(src, qlist_copy_elem, dst); - -    return dst; -} - -/** - * qlist_append_obj(): Append an QObject into QList - * - * NOTE: ownership of 'value' is transferred to the QList - */ -void qlist_append_obj(QList *qlist, QObject *value) -{ -    QListEntry *entry; - -    entry = g_malloc(sizeof(*entry)); -    entry->value = value; - -    QTAILQ_INSERT_TAIL(&qlist->head, entry, next); -} - -/** - * qlist_iter(): Iterate over all the list's stored values. - * - * This function allows the user to provide an iterator, which will be - * called for each stored value in the list. - */ -void qlist_iter(const QList *qlist, -                void (*iter)(QObject *obj, void *opaque), void *opaque) -{ -    QListEntry *entry; - -    QTAILQ_FOREACH(entry, &qlist->head, next) -        iter(entry->value, opaque); -} - -QObject *qlist_pop(QList *qlist) -{ -    QListEntry *entry; -    QObject *ret; - -    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { -        return NULL; -    } - -    entry = QTAILQ_FIRST(&qlist->head); -    QTAILQ_REMOVE(&qlist->head, entry, next); - -    ret = entry->value; -    g_free(entry); - -    return ret; -} - -QObject *qlist_peek(QList *qlist) -{ -    QListEntry *entry; -    QObject *ret; - -    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { -        return NULL; -    } - -    entry = QTAILQ_FIRST(&qlist->head); - -    ret = entry->value; - -    return ret; -} - -int qlist_empty(const QList *qlist) -{ -    return QTAILQ_EMPTY(&qlist->head); -} - -static void qlist_size_iter(QObject *obj, void *opaque) -{ -    size_t *count = opaque; -    (*count)++; -} - -size_t qlist_size(const QList *qlist) -{ -    size_t count = 0; -    qlist_iter(qlist, qlist_size_iter, &count); -    return count; -} - -/** - * qobject_to_qlist(): Convert a QObject into a QList - */ -QList *qobject_to_qlist(const QObject *obj) -{ -    if (qobject_type(obj) != QTYPE_QLIST) { -        return NULL; -    } - -    return container_of(obj, QList, base); -} - -/** - * qlist_destroy_obj(): Free all the memory allocated by a QList - */ -static void qlist_destroy_obj(QObject *obj) -{ -    QList *qlist; -    QListEntry *entry, *next_entry; - -    assert(obj != NULL); -    qlist = qobject_to_qlist(obj); - -    QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) { -        QTAILQ_REMOVE(&qlist->head, entry, next); -        qobject_decref(entry->value); -        g_free(entry); -    } - -    g_free(qlist); -} diff --git a/contrib/qemu/qobject/qstring.c b/contrib/qemu/qobject/qstring.c deleted file mode 100644 index 607b7a142c6..00000000000 --- a/contrib/qemu/qobject/qstring.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * QString Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - *  Luiz Capitulino <lcapitulino@redhat.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - */ - -#include "qapi/qmp/qobject.h" -#include "qapi/qmp/qstring.h" -#include "qemu-common.h" - -static void qstring_destroy_obj(QObject *obj); - -static const QType qstring_type = { -    .code = QTYPE_QSTRING, -    .destroy = qstring_destroy_obj, -}; - -/** - * qstring_new(): Create a new empty QString - * - * Return strong reference. - */ -QString *qstring_new(void) -{ -    return qstring_from_str(""); -} - -/** - * qstring_get_length(): Get the length of a QString - */ -size_t qstring_get_length(const QString *qstring) -{ -    return qstring->length; -} - -/** - * qstring_from_substr(): Create a new QString from a C string substring - * - * Return string reference - */ -QString *qstring_from_substr(const char *str, int start, int end) -{ -    QString *qstring; - -    qstring = g_malloc(sizeof(*qstring)); - -    qstring->length = end - start + 1; -    qstring->capacity = qstring->length; - -    qstring->string = g_malloc(qstring->capacity + 1); -    memcpy(qstring->string, str + start, qstring->length); -    qstring->string[qstring->length] = 0; - -    QOBJECT_INIT(qstring, &qstring_type); - -    return qstring; -} - -/** - * qstring_from_str(): Create a new QString from a regular C string - * - * Return strong reference. - */ -QString *qstring_from_str(const char *str) -{ -    return qstring_from_substr(str, 0, strlen(str) - 1); -} - -static void capacity_increase(QString *qstring, size_t len) -{ -    if (qstring->capacity < (qstring->length + len)) { -        qstring->capacity += len; -        qstring->capacity *= 2; /* use exponential growth */ - -        qstring->string = g_realloc(qstring->string, qstring->capacity + 1); -    } -} - -/* qstring_append(): Append a C string to a QString - */ -void qstring_append(QString *qstring, const char *str) -{ -    size_t len = strlen(str); - -    capacity_increase(qstring, len); -    memcpy(qstring->string + qstring->length, str, len); -    qstring->length += len; -    qstring->string[qstring->length] = 0; -} - -void qstring_append_int(QString *qstring, int64_t value) -{ -    char num[32]; - -    snprintf(num, sizeof(num), "%" PRId64, value); -    qstring_append(qstring, num); -} - -/** - * qstring_append_chr(): Append a C char to a QString - */ -void qstring_append_chr(QString *qstring, int c) -{ -    capacity_increase(qstring, 1); -    qstring->string[qstring->length++] = c; -    qstring->string[qstring->length] = 0; -} - -/** - * qobject_to_qstring(): Convert a QObject to a QString - */ -QString *qobject_to_qstring(const QObject *obj) -{ -    if (qobject_type(obj) != QTYPE_QSTRING) -        return NULL; - -    return container_of(obj, QString, base); -} - -/** - * qstring_get_str(): Return a pointer to the stored string - * - * NOTE: Should be used with caution, if the object is deallocated - * this pointer becomes invalid. - */ -const char *qstring_get_str(const QString *qstring) -{ -    return qstring->string; -} - -/** - * qstring_destroy_obj(): Free all memory allocated by a QString - * object - */ -static void qstring_destroy_obj(QObject *obj) -{ -    QString *qs; - -    assert(obj != NULL); -    qs = qobject_to_qstring(obj); -    g_free(qs->string); -    g_free(qs); -} diff --git a/contrib/qemu/trace/generated-tracers.h b/contrib/qemu/trace/generated-tracers.h deleted file mode 100644 index b512660f358..00000000000 --- a/contrib/qemu/trace/generated-tracers.h +++ /dev/null @@ -1,3759 +0,0 @@ -/* This file is autogenerated by tracetool, do not edit. */ - -#ifndef TRACE__GENERATED_TRACERS_H -#define TRACE__GENERATED_TRACERS_H - -#include "qemu-common.h" - -static inline void trace_qxl_interface_set_mm_time(int qid, uint32_t mm_time) -{ -} - -static inline void trace_qxl_io_write_vga(int qid, const char * mode, uint32_t addr, uint32_t val) -{ -} - -static inline void trace_g_malloc(size_t size, void * ptr) -{ -} - -static inline void trace_g_realloc(void * ptr, size_t size, void * newptr) -{ -} - -static inline void trace_g_free(void * ptr) -{ -} - -static inline void trace_qemu_memalign(size_t alignment, size_t size, void * ptr) -{ -} - -static inline void trace_qemu_anon_ram_alloc(size_t size, void * ptr) -{ -} - -static inline void trace_qemu_vfree(void * ptr) -{ -} - -static inline void trace_qemu_anon_ram_free(void * ptr, size_t size) -{ -} - -static inline void trace_virtqueue_fill(void * vq, const void * elem, unsigned int len, unsigned int idx) -{ -} - -static inline void trace_virtqueue_flush(void * vq, unsigned int count) -{ -} - -static inline void trace_virtqueue_pop(void * vq, void * elem, unsigned int in_num, unsigned int out_num) -{ -} - -static inline void trace_virtio_queue_notify(void * vdev, int n, void * vq) -{ -} - -static inline void trace_virtio_irq(void * vq) -{ -} - -static inline void trace_virtio_notify(void * vdev, void * vq) -{ -} - -static inline void trace_virtio_set_status(void * vdev, uint8_t val) -{ -} - -static inline void trace_virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) -{ -} - -static inline void trace_virtio_serial_throttle_port(unsigned int port, bool throttle) -{ -} - -static inline void trace_virtio_serial_handle_control_message(uint16_t event, uint16_t value) -{ -} - -static inline void trace_virtio_serial_handle_control_message_port(unsigned int port) -{ -} - -static inline void trace_virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) -{ -} - -static inline void trace_virtio_console_chr_read(unsigned int port, int size) -{ -} - -static inline void trace_virtio_console_chr_event(unsigned int port, int event) -{ -} - -static inline void trace_bdrv_open_common(void * bs, const char * filename, int flags, const char * format_name) -{ -} - -static inline void trace_multiwrite_cb(void * mcb, int ret) -{ -} - -static inline void trace_bdrv_aio_multiwrite(void * mcb, int num_callbacks, int num_reqs) -{ -} - -static inline void trace_bdrv_aio_discard(void * bs, int64_t sector_num, int nb_sectors, void * opaque) -{ -} - -static inline void trace_bdrv_aio_flush(void * bs, void * opaque) -{ -} - -static inline void trace_bdrv_aio_readv(void * bs, int64_t sector_num, int nb_sectors, void * opaque) -{ -} - -static inline void trace_bdrv_aio_writev(void * bs, int64_t sector_num, int nb_sectors, void * opaque) -{ -} - -static inline void trace_bdrv_lock_medium(void * bs, bool locked) -{ -} - -static inline void trace_bdrv_co_readv(void * bs, int64_t sector_num, int nb_sector) -{ -} - -static inline void trace_bdrv_co_copy_on_readv(void * bs, int64_t sector_num, int nb_sector) -{ -} - -static inline void trace_bdrv_co_writev(void * bs, int64_t sector_num, int nb_sector) -{ -} - -static inline void trace_bdrv_co_write_zeroes(void * bs, int64_t sector_num, int nb_sector) -{ -} - -static inline void trace_bdrv_co_io_em(void * bs, int64_t sector_num, int nb_sectors, int is_write, void * acb) -{ -} - -static inline void trace_bdrv_co_do_copy_on_readv(void * bs, int64_t sector_num, int nb_sectors, int64_t cluster_sector_num, int cluster_nb_sectors) -{ -} - -static inline void trace_stream_one_iteration(void * s, int64_t sector_num, int nb_sectors, int is_allocated) -{ -} - -static inline void trace_stream_start(void * bs, void * base, void * s, void * co, void * opaque) -{ -} - -static inline void trace_commit_one_iteration(void * s, int64_t sector_num, int nb_sectors, int is_allocated) -{ -} - -static inline void trace_commit_start(void * bs, void * base, void * top, void * s, void * co, void * opaque) -{ -} - -static inline void trace_mirror_start(void * bs, void * s, void * co, void * opaque) -{ -} - -static inline void trace_mirror_restart_iter(void * s, int64_t cnt) -{ -} - -static inline void trace_mirror_before_flush(void * s) -{ -} - -static inline void trace_mirror_before_drain(void * s, int64_t cnt) -{ -} - -static inline void trace_mirror_before_sleep(void * s, int64_t cnt, int synced) -{ -} - -static inline void trace_mirror_one_iteration(void * s, int64_t sector_num, int nb_sectors) -{ -} - -static inline void trace_mirror_cow(void * s, int64_t sector_num) -{ -} - -static inline void trace_mirror_iteration_done(void * s, int64_t sector_num, int nb_sectors, int ret) -{ -} - -static inline void trace_mirror_yield(void * s, int64_t cnt, int buf_free_count, int in_flight) -{ -} - -static inline void trace_mirror_yield_in_flight(void * s, int64_t sector_num, int in_flight) -{ -} - -static inline void trace_mirror_yield_buf_busy(void * s, int nb_chunks, int in_flight) -{ -} - -static inline void trace_mirror_break_buf_busy(void * s, int nb_chunks, int in_flight) -{ -} - -static inline void trace_backup_do_cow_enter(void * job, int64_t start, int64_t sector_num, int nb_sectors) -{ -} - -static inline void trace_backup_do_cow_return(void * job, int64_t sector_num, int nb_sectors, int ret) -{ -} - -static inline void trace_backup_do_cow_skip(void * job, int64_t start) -{ -} - -static inline void trace_backup_do_cow_process(void * job, int64_t start) -{ -} - -static inline void trace_backup_do_cow_read_fail(void * job, int64_t start, int ret) -{ -} - -static inline void trace_backup_do_cow_write_fail(void * job, int64_t start, int ret) -{ -} - -static inline void trace_qmp_block_job_cancel(void * job) -{ -} - -static inline void trace_qmp_block_job_pause(void * job) -{ -} - -static inline void trace_qmp_block_job_resume(void * job) -{ -} - -static inline void trace_qmp_block_job_complete(void * job) -{ -} - -static inline void trace_block_job_cb(void * bs, void * job, int ret) -{ -} - -static inline void trace_qmp_block_stream(void * bs, void * job) -{ -} - -static inline void trace_virtio_blk_req_complete(void * req, int status) -{ -} - -static inline void trace_virtio_blk_rw_complete(void * req, int ret) -{ -} - -static inline void trace_virtio_blk_handle_write(void * req, uint64_t sector, size_t nsectors) -{ -} - -static inline void trace_virtio_blk_handle_read(void * req, uint64_t sector, size_t nsectors) -{ -} - -static inline void trace_virtio_blk_data_plane_start(void * s) -{ -} - -static inline void trace_virtio_blk_data_plane_stop(void * s) -{ -} - -static inline void trace_virtio_blk_data_plane_process_request(void * s, unsigned int out_num, unsigned int in_num, unsigned int head) -{ -} - -static inline void trace_virtio_blk_data_plane_complete_request(void * s, unsigned int head, int ret) -{ -} - -static inline void trace_vring_setup(uint64_t physical, void * desc, void * avail, void * used) -{ -} - -static inline void trace_thread_pool_submit(void * pool, void * req, void * opaque) -{ -} - -static inline void trace_thread_pool_complete(void * pool, void * req, void * opaque, int ret) -{ -} - -static inline void trace_thread_pool_cancel(void * req, void * opaque) -{ -} - -static inline void trace_paio_submit(void * acb, void * opaque, int64_t sector_num, int nb_sectors, int type) -{ -} - -static inline void trace_paio_complete(void * acb, void * opaque, int ret) -{ -} - -static inline void trace_paio_cancel(void * acb, void * opaque) -{ -} - -static inline void trace_cpu_in(unsigned int addr, unsigned int val) -{ -} - -static inline void trace_cpu_out(unsigned int addr, unsigned int val) -{ -} - -static inline void trace_balloon_event(void * opaque, unsigned long addr) -{ -} - -static inline void trace_apic_local_deliver(int vector, uint32_t lvt) -{ -} - -static inline void trace_apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) -{ -} - -static inline void trace_cpu_set_apic_base(uint64_t val) -{ -} - -static inline void trace_cpu_get_apic_base(uint64_t val) -{ -} - -static inline void trace_apic_mem_readl(uint64_t addr, uint32_t val) -{ -} - -static inline void trace_apic_mem_writel(uint64_t addr, uint32_t val) -{ -} - -static inline void trace_apic_report_irq_delivered(int apic_irq_delivered) -{ -} - -static inline void trace_apic_reset_irq_delivered(int apic_irq_delivered) -{ -} - -static inline void trace_apic_get_irq_delivered(int apic_irq_delivered) -{ -} - -static inline void trace_cs4231_mem_readl_dreg(uint32_t reg, uint32_t ret) -{ -} - -static inline void trace_cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) -{ -} - -static inline void trace_cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) -{ -} - -static inline void trace_cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) -{ -} - -static inline void trace_nvram_read(uint32_t addr, uint32_t ret) -{ -} - -static inline void trace_nvram_write(uint32_t addr, uint32_t old, uint32_t val) -{ -} - -static inline void trace_ecc_mem_writel_mer(uint32_t val) -{ -} - -static inline void trace_ecc_mem_writel_mdr(uint32_t val) -{ -} - -static inline void trace_ecc_mem_writel_mfsr(uint32_t val) -{ -} - -static inline void trace_ecc_mem_writel_vcr(uint32_t val) -{ -} - -static inline void trace_ecc_mem_writel_dr(uint32_t val) -{ -} - -static inline void trace_ecc_mem_writel_ecr0(uint32_t val) -{ -} - -static inline void trace_ecc_mem_writel_ecr1(uint32_t val) -{ -} - -static inline void trace_ecc_mem_readl_mer(uint32_t ret) -{ -} - -static inline void trace_ecc_mem_readl_mdr(uint32_t ret) -{ -} - -static inline void trace_ecc_mem_readl_mfsr(uint32_t ret) -{ -} - -static inline void trace_ecc_mem_readl_vcr(uint32_t ret) -{ -} - -static inline void trace_ecc_mem_readl_mfar0(uint32_t ret) -{ -} - -static inline void trace_ecc_mem_readl_mfar1(uint32_t ret) -{ -} - -static inline void trace_ecc_mem_readl_dr(uint32_t ret) -{ -} - -static inline void trace_ecc_mem_readl_ecr0(uint32_t ret) -{ -} - -static inline void trace_ecc_mem_readl_ecr1(uint32_t ret) -{ -} - -static inline void trace_ecc_diag_mem_writeb(uint64_t addr, uint32_t val) -{ -} - -static inline void trace_ecc_diag_mem_readb(uint64_t addr, uint32_t ret) -{ -} - -static inline void trace_fw_cfg_write(void * s, uint8_t value) -{ -} - -static inline void trace_fw_cfg_select(void * s, uint16_t key, int ret) -{ -} - -static inline void trace_fw_cfg_read(void * s, uint8_t ret) -{ -} - -static inline void trace_fw_cfg_add_file_dupe(void * s, char * name) -{ -} - -static inline void trace_fw_cfg_add_file(void * s, int index, char * name, size_t len) -{ -} - -static inline void trace_hd_geometry_lchs_guess(void * bs, int cyls, int heads, int secs) -{ -} - -static inline void trace_hd_geometry_guess(void * bs, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) -{ -} - -static inline void trace_jazz_led_read(uint64_t addr, uint8_t val) -{ -} - -static inline void trace_jazz_led_write(uint64_t addr, uint8_t new) -{ -} - -static inline void trace_lance_mem_readw(uint64_t addr, uint32_t ret) -{ -} - -static inline void trace_lance_mem_writew(uint64_t addr, uint32_t val) -{ -} - -static inline void trace_slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) -{ -} - -static inline void trace_slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val) -{ -} - -static inline void trace_slavio_intctl_mem_writel_clear(uint32_t cpu, uint32_t val, uint32_t intreg_pending) -{ -} - -static inline void trace_slavio_intctl_mem_writel_set(uint32_t cpu, uint32_t val, uint32_t intreg_pending) -{ -} - -static inline void trace_slavio_intctlm_mem_readl(uint64_t addr, uint32_t ret) -{ -} - -static inline void trace_slavio_intctlm_mem_writel(uint64_t addr, uint32_t val) -{ -} - -static inline void trace_slavio_intctlm_mem_writel_enable(uint32_t val, uint32_t intregm_disabled) -{ -} - -static inline void trace_slavio_intctlm_mem_writel_disable(uint32_t val, uint32_t intregm_disabled) -{ -} - -static inline void trace_slavio_intctlm_mem_writel_target(uint32_t cpu) -{ -} - -static inline void trace_slavio_check_interrupts(uint32_t pending, uint32_t intregm_disabled) -{ -} - -static inline void trace_slavio_set_irq(uint32_t target_cpu, int irq, uint32_t pil, int level) -{ -} - -static inline void trace_slavio_set_timer_irq_cpu(int cpu, int level) -{ -} - -static inline void trace_slavio_misc_update_irq_raise(void) -{ -} - -static inline void trace_slavio_misc_update_irq_lower(void) -{ -} - -static inline void trace_slavio_set_power_fail(int power_failing, uint8_t config) -{ -} - -static inline void trace_slavio_cfg_mem_writeb(uint32_t val) -{ -} - -static inline void trace_slavio_cfg_mem_readb(uint32_t ret) -{ -} - -static inline void trace_slavio_diag_mem_writeb(uint32_t val) -{ -} - -static inline void trace_slavio_diag_mem_readb(uint32_t ret) -{ -} - -static inline void trace_slavio_mdm_mem_writeb(uint32_t val) -{ -} - -static inline void trace_slavio_mdm_mem_readb(uint32_t ret) -{ -} - -static inline void trace_slavio_aux1_mem_writeb(uint32_t val) -{ -} - -static inline void trace_slavio_aux1_mem_readb(uint32_t ret) -{ -} - -static inline void trace_slavio_aux2_mem_writeb(uint32_t val) -{ -} - -static inline void trace_slavio_aux2_mem_readb(uint32_t ret) -{ -} - -static inline void trace_apc_mem_writeb(uint32_t val) -{ -} - -static inline void trace_apc_mem_readb(uint32_t ret) -{ -} - -static inline void trace_slavio_sysctrl_mem_writel(uint32_t val) -{ -} - -static inline void trace_slavio_sysctrl_mem_readl(uint32_t ret) -{ -} - -static inline void trace_slavio_led_mem_writew(uint32_t val) -{ -} - -static inline void trace_slavio_led_mem_readw(uint32_t ret) -{ -} - -static inline void trace_slavio_timer_get_out(uint64_t limit, uint32_t counthigh, uint32_t count) -{ -} - -static inline void trace_slavio_timer_irq(uint32_t counthigh, uint32_t count) -{ -} - -static inline void trace_slavio_timer_mem_readl_invalid(uint64_t addr) -{ -} - -static inline void trace_slavio_timer_mem_readl(uint64_t addr, uint32_t ret) -{ -} - -static inline void trace_slavio_timer_mem_writel(uint64_t addr, uint32_t val) -{ -} - -static inline void trace_slavio_timer_mem_writel_limit(unsigned int timer_index, uint64_t count) -{ -} - -static inline void trace_slavio_timer_mem_writel_counter_invalid(void) -{ -} - -static inline void trace_slavio_timer_mem_writel_status_start(unsigned int timer_index) -{ -} - -static inline void trace_slavio_timer_mem_writel_status_stop(unsigned int timer_index) -{ -} - -static inline void trace_slavio_timer_mem_writel_mode_user(unsigned int timer_index) -{ -} - -static inline void trace_slavio_timer_mem_writel_mode_counter(unsigned int timer_index) -{ -} - -static inline void trace_slavio_timer_mem_writel_mode_invalid(void) -{ -} - -static inline void trace_slavio_timer_mem_writel_invalid(uint64_t addr) -{ -} - -static inline void trace_ledma_memory_read(uint64_t addr) -{ -} - -static inline void trace_ledma_memory_write(uint64_t addr) -{ -} - -static inline void trace_sparc32_dma_set_irq_raise(void) -{ -} - -static inline void trace_sparc32_dma_set_irq_lower(void) -{ -} - -static inline void trace_espdma_memory_read(uint32_t addr) -{ -} - -static inline void trace_espdma_memory_write(uint32_t addr) -{ -} - -static inline void trace_sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) -{ -} - -static inline void trace_sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) -{ -} - -static inline void trace_sparc32_dma_enable_raise(void) -{ -} - -static inline void trace_sparc32_dma_enable_lower(void) -{ -} - -static inline void trace_sun4m_cpu_interrupt(unsigned int level) -{ -} - -static inline void trace_sun4m_cpu_reset_interrupt(unsigned int level) -{ -} - -static inline void trace_sun4m_cpu_set_irq_raise(int level) -{ -} - -static inline void trace_sun4m_cpu_set_irq_lower(int level) -{ -} - -static inline void trace_sun4m_iommu_mem_readl(uint64_t addr, uint32_t ret) -{ -} - -static inline void trace_sun4m_iommu_mem_writel(uint64_t addr, uint32_t val) -{ -} - -static inline void trace_sun4m_iommu_mem_writel_ctrl(uint64_t iostart) -{ -} - -static inline void trace_sun4m_iommu_mem_writel_tlbflush(uint32_t val) -{ -} - -static inline void trace_sun4m_iommu_mem_writel_pgflush(uint32_t val) -{ -} - -static inline void trace_sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) -{ -} - -static inline void trace_sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) -{ -} - -static inline void trace_sun4m_iommu_bad_addr(uint64_t addr) -{ -} - -static inline void trace_usb_packet_state_change(int bus, const char * port, int ep, void * p, const char * o, const char * n) -{ -} - -static inline void trace_usb_packet_state_fault(int bus, const char * port, int ep, void * p, const char * o, const char * n) -{ -} - -static inline void trace_usb_port_claim(int bus, const char * port) -{ -} - -static inline void trace_usb_port_attach(int bus, const char * port, const char * devspeed, const char * portspeed) -{ -} - -static inline void trace_usb_port_detach(int bus, const char * port) -{ -} - -static inline void trace_usb_port_release(int bus, const char * port) -{ -} - -static inline void trace_usb_ehci_reset(void) -{ -} - -static inline void trace_usb_ehci_opreg_read(uint32_t addr, const char * str, uint32_t val) -{ -} - -static inline void trace_usb_ehci_opreg_write(uint32_t addr, const char * str, uint32_t val) -{ -} - -static inline void trace_usb_ehci_opreg_change(uint32_t addr, const char * str, uint32_t new, uint32_t old) -{ -} - -static inline void trace_usb_ehci_portsc_read(uint32_t addr, uint32_t port, uint32_t val) -{ -} - -static inline void trace_usb_ehci_portsc_write(uint32_t addr, uint32_t port, uint32_t val) -{ -} - -static inline void trace_usb_ehci_portsc_change(uint32_t addr, uint32_t port, uint32_t new, uint32_t old) -{ -} - -static inline void trace_usb_ehci_usbsts(const char * sts, int state) -{ -} - -static inline void trace_usb_ehci_state(const char * schedule, const char * state) -{ -} - -static inline void trace_usb_ehci_qh_ptrs(void * q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) -{ -} - -static inline void trace_usb_ehci_qh_fields(uint32_t addr, int rl, int mplen, int eps, int ep, int devaddr) -{ -} - -static inline void trace_usb_ehci_qh_bits(uint32_t addr, int c, int h, int dtc, int i) -{ -} - -static inline void trace_usb_ehci_qtd_ptrs(void * q, uint32_t addr, uint32_t nxt, uint32_t altnext) -{ -} - -static inline void trace_usb_ehci_qtd_fields(uint32_t addr, int tbytes, int cpage, int cerr, int pid) -{ -} - -static inline void trace_usb_ehci_qtd_bits(uint32_t addr, int ioc, int active, int halt, int babble, int xacterr) -{ -} - -static inline void trace_usb_ehci_itd(uint32_t addr, uint32_t nxt, uint32_t mplen, uint32_t mult, uint32_t ep, uint32_t devaddr) -{ -} - -static inline void trace_usb_ehci_sitd(uint32_t addr, uint32_t nxt, uint32_t active) -{ -} - -static inline void trace_usb_ehci_port_attach(uint32_t port, const char * owner, const char * device) -{ -} - -static inline void trace_usb_ehci_port_detach(uint32_t port, const char * owner) -{ -} - -static inline void trace_usb_ehci_port_reset(uint32_t port, int enable) -{ -} - -static inline void trace_usb_ehci_data(int rw, uint32_t cpage, uint32_t offset, uint32_t addr, uint32_t len, uint32_t bufpos) -{ -} - -static inline void trace_usb_ehci_queue_action(void * q, const char * action) -{ -} - -static inline void trace_usb_ehci_packet_action(void * q, void * p, const char * action) -{ -} - -static inline void trace_usb_ehci_irq(uint32_t level, uint32_t frindex, uint32_t sts, uint32_t mask) -{ -} - -static inline void trace_usb_ehci_guest_bug(const char * reason) -{ -} - -static inline void trace_usb_ehci_doorbell_ring(void) -{ -} - -static inline void trace_usb_ehci_doorbell_ack(void) -{ -} - -static inline void trace_usb_ehci_dma_error(void) -{ -} - -static inline void trace_usb_uhci_reset(void) -{ -} - -static inline void trace_usb_uhci_schedule_start(void) -{ -} - -static inline void trace_usb_uhci_schedule_stop(void) -{ -} - -static inline void trace_usb_uhci_frame_start(uint32_t num) -{ -} - -static inline void trace_usb_uhci_frame_stop_bandwidth(void) -{ -} - -static inline void trace_usb_uhci_frame_loop_stop_idle(void) -{ -} - -static inline void trace_usb_uhci_frame_loop_continue(void) -{ -} - -static inline void trace_usb_uhci_mmio_readw(uint32_t addr, uint32_t val) -{ -} - -static inline void trace_usb_uhci_mmio_writew(uint32_t addr, uint32_t val) -{ -} - -static inline void trace_usb_uhci_queue_add(uint32_t token) -{ -} - -static inline void trace_usb_uhci_queue_del(uint32_t token, const char * reason) -{ -} - -static inline void trace_usb_uhci_packet_add(uint32_t token, uint32_t addr) -{ -} - -static inline void trace_usb_uhci_packet_link_async(uint32_t token, uint32_t addr) -{ -} - -static inline void trace_usb_uhci_packet_unlink_async(uint32_t token, uint32_t addr) -{ -} - -static inline void trace_usb_uhci_packet_cancel(uint32_t token, uint32_t addr, int done) -{ -} - -static inline void trace_usb_uhci_packet_complete_success(uint32_t token, uint32_t addr) -{ -} - -static inline void trace_usb_uhci_packet_complete_shortxfer(uint32_t token, uint32_t addr) -{ -} - -static inline void trace_usb_uhci_packet_complete_stall(uint32_t token, uint32_t addr) -{ -} - -static inline void trace_usb_uhci_packet_complete_babble(uint32_t token, uint32_t addr) -{ -} - -static inline void trace_usb_uhci_packet_complete_error(uint32_t token, uint32_t addr) -{ -} - -static inline void trace_usb_uhci_packet_del(uint32_t token, uint32_t addr) -{ -} - -static inline void trace_usb_uhci_qh_load(uint32_t qh) -{ -} - -static inline void trace_usb_uhci_td_load(uint32_t qh, uint32_t td, uint32_t ctrl, uint32_t token) -{ -} - -static inline void trace_usb_uhci_td_queue(uint32_t td, uint32_t ctrl, uint32_t token) -{ -} - -static inline void trace_usb_uhci_td_nextqh(uint32_t qh, uint32_t td) -{ -} - -static inline void trace_usb_uhci_td_async(uint32_t qh, uint32_t td) -{ -} - -static inline void trace_usb_uhci_td_complete(uint32_t qh, uint32_t td) -{ -} - -static inline void trace_usb_xhci_reset(void) -{ -} - -static inline void trace_usb_xhci_run(void) -{ -} - -static inline void trace_usb_xhci_stop(void) -{ -} - -static inline void trace_usb_xhci_cap_read(uint32_t off, uint32_t val) -{ -} - -static inline void trace_usb_xhci_oper_read(uint32_t off, uint32_t val) -{ -} - -static inline void trace_usb_xhci_port_read(uint32_t port, uint32_t off, uint32_t val) -{ -} - -static inline void trace_usb_xhci_runtime_read(uint32_t off, uint32_t val) -{ -} - -static inline void trace_usb_xhci_doorbell_read(uint32_t off, uint32_t val) -{ -} - -static inline void trace_usb_xhci_oper_write(uint32_t off, uint32_t val) -{ -} - -static inline void trace_usb_xhci_port_write(uint32_t port, uint32_t off, uint32_t val) -{ -} - -static inline void trace_usb_xhci_runtime_write(uint32_t off, uint32_t val) -{ -} - -static inline void trace_usb_xhci_doorbell_write(uint32_t off, uint32_t val) -{ -} - -static inline void trace_usb_xhci_irq_intx(uint32_t level) -{ -} - -static inline void trace_usb_xhci_irq_msi(uint32_t nr) -{ -} - -static inline void trace_usb_xhci_irq_msix(uint32_t nr) -{ -} - -static inline void trace_usb_xhci_irq_msix_use(uint32_t nr) -{ -} - -static inline void trace_usb_xhci_irq_msix_unuse(uint32_t nr) -{ -} - -static inline void trace_usb_xhci_queue_event(uint32_t vector, uint32_t idx, const char * trb, const char * evt, uint64_t param, uint32_t status, uint32_t control) -{ -} - -static inline void trace_usb_xhci_fetch_trb(uint64_t addr, const char * name, uint64_t param, uint32_t status, uint32_t control) -{ -} - -static inline void trace_usb_xhci_port_reset(uint32_t port) -{ -} - -static inline void trace_usb_xhci_port_link(uint32_t port, uint32_t pls) -{ -} - -static inline void trace_usb_xhci_port_notify(uint32_t port, uint32_t pls) -{ -} - -static inline void trace_usb_xhci_slot_enable(uint32_t slotid) -{ -} - -static inline void trace_usb_xhci_slot_disable(uint32_t slotid) -{ -} - -static inline void trace_usb_xhci_slot_address(uint32_t slotid) -{ -} - -static inline void trace_usb_xhci_slot_configure(uint32_t slotid) -{ -} - -static inline void trace_usb_xhci_slot_evaluate(uint32_t slotid) -{ -} - -static inline void trace_usb_xhci_slot_reset(uint32_t slotid) -{ -} - -static inline void trace_usb_xhci_ep_enable(uint32_t slotid, uint32_t epid) -{ -} - -static inline void trace_usb_xhci_ep_disable(uint32_t slotid, uint32_t epid) -{ -} - -static inline void trace_usb_xhci_ep_set_dequeue(uint32_t slotid, uint32_t epid, uint32_t streamid, uint64_t param) -{ -} - -static inline void trace_usb_xhci_ep_kick(uint32_t slotid, uint32_t epid, uint32_t streamid) -{ -} - -static inline void trace_usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) -{ -} - -static inline void trace_usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) -{ -} - -static inline void trace_usb_xhci_xfer_start(void * xfer, uint32_t slotid, uint32_t epid, uint32_t streamid) -{ -} - -static inline void trace_usb_xhci_xfer_async(void * xfer) -{ -} - -static inline void trace_usb_xhci_xfer_nak(void * xfer) -{ -} - -static inline void trace_usb_xhci_xfer_retry(void * xfer) -{ -} - -static inline void trace_usb_xhci_xfer_success(void * xfer, uint32_t bytes) -{ -} - -static inline void trace_usb_xhci_xfer_error(void * xfer, uint32_t ret) -{ -} - -static inline void trace_usb_xhci_unimplemented(const char * item, int nr) -{ -} - -static inline void trace_usb_desc_device(int addr, int len, int ret) -{ -} - -static inline void trace_usb_desc_device_qualifier(int addr, int len, int ret) -{ -} - -static inline void trace_usb_desc_config(int addr, int index, int len, int ret) -{ -} - -static inline void trace_usb_desc_other_speed_config(int addr, int index, int len, int ret) -{ -} - -static inline void trace_usb_desc_string(int addr, int index, int len, int ret) -{ -} - -static inline void trace_usb_desc_bos(int addr, int len, int ret) -{ -} - -static inline void trace_usb_set_addr(int addr) -{ -} - -static inline void trace_usb_set_config(int addr, int config, int ret) -{ -} - -static inline void trace_usb_set_interface(int addr, int iface, int alt, int ret) -{ -} - -static inline void trace_usb_clear_device_feature(int addr, int feature, int ret) -{ -} - -static inline void trace_usb_set_device_feature(int addr, int feature, int ret) -{ -} - -static inline void trace_usb_hub_reset(int addr) -{ -} - -static inline void trace_usb_hub_control(int addr, int request, int value, int index, int length) -{ -} - -static inline void trace_usb_hub_get_port_status(int addr, int nr, int status, int changed) -{ -} - -static inline void trace_usb_hub_set_port_feature(int addr, int nr, const char * f) -{ -} - -static inline void trace_usb_hub_clear_port_feature(int addr, int nr, const char * f) -{ -} - -static inline void trace_usb_hub_attach(int addr, int nr) -{ -} - -static inline void trace_usb_hub_detach(int addr, int nr) -{ -} - -static inline void trace_usb_uas_reset(int addr) -{ -} - -static inline void trace_usb_uas_command(int addr, uint16_t tag, int lun, uint32_t lun64_1, uint32_t lun64_2) -{ -} - -static inline void trace_usb_uas_response(int addr, uint16_t tag, uint8_t code) -{ -} - -static inline void trace_usb_uas_sense(int addr, uint16_t tag, uint8_t status) -{ -} - -static inline void trace_usb_uas_read_ready(int addr, uint16_t tag) -{ -} - -static inline void trace_usb_uas_write_ready(int addr, uint16_t tag) -{ -} - -static inline void trace_usb_uas_xfer_data(int addr, uint16_t tag, uint32_t copy, uint32_t uoff, uint32_t usize, uint32_t soff, uint32_t ssize) -{ -} - -static inline void trace_usb_uas_scsi_data(int addr, uint16_t tag, uint32_t bytes) -{ -} - -static inline void trace_usb_uas_scsi_complete(int addr, uint16_t tag, uint32_t status, uint32_t resid) -{ -} - -static inline void trace_usb_uas_tmf_abort_task(int addr, uint16_t tag, uint16_t task_tag) -{ -} - -static inline void trace_usb_uas_tmf_logical_unit_reset(int addr, uint16_t tag, int lun) -{ -} - -static inline void trace_usb_uas_tmf_unsupported(int addr, uint16_t tag, uint32_t function) -{ -} - -static inline void trace_usb_host_open_started(int bus, int addr) -{ -} - -static inline void trace_usb_host_open_success(int bus, int addr) -{ -} - -static inline void trace_usb_host_open_failure(int bus, int addr) -{ -} - -static inline void trace_usb_host_disconnect(int bus, int addr) -{ -} - -static inline void trace_usb_host_close(int bus, int addr) -{ -} - -static inline void trace_usb_host_attach_kernel(int bus, int addr, int interface) -{ -} - -static inline void trace_usb_host_detach_kernel(int bus, int addr, int interface) -{ -} - -static inline void trace_usb_host_set_address(int bus, int addr, int config) -{ -} - -static inline void trace_usb_host_set_config(int bus, int addr, int config) -{ -} - -static inline void trace_usb_host_set_interface(int bus, int addr, int interface, int alt) -{ -} - -static inline void trace_usb_host_claim_interfaces(int bus, int addr, int config, int nif) -{ -} - -static inline void trace_usb_host_claim_interface(int bus, int addr, int config, int interface) -{ -} - -static inline void trace_usb_host_release_interfaces(int bus, int addr) -{ -} - -static inline void trace_usb_host_release_interface(int bus, int addr, int interface) -{ -} - -static inline void trace_usb_host_req_control(int bus, int addr, void * p, int req, int value, int index) -{ -} - -static inline void trace_usb_host_req_data(int bus, int addr, void * p, int in, int ep, int size) -{ -} - -static inline void trace_usb_host_req_complete(int bus, int addr, void * p, int status, int length) -{ -} - -static inline void trace_usb_host_req_emulated(int bus, int addr, void * p, int status) -{ -} - -static inline void trace_usb_host_req_canceled(int bus, int addr, void * p) -{ -} - -static inline void trace_usb_host_urb_submit(int bus, int addr, void * aurb, int length, int more) -{ -} - -static inline void trace_usb_host_urb_complete(int bus, int addr, void * aurb, int status, int length, int more) -{ -} - -static inline void trace_usb_host_urb_canceled(int bus, int addr, void * aurb) -{ -} - -static inline void trace_usb_host_ep_set_halt(int bus, int addr, int ep) -{ -} - -static inline void trace_usb_host_ep_clear_halt(int bus, int addr, int ep) -{ -} - -static inline void trace_usb_host_iso_start(int bus, int addr, int ep) -{ -} - -static inline void trace_usb_host_iso_stop(int bus, int addr, int ep) -{ -} - -static inline void trace_usb_host_iso_out_of_bufs(int bus, int addr, int ep) -{ -} - -static inline void trace_usb_host_iso_many_urbs(int bus, int addr, int count) -{ -} - -static inline void trace_usb_host_reset(int bus, int addr) -{ -} - -static inline void trace_usb_host_auto_scan_enabled(void) -{ -} - -static inline void trace_usb_host_auto_scan_disabled(void) -{ -} - -static inline void trace_usb_host_claim_port(int bus, int hub, int port) -{ -} - -static inline void trace_usb_host_parse_device(int bus, int addr, int vendor, int product) -{ -} - -static inline void trace_usb_host_parse_config(int bus, int addr, int value, int active) -{ -} - -static inline void trace_usb_host_parse_interface(int bus, int addr, int num, int alt, int active) -{ -} - -static inline void trace_usb_host_parse_endpoint(int bus, int addr, int ep, const char * dir, const char * type, int active) -{ -} - -static inline void trace_usb_host_parse_unknown(int bus, int addr, int len, int type) -{ -} - -static inline void trace_usb_host_parse_error(int bus, int addr, const char * errmsg) -{ -} - -static inline void trace_scsi_req_alloc(int target, int lun, int tag) -{ -} - -static inline void trace_scsi_req_cancel(int target, int lun, int tag) -{ -} - -static inline void trace_scsi_req_data(int target, int lun, int tag, int len) -{ -} - -static inline void trace_scsi_req_data_canceled(int target, int lun, int tag, int len) -{ -} - -static inline void trace_scsi_req_dequeue(int target, int lun, int tag) -{ -} - -static inline void trace_scsi_req_continue(int target, int lun, int tag) -{ -} - -static inline void trace_scsi_req_continue_canceled(int target, int lun, int tag) -{ -} - -static inline void trace_scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) -{ -} - -static inline void trace_scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) -{ -} - -static inline void trace_scsi_req_parse_bad(int target, int lun, int tag, int cmd) -{ -} - -static inline void trace_scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) -{ -} - -static inline void trace_scsi_device_set_ua(int target, int lun, int key, int asc, int ascq) -{ -} - -static inline void trace_scsi_report_luns(int target, int lun, int tag) -{ -} - -static inline void trace_scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2) -{ -} - -static inline void trace_scsi_test_unit_ready(int target, int lun, int tag) -{ -} - -static inline void trace_scsi_request_sense(int target, int lun, int tag) -{ -} - -static inline void trace_vm_state_notify(int running, int reason) -{ -} - -static inline void trace_load_file(const char * name, const char * path) -{ -} - -static inline void trace_runstate_set(int new_state) -{ -} - -static inline void trace_qcow2_writev_start_req(void * co, int64_t sector, int nb_sectors) -{ -} - -static inline void trace_qcow2_writev_done_req(void * co, int ret) -{ -} - -static inline void trace_qcow2_writev_start_part(void * co) -{ -} - -static inline void trace_qcow2_writev_done_part(void * co, int cur_nr_sectors) -{ -} - -static inline void trace_qcow2_writev_data(void * co, uint64_t offset) -{ -} - -static inline void trace_qcow2_alloc_clusters_offset(void * co, uint64_t offset, int n_start, int n_end) -{ -} - -static inline void trace_qcow2_handle_copied(void * co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) -{ -} - -static inline void trace_qcow2_handle_alloc(void * co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) -{ -} - -static inline void trace_qcow2_do_alloc_clusters_offset(void * co, uint64_t guest_offset, uint64_t host_offset, int nb_clusters) -{ -} - -static inline void trace_qcow2_cluster_alloc_phys(void * co) -{ -} - -static inline void trace_qcow2_cluster_link_l2(void * co, int nb_clusters) -{ -} - -static inline void trace_qcow2_l2_allocate(void * bs, int l1_index) -{ -} - -static inline void trace_qcow2_l2_allocate_get_empty(void * bs, int l1_index) -{ -} - -static inline void trace_qcow2_l2_allocate_write_l2(void * bs, int l1_index) -{ -} - -static inline void trace_qcow2_l2_allocate_write_l1(void * bs, int l1_index) -{ -} - -static inline void trace_qcow2_l2_allocate_done(void * bs, int l1_index, int ret) -{ -} - -static inline void trace_qcow2_cache_get(void * co, int c, uint64_t offset, bool read_from_disk) -{ -} - -static inline void trace_qcow2_cache_get_replace_entry(void * co, int c, int i) -{ -} - -static inline void trace_qcow2_cache_get_read(void * co, int c, int i) -{ -} - -static inline void trace_qcow2_cache_get_done(void * co, int c, int i) -{ -} - -static inline void trace_qcow2_cache_flush(void * co, int c) -{ -} - -static inline void trace_qcow2_cache_entry_flush(void * co, int c, int i) -{ -} - -static inline void trace_qed_alloc_l2_cache_entry(void * l2_cache, void * entry) -{ -} - -static inline void trace_qed_unref_l2_cache_entry(void * entry, int ref) -{ -} - -static inline void trace_qed_find_l2_cache_entry(void * l2_cache, void * entry, uint64_t offset, int ref) -{ -} - -static inline void trace_qed_read_table(void * s, uint64_t offset, void * table) -{ -} - -static inline void trace_qed_read_table_cb(void * s, void * table, int ret) -{ -} - -static inline void trace_qed_write_table(void * s, uint64_t offset, void * table, unsigned int index, unsigned int n) -{ -} - -static inline void trace_qed_write_table_cb(void * s, void * table, int flush, int ret) -{ -} - -static inline void trace_qed_need_check_timer_cb(void * s) -{ -} - -static inline void trace_qed_start_need_check_timer(void * s) -{ -} - -static inline void trace_qed_cancel_need_check_timer(void * s) -{ -} - -static inline void trace_qed_aio_complete(void * s, void * acb, int ret) -{ -} - -static inline void trace_qed_aio_setup(void * s, void * acb, int64_t sector_num, int nb_sectors, void * opaque, int flags) -{ -} - -static inline void trace_qed_aio_next_io(void * s, void * acb, int ret, uint64_t cur_pos) -{ -} - -static inline void trace_qed_aio_read_data(void * s, void * acb, int ret, uint64_t offset, size_t len) -{ -} - -static inline void trace_qed_aio_write_data(void * s, void * acb, int ret, uint64_t offset, size_t len) -{ -} - -static inline void trace_qed_aio_write_prefill(void * s, void * acb, uint64_t start, size_t len, uint64_t offset) -{ -} - -static inline void trace_qed_aio_write_postfill(void * s, void * acb, uint64_t start, size_t len, uint64_t offset) -{ -} - -static inline void trace_qed_aio_write_main(void * s, void * acb, int ret, uint64_t offset, size_t len) -{ -} - -static inline void trace_g364fb_read(uint64_t addr, uint32_t val) -{ -} - -static inline void trace_g364fb_write(uint64_t addr, uint32_t new) -{ -} - -static inline void trace_grlib_gptimer_enable(int id, uint32_t count) -{ -} - -static inline void trace_grlib_gptimer_disabled(int id, uint32_t config) -{ -} - -static inline void trace_grlib_gptimer_restart(int id, uint32_t reload) -{ -} - -static inline void trace_grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) -{ -} - -static inline void trace_grlib_gptimer_hit(int id) -{ -} - -static inline void trace_grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) -{ -} - -static inline void trace_grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) -{ -} - -static inline void trace_grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) -{ -} - -static inline void trace_grlib_irqmp_ack(int intno) -{ -} - -static inline void trace_grlib_irqmp_set_irq(int irq) -{ -} - -static inline void trace_grlib_irqmp_readl_unknown(uint64_t addr) -{ -} - -static inline void trace_grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) -{ -} - -static inline void trace_grlib_apbuart_event(int event) -{ -} - -static inline void trace_grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) -{ -} - -static inline void trace_grlib_apbuart_readl_unknown(uint64_t addr) -{ -} - -static inline void trace_leon3_set_irq(int intno) -{ -} - -static inline void trace_leon3_reset_irq(int intno) -{ -} - -static inline void trace_spice_vmc_write(ssize_t out, int len) -{ -} - -static inline void trace_spice_vmc_read(int bytes, int len) -{ -} - -static inline void trace_spice_vmc_register_interface(void * scd) -{ -} - -static inline void trace_spice_vmc_unregister_interface(void * scd) -{ -} - -static inline void trace_spice_vmc_event(int event) -{ -} - -static inline void trace_lm32_pic_raise_irq(void) -{ -} - -static inline void trace_lm32_pic_lower_irq(void) -{ -} - -static inline void trace_lm32_pic_interrupt(int irq, int level) -{ -} - -static inline void trace_lm32_pic_set_im(uint32_t im) -{ -} - -static inline void trace_lm32_pic_set_ip(uint32_t ip) -{ -} - -static inline void trace_lm32_pic_get_im(uint32_t im) -{ -} - -static inline void trace_lm32_pic_get_ip(uint32_t ip) -{ -} - -static inline void trace_lm32_juart_get_jtx(uint32_t value) -{ -} - -static inline void trace_lm32_juart_set_jtx(uint32_t value) -{ -} - -static inline void trace_lm32_juart_get_jrx(uint32_t value) -{ -} - -static inline void trace_lm32_juart_set_jrx(uint32_t value) -{ -} - -static inline void trace_lm32_timer_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_lm32_timer_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_lm32_timer_hit(void) -{ -} - -static inline void trace_lm32_timer_irq_state(int level) -{ -} - -static inline void trace_lm32_uart_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_lm32_uart_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_lm32_uart_irq_state(int level) -{ -} - -static inline void trace_lm32_sys_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_megasas_init_firmware(uint64_t pa) -{ -} - -static inline void trace_megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) -{ -} - -static inline void trace_megasas_initq_map_failed(int frame) -{ -} - -static inline void trace_megasas_initq_mismatch(int queue_len, int fw_cmds) -{ -} - -static inline void trace_megasas_qf_found(unsigned int index, uint64_t pa) -{ -} - -static inline void trace_megasas_qf_new(unsigned int index, void * cmd) -{ -} - -static inline void trace_megasas_qf_failed(unsigned long pa) -{ -} - -static inline void trace_megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, unsigned int tail, int busy) -{ -} - -static inline void trace_megasas_qf_update(unsigned int head, unsigned int busy) -{ -} - -static inline void trace_megasas_qf_dequeue(unsigned int index) -{ -} - -static inline void trace_megasas_qf_map_failed(int cmd, unsigned long frame) -{ -} - -static inline void trace_megasas_qf_complete_noirq(uint64_t context) -{ -} - -static inline void trace_megasas_qf_complete(uint64_t context, unsigned int tail, unsigned int offset, int busy, unsigned int doorbell) -{ -} - -static inline void trace_megasas_handle_frame(const char * cmd, uint64_t addr, uint64_t context, uint32_t count) -{ -} - -static inline void trace_megasas_frame_busy(uint64_t addr) -{ -} - -static inline void trace_megasas_unhandled_frame_cmd(int cmd, uint8_t frame_cmd) -{ -} - -static inline void trace_megasas_handle_scsi(const char * frame, int bus, int dev, int lun, void * sdev, unsigned long size) -{ -} - -static inline void trace_megasas_scsi_target_not_present(const char * frame, int bus, int dev, int lun) -{ -} - -static inline void trace_megasas_scsi_invalid_cdb_len(const char * frame, int bus, int dev, int lun, int len) -{ -} - -static inline void trace_megasas_iov_read_overflow(int cmd, int bytes, int len) -{ -} - -static inline void trace_megasas_iov_write_overflow(int cmd, int bytes, int len) -{ -} - -static inline void trace_megasas_iov_read_underflow(int cmd, int bytes, int len) -{ -} - -static inline void trace_megasas_iov_write_underflow(int cmd, int bytes, int len) -{ -} - -static inline void trace_megasas_scsi_req_alloc_failed(const char * frame, int dev, int lun) -{ -} - -static inline void trace_megasas_scsi_read_start(int cmd, int len) -{ -} - -static inline void trace_megasas_scsi_write_start(int cmd, int len) -{ -} - -static inline void trace_megasas_scsi_nodata(int cmd) -{ -} - -static inline void trace_megasas_scsi_complete(int cmd, uint32_t status, int len, int xfer) -{ -} - -static inline void trace_megasas_command_complete(int cmd, uint32_t status, uint32_t resid) -{ -} - -static inline void trace_megasas_handle_io(int cmd, const char * frame, int dev, int lun, unsigned long lba, unsigned long count) -{ -} - -static inline void trace_megasas_io_target_not_present(int cmd, const char * frame, int dev, int lun) -{ -} - -static inline void trace_megasas_io_read_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) -{ -} - -static inline void trace_megasas_io_write_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) -{ -} - -static inline void trace_megasas_io_complete(int cmd, uint32_t len) -{ -} - -static inline void trace_megasas_io_read(int cmd, int bytes, int len, unsigned long offset) -{ -} - -static inline void trace_megasas_io_write(int cmd, int bytes, int len, unsigned long offset) -{ -} - -static inline void trace_megasas_io_continue(int cmd, int bytes) -{ -} - -static inline void trace_megasas_iovec_map_failed(int cmd, int index, unsigned long iov_size) -{ -} - -static inline void trace_megasas_iovec_sgl_overflow(int cmd, int index, int limit) -{ -} - -static inline void trace_megasas_iovec_sgl_underflow(int cmd, int index) -{ -} - -static inline void trace_megasas_iovec_sgl_invalid(int cmd, int index, uint64_t pa, uint32_t len) -{ -} - -static inline void trace_megasas_iovec_overflow(int cmd, int len, int limit) -{ -} - -static inline void trace_megasas_iovec_underflow(int cmd, int len, int limit) -{ -} - -static inline void trace_megasas_handle_dcmd(int cmd, int opcode) -{ -} - -static inline void trace_megasas_finish_dcmd(int cmd, int size) -{ -} - -static inline void trace_megasas_dcmd_req_alloc_failed(int cmd, const char * desc) -{ -} - -static inline void trace_megasas_dcmd_internal_submit(int cmd, const char * desc, int dev) -{ -} - -static inline void trace_megasas_dcmd_internal_finish(int cmd, int opcode, int lun) -{ -} - -static inline void trace_megasas_dcmd_internal_invalid(int cmd, int opcode) -{ -} - -static inline void trace_megasas_dcmd_unhandled(int cmd, int opcode, int len) -{ -} - -static inline void trace_megasas_dcmd_zero_sge(int cmd) -{ -} - -static inline void trace_megasas_dcmd_invalid_sge(int cmd, int count) -{ -} - -static inline void trace_megasas_dcmd_map_failed(int cmd) -{ -} - -static inline void trace_megasas_dcmd_invalid_xfer_len(int cmd, unsigned long size, unsigned long max) -{ -} - -static inline void trace_megasas_dcmd_enter(int cmd, const char * dcmd, int len) -{ -} - -static inline void trace_megasas_dcmd_dummy(int cmd, unsigned long size) -{ -} - -static inline void trace_megasas_dcmd_set_fw_time(int cmd, unsigned long time) -{ -} - -static inline void trace_megasas_dcmd_pd_get_list(int cmd, int num, int max, int offset) -{ -} - -static inline void trace_megasas_dcmd_ld_get_list(int cmd, int num, int max) -{ -} - -static inline void trace_megasas_dcmd_ld_get_info(int cmd, int ld_id) -{ -} - -static inline void trace_megasas_dcmd_pd_get_info(int cmd, int pd_id) -{ -} - -static inline void trace_megasas_dcmd_pd_list_query(int cmd, int flags) -{ -} - -static inline void trace_megasas_dcmd_unsupported(int cmd, unsigned long size) -{ -} - -static inline void trace_megasas_abort_frame(int cmd, int abort_cmd) -{ -} - -static inline void trace_megasas_abort_no_cmd(int cmd, uint64_t context) -{ -} - -static inline void trace_megasas_abort_invalid_context(int cmd, uint64_t context, int abort_cmd) -{ -} - -static inline void trace_megasas_reset(void) -{ -} - -static inline void trace_megasas_init(int sges, int cmds, const char * intr, const char * mode) -{ -} - -static inline void trace_megasas_msix_raise(int vector) -{ -} - -static inline void trace_megasas_irq_lower(void) -{ -} - -static inline void trace_megasas_irq_raise(void) -{ -} - -static inline void trace_megasas_intr_enabled(void) -{ -} - -static inline void trace_megasas_intr_disabled(void) -{ -} - -static inline void trace_megasas_mmio_readl(unsigned long addr, uint32_t val) -{ -} - -static inline void trace_megasas_mmio_invalid_readl(unsigned long addr) -{ -} - -static inline void trace_megasas_mmio_writel(uint32_t addr, uint32_t val) -{ -} - -static inline void trace_megasas_mmio_invalid_writel(uint32_t addr, uint32_t val) -{ -} - -static inline void trace_milkymist_ac97_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_ac97_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_ac97_pulse_irq_crrequest(void) -{ -} - -static inline void trace_milkymist_ac97_pulse_irq_crreply(void) -{ -} - -static inline void trace_milkymist_ac97_pulse_irq_dmaw(void) -{ -} - -static inline void trace_milkymist_ac97_pulse_irq_dmar(void) -{ -} - -static inline void trace_milkymist_ac97_in_cb(int avail, uint32_t remaining) -{ -} - -static inline void trace_milkymist_ac97_in_cb_transferred(int transferred) -{ -} - -static inline void trace_milkymist_ac97_out_cb(int free, uint32_t remaining) -{ -} - -static inline void trace_milkymist_ac97_out_cb_transferred(int transferred) -{ -} - -static inline void trace_milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_memcard_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_memcard_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) -{ -} - -static inline void trace_milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) -{ -} - -static inline void trace_milkymist_minimac2_tx_frame(uint32_t length) -{ -} - -static inline void trace_milkymist_minimac2_rx_frame(const void * buf, uint32_t length) -{ -} - -static inline void trace_milkymist_minimac2_drop_rx_frame(const void * buf) -{ -} - -static inline void trace_milkymist_minimac2_rx_transfer(const void * buf, uint32_t length) -{ -} - -static inline void trace_milkymist_minimac2_raise_irq_rx(void) -{ -} - -static inline void trace_milkymist_minimac2_lower_irq_rx(void) -{ -} - -static inline void trace_milkymist_minimac2_pulse_irq_tx(void) -{ -} - -static inline void trace_milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) -{ -} - -static inline void trace_milkymist_pfpu_pulse_irq(void) -{ -} - -static inline void trace_milkymist_softusb_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_softusb_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_softusb_mevt(uint8_t m) -{ -} - -static inline void trace_milkymist_softusb_kevt(uint8_t m) -{ -} - -static inline void trace_milkymist_softusb_mouse_event(int dx, int dy, int dz, int bs) -{ -} - -static inline void trace_milkymist_softusb_pulse_irq(void) -{ -} - -static inline void trace_milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_sysctl_icap_write(uint32_t value) -{ -} - -static inline void trace_milkymist_sysctl_start_timer0(void) -{ -} - -static inline void trace_milkymist_sysctl_stop_timer0(void) -{ -} - -static inline void trace_milkymist_sysctl_start_timer1(void) -{ -} - -static inline void trace_milkymist_sysctl_stop_timer1(void) -{ -} - -static inline void trace_milkymist_sysctl_pulse_irq_timer0(void) -{ -} - -static inline void trace_milkymist_sysctl_pulse_irq_timer1(void) -{ -} - -static inline void trace_milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_tmu2_start(void) -{ -} - -static inline void trace_milkymist_tmu2_pulse_irq(void) -{ -} - -static inline void trace_milkymist_uart_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_uart_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_uart_raise_irq(void) -{ -} - -static inline void trace_milkymist_uart_lower_irq(void) -{ -} - -static inline void trace_milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) -{ -} - -static inline void trace_mipsnet_send(uint32_t size) -{ -} - -static inline void trace_mipsnet_receive(uint32_t size) -{ -} - -static inline void trace_mipsnet_read(uint64_t addr, uint32_t val) -{ -} - -static inline void trace_mipsnet_write(uint64_t addr, uint64_t val) -{ -} - -static inline void trace_mipsnet_irq(uint32_t isr, uint32_t intctl) -{ -} - -static inline void trace_pc87312_io_read(uint32_t addr, uint32_t val) -{ -} - -static inline void trace_pc87312_io_write(uint32_t addr, uint32_t val) -{ -} - -static inline void trace_pc87312_info_floppy(uint32_t base) -{ -} - -static inline void trace_pc87312_info_ide(uint32_t base) -{ -} - -static inline void trace_pc87312_info_parallel(uint32_t base, uint32_t irq) -{ -} - -static inline void trace_pc87312_info_serial(int n, uint32_t base, uint32_t irq) -{ -} - -static inline void trace_pvscsi_ring_init_data(uint32_t txr_len_log2, uint32_t rxr_len_log2) -{ -} - -static inline void trace_pvscsi_ring_init_msg(uint32_t len_log2) -{ -} - -static inline void trace_pvscsi_ring_flush_cmp(uint64_t filled_cmp_ptr) -{ -} - -static inline void trace_pvscsi_ring_flush_msg(uint64_t filled_cmp_ptr) -{ -} - -static inline void trace_pvscsi_update_irq_level(bool raise, uint64_t mask, uint64_t status) -{ -} - -static inline void trace_pvscsi_update_irq_msi(void) -{ -} - -static inline void trace_pvscsi_cmp_ring_put(unsigned long addr) -{ -} - -static inline void trace_pvscsi_msg_ring_put(unsigned long addr) -{ -} - -static inline void trace_pvscsi_complete_request(uint64_t context, uint64_t len, uint8_t sense_key) -{ -} - -static inline void trace_pvscsi_get_sg_list(int nsg, size_t size) -{ -} - -static inline void trace_pvscsi_get_next_sg_elem(uint32_t flags) -{ -} - -static inline void trace_pvscsi_command_complete_not_found(uint32_t tag) -{ -} - -static inline void trace_pvscsi_command_complete_data_run(void) -{ -} - -static inline void trace_pvscsi_command_complete_sense_len(int len) -{ -} - -static inline void trace_pvscsi_convert_sglist(uint64_t context, unsigned long addr, uint32_t resid) -{ -} - -static inline void trace_pvscsi_process_req_descr(uint8_t cmd, uint64_t ctx) -{ -} - -static inline void trace_pvscsi_process_req_descr_unknown_device(void) -{ -} - -static inline void trace_pvscsi_process_req_descr_invalid_dir(void) -{ -} - -static inline void trace_pvscsi_process_io(unsigned long addr) -{ -} - -static inline void trace_pvscsi_on_cmd_noimpl(const char* cmd) -{ -} - -static inline void trace_pvscsi_on_cmd_reset_dev(uint32_t tgt, int lun, void* dev) -{ -} - -static inline void trace_pvscsi_on_cmd_arrived(const char* cmd) -{ -} - -static inline void trace_pvscsi_on_cmd_abort(uint64_t ctx, uint32_t tgt) -{ -} - -static inline void trace_pvscsi_on_cmd_unknown(uint64_t cmd_id) -{ -} - -static inline void trace_pvscsi_on_cmd_unknown_data(uint32_t data) -{ -} - -static inline void trace_pvscsi_io_write(const char* cmd, uint64_t val) -{ -} - -static inline void trace_pvscsi_io_write_unknown(unsigned long addr, unsigned sz, uint64_t val) -{ -} - -static inline void trace_pvscsi_io_read(const char* cmd, uint64_t status) -{ -} - -static inline void trace_pvscsi_io_read_unknown(unsigned long addr, unsigned sz) -{ -} - -static inline void trace_pvscsi_init_msi_fail(int res) -{ -} - -static inline void trace_pvscsi_state(const char* state) -{ -} - -static inline void trace_pvscsi_tx_rings_ppn(const char* label, uint64_t ppn) -{ -} - -static inline void trace_pvscsi_tx_rings_num_pages(const char* label, uint32_t num) -{ -} - -static inline void trace_xen_ram_alloc(unsigned long ram_addr, unsigned long size) -{ -} - -static inline void trace_xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) -{ -} - -static inline void trace_xen_map_cache(uint64_t phys_addr) -{ -} - -static inline void trace_xen_remap_bucket(uint64_t index) -{ -} - -static inline void trace_xen_map_cache_return(void* ptr) -{ -} - -static inline void trace_xen_map_block(uint64_t phys_addr, uint64_t size) -{ -} - -static inline void trace_xen_unmap_block(void* addr, unsigned long size) -{ -} - -static inline void trace_xen_platform_log(char * s) -{ -} - -static inline void trace_qemu_coroutine_enter(void * from, void * to, void * opaque) -{ -} - -static inline void trace_qemu_coroutine_yield(void * from, void * to) -{ -} - -static inline void trace_qemu_coroutine_terminate(void * co) -{ -} - -static inline void trace_qemu_co_queue_run_restart(void * co) -{ -} - -static inline void trace_qemu_co_queue_next(void * nxt) -{ -} - -static inline void trace_qemu_co_mutex_lock_entry(void * mutex, void * self) -{ -} - -static inline void trace_qemu_co_mutex_lock_return(void * mutex, void * self) -{ -} - -static inline void trace_qemu_co_mutex_unlock_entry(void * mutex, void * self) -{ -} - -static inline void trace_qemu_co_mutex_unlock_return(void * mutex, void * self) -{ -} - -static inline void trace_escc_put_queue(char channel, int b) -{ -} - -static inline void trace_escc_get_queue(char channel, int val) -{ -} - -static inline void trace_escc_update_irq(int irq) -{ -} - -static inline void trace_escc_update_parameters(char channel, int speed, int parity, int data_bits, int stop_bits) -{ -} - -static inline void trace_escc_mem_writeb_ctrl(char channel, uint32_t reg, uint32_t val) -{ -} - -static inline void trace_escc_mem_writeb_data(char channel, uint32_t val) -{ -} - -static inline void trace_escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) -{ -} - -static inline void trace_escc_mem_readb_data(char channel, uint32_t ret) -{ -} - -static inline void trace_escc_serial_receive_byte(char channel, int ch) -{ -} - -static inline void trace_escc_sunkbd_event_in(int ch) -{ -} - -static inline void trace_escc_sunkbd_event_out(int ch) -{ -} - -static inline void trace_escc_kbd_command(int val) -{ -} - -static inline void trace_escc_sunmouse_event(int dx, int dy, int buttons_state) -{ -} - -static inline void trace_iscsi_aio_write16_cb(void * iscsi, int status, void * acb, int canceled) -{ -} - -static inline void trace_iscsi_aio_writev(void * iscsi, int64_t sector_num, int nb_sectors, void * opaque, void * acb) -{ -} - -static inline void trace_iscsi_aio_read16_cb(void * iscsi, int status, void * acb, int canceled) -{ -} - -static inline void trace_iscsi_aio_readv(void * iscsi, int64_t sector_num, int nb_sectors, void * opaque, void * acb) -{ -} - -static inline void trace_esp_error_fifo_overrun(void) -{ -} - -static inline void trace_esp_error_unhandled_command(uint32_t val) -{ -} - -static inline void trace_esp_error_invalid_write(uint32_t val, uint32_t addr) -{ -} - -static inline void trace_esp_raise_irq(void) -{ -} - -static inline void trace_esp_lower_irq(void) -{ -} - -static inline void trace_esp_dma_enable(void) -{ -} - -static inline void trace_esp_dma_disable(void) -{ -} - -static inline void trace_esp_get_cmd(uint32_t dmalen, int target) -{ -} - -static inline void trace_esp_do_busid_cmd(uint8_t busid) -{ -} - -static inline void trace_esp_handle_satn_stop(uint32_t cmdlen) -{ -} - -static inline void trace_esp_write_response(uint32_t status) -{ -} - -static inline void trace_esp_do_dma(uint32_t cmdlen, uint32_t len) -{ -} - -static inline void trace_esp_command_complete(void) -{ -} - -static inline void trace_esp_command_complete_unexpected(void) -{ -} - -static inline void trace_esp_command_complete_fail(void) -{ -} - -static inline void trace_esp_transfer_data(uint32_t dma_left, int32_t ti_size) -{ -} - -static inline void trace_esp_handle_ti(uint32_t minlen) -{ -} - -static inline void trace_esp_handle_ti_cmd(uint32_t cmdlen) -{ -} - -static inline void trace_esp_mem_readb(uint32_t saddr, uint8_t reg) -{ -} - -static inline void trace_esp_mem_writeb(uint32_t saddr, uint8_t reg, uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_nop(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_flush(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_reset(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_bus_reset(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_iccs(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_msgacc(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_pad(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_satn(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_rstatn(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_sel(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_selatn(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_selatns(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_ensel(uint32_t val) -{ -} - -static inline void trace_esp_mem_writeb_cmd_dissel(uint32_t val) -{ -} - -static inline void trace_esp_pci_error_invalid_dma_direction(void) -{ -} - -static inline void trace_esp_pci_error_invalid_read(uint32_t reg) -{ -} - -static inline void trace_esp_pci_error_invalid_write(uint32_t reg) -{ -} - -static inline void trace_esp_pci_error_invalid_write_dma(uint32_t val, uint32_t addr) -{ -} - -static inline void trace_esp_pci_dma_read(uint32_t saddr, uint32_t reg) -{ -} - -static inline void trace_esp_pci_dma_write(uint32_t saddr, uint32_t reg, uint32_t val) -{ -} - -static inline void trace_esp_pci_dma_idle(uint32_t val) -{ -} - -static inline void trace_esp_pci_dma_blast(uint32_t val) -{ -} - -static inline void trace_esp_pci_dma_abort(uint32_t val) -{ -} - -static inline void trace_esp_pci_dma_start(uint32_t val) -{ -} - -static inline void trace_esp_pci_sbac_read(uint32_t reg) -{ -} - -static inline void trace_esp_pci_sbac_write(uint32_t reg, uint32_t val) -{ -} - -static inline void trace_handle_qmp_command(void * mon, const char * cmd_name) -{ -} - -static inline void trace_monitor_protocol_emitter(void * mon) -{ -} - -static inline void trace_monitor_protocol_event(uint32_t event, const char * evname, void * data) -{ -} - -static inline void trace_monitor_protocol_event_handler(uint32_t event, void * data, uint64_t last, uint64_t now) -{ -} - -static inline void trace_monitor_protocol_event_emit(uint32_t event, void * data) -{ -} - -static inline void trace_monitor_protocol_event_queue(uint32_t event, void * data, uint64_t rate, uint64_t last, uint64_t now) -{ -} - -static inline void trace_monitor_protocol_event_throttle(uint32_t event, uint64_t rate) -{ -} - -static inline void trace_open_eth_mii_write(unsigned idx, uint16_t v) -{ -} - -static inline void trace_open_eth_mii_read(unsigned idx, uint16_t v) -{ -} - -static inline void trace_open_eth_update_irq(uint32_t v) -{ -} - -static inline void trace_open_eth_receive(unsigned len) -{ -} - -static inline void trace_open_eth_receive_mcast(unsigned idx, uint32_t h0, uint32_t h1) -{ -} - -static inline void trace_open_eth_receive_reject(void) -{ -} - -static inline void trace_open_eth_receive_desc(uint32_t addr, uint32_t len_flags) -{ -} - -static inline void trace_open_eth_start_xmit(uint32_t addr, unsigned len, unsigned tx_len) -{ -} - -static inline void trace_open_eth_reg_read(uint32_t addr, uint32_t v) -{ -} - -static inline void trace_open_eth_reg_write(uint32_t addr, uint32_t v) -{ -} - -static inline void trace_open_eth_desc_read(uint32_t addr, uint32_t v) -{ -} - -static inline void trace_open_eth_desc_write(uint32_t addr, uint32_t v) -{ -} - -static inline void trace_v9fs_rerror(uint16_t tag, uint8_t id, int err) -{ -} - -static inline void trace_v9fs_version(uint16_t tag, uint8_t id, int32_t msize, char* version) -{ -} - -static inline void trace_v9fs_version_return(uint16_t tag, uint8_t id, int32_t msize, char* version) -{ -} - -static inline void trace_v9fs_attach(uint16_t tag, uint8_t id, int32_t fid, int32_t afid, char* uname, char* aname) -{ -} - -static inline void trace_v9fs_attach_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) -{ -} - -static inline void trace_v9fs_stat(uint16_t tag, uint8_t id, int32_t fid) -{ -} - -static inline void trace_v9fs_stat_return(uint16_t tag, uint8_t id, int32_t mode, int32_t atime, int32_t mtime, int64_t length) -{ -} - -static inline void trace_v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask) -{ -} - -static inline void trace_v9fs_getattr_return(uint16_t tag, uint8_t id, uint64_t result_mask, uint32_t mode, uint32_t uid, uint32_t gid) -{ -} - -static inline void trace_v9fs_walk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, uint16_t nwnames) -{ -} - -static inline void trace_v9fs_walk_return(uint16_t tag, uint8_t id, uint16_t nwnames, void* qids) -{ -} - -static inline void trace_v9fs_open(uint16_t tag, uint8_t id, int32_t fid, int32_t mode) -{ -} - -static inline void trace_v9fs_open_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) -{ -} - -static inline void trace_v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode, uint32_t gid) -{ -} - -static inline void trace_v9fs_lcreate_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int32_t iounit) -{ -} - -static inline void trace_v9fs_fsync(uint16_t tag, uint8_t id, int32_t fid, int datasync) -{ -} - -static inline void trace_v9fs_clunk(uint16_t tag, uint8_t id, int32_t fid) -{ -} - -static inline void trace_v9fs_read(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t max_count) -{ -} - -static inline void trace_v9fs_read_return(uint16_t tag, uint8_t id, int32_t count, ssize_t err) -{ -} - -static inline void trace_v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, uint64_t offset, uint32_t max_count) -{ -} - -static inline void trace_v9fs_readdir_return(uint16_t tag, uint8_t id, uint32_t count, ssize_t retval) -{ -} - -static inline void trace_v9fs_write(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t count, int cnt) -{ -} - -static inline void trace_v9fs_write_return(uint16_t tag, uint8_t id, int32_t total, ssize_t err) -{ -} - -static inline void trace_v9fs_create(uint16_t tag, uint8_t id, int32_t fid, char* name, int32_t perm, int8_t mode) -{ -} - -static inline void trace_v9fs_create_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) -{ -} - -static inline void trace_v9fs_symlink(uint16_t tag, uint8_t id, int32_t fid, char* name, char* symname, uint32_t gid) -{ -} - -static inline void trace_v9fs_symlink_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) -{ -} - -static inline void trace_v9fs_flush(uint16_t tag, uint8_t id, int16_t flush_tag) -{ -} - -static inline void trace_v9fs_link(uint16_t tag, uint8_t id, int32_t dfid, int32_t oldfid, char* name) -{ -} - -static inline void trace_v9fs_remove(uint16_t tag, uint8_t id, int32_t fid) -{ -} - -static inline void trace_v9fs_wstat(uint16_t tag, uint8_t id, int32_t fid, int32_t mode, int32_t atime, int32_t mtime) -{ -} - -static inline void trace_v9fs_mknod(uint16_t tag, uint8_t id, int32_t fid, int mode, int major, int minor) -{ -} - -static inline void trace_v9fs_mknod_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) -{ -} - -static inline void trace_v9fs_lock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length) -{ -} - -static inline void trace_v9fs_lock_return(uint16_t tag, uint8_t id, int8_t status) -{ -} - -static inline void trace_v9fs_getlock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length) -{ -} - -static inline void trace_v9fs_getlock_return(uint16_t tag, uint8_t id, uint8_t type, uint64_t start, uint64_t length, uint32_t proc_id) -{ -} - -static inline void trace_v9fs_mkdir(uint16_t tag, uint8_t id, int32_t fid, char* name, int mode, uint32_t gid) -{ -} - -static inline void trace_v9fs_mkdir_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int err) -{ -} - -static inline void trace_v9fs_xattrwalk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, char* name) -{ -} - -static inline void trace_v9fs_xattrwalk_return(uint16_t tag, uint8_t id, int64_t size) -{ -} - -static inline void trace_v9fs_xattrcreate(uint16_t tag, uint8_t id, int32_t fid, char* name, int64_t size, int flags) -{ -} - -static inline void trace_v9fs_readlink(uint16_t tag, uint8_t id, int32_t fid) -{ -} - -static inline void trace_v9fs_readlink_return(uint16_t tag, uint8_t id, char* target) -{ -} - -static inline void trace_mmu_helper_dfault(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) -{ -} - -static inline void trace_mmu_helper_dprot(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) -{ -} - -static inline void trace_mmu_helper_dmiss(uint64_t address, uint64_t context) -{ -} - -static inline void trace_mmu_helper_tfault(uint64_t address, uint64_t context) -{ -} - -static inline void trace_mmu_helper_tmiss(uint64_t address, uint64_t context) -{ -} - -static inline void trace_mmu_helper_get_phys_addr_code(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) -{ -} - -static inline void trace_mmu_helper_get_phys_addr_data(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) -{ -} - -static inline void trace_mmu_helper_mmu_fault(uint64_t address, uint64_t paddr, int mmu_idx, uint32_t tl, uint64_t prim_context, uint64_t sec_context) -{ -} - -static inline void trace_int_helper_set_softint(uint32_t softint) -{ -} - -static inline void trace_int_helper_clear_softint(uint32_t softint) -{ -} - -static inline void trace_int_helper_write_softint(uint32_t softint) -{ -} - -static inline void trace_int_helper_icache_freeze(void) -{ -} - -static inline void trace_int_helper_dcache_freeze(void) -{ -} - -static inline void trace_win_helper_gregset_error(uint32_t pstate) -{ -} - -static inline void trace_win_helper_switch_pstate(uint32_t pstate_regs, uint32_t new_pstate_regs) -{ -} - -static inline void trace_win_helper_no_switch_pstate(uint32_t new_pstate_regs) -{ -} - -static inline void trace_win_helper_wrpil(uint32_t psrpil, uint32_t new_pil) -{ -} - -static inline void trace_win_helper_done(uint32_t tl) -{ -} - -static inline void trace_win_helper_retry(uint32_t tl) -{ -} - -static inline void trace_dma_bdrv_io(void * dbs, void * bs, int64_t sector_num, bool to_dev) -{ -} - -static inline void trace_dma_aio_cancel(void * dbs) -{ -} - -static inline void trace_dma_complete(void * dbs, int ret, void * cb) -{ -} - -static inline void trace_dma_bdrv_cb(void * dbs, int ret) -{ -} - -static inline void trace_dma_map_wait(void * dbs) -{ -} - -static inline void trace_console_gfx_new(void) -{ -} - -static inline void trace_console_txt_new(int w, int h) -{ -} - -static inline void trace_console_select(int nr) -{ -} - -static inline void trace_console_refresh(int interval) -{ -} - -static inline void trace_displaysurface_create(void * display_surface, int w, int h) -{ -} - -static inline void trace_displaysurface_create_from(void * display_surface, int w, int h, int bpp, int swap) -{ -} - -static inline void trace_displaysurface_free(void * display_surface) -{ -} - -static inline void trace_displaychangelistener_register(void * dcl, const char * name) -{ -} - -static inline void trace_displaychangelistener_unregister(void * dcl, const char * name) -{ -} - -static inline void trace_ppm_save(const char * filename, void * display_surface) -{ -} - -static inline void trace_vmware_value_read(uint32_t index, uint32_t value) -{ -} - -static inline void trace_vmware_value_write(uint32_t index, uint32_t value) -{ -} - -static inline void trace_vmware_palette_read(uint32_t index, uint32_t value) -{ -} - -static inline void trace_vmware_palette_write(uint32_t index, uint32_t value) -{ -} - -static inline void trace_vmware_scratch_read(uint32_t index, uint32_t value) -{ -} - -static inline void trace_vmware_scratch_write(uint32_t index, uint32_t value) -{ -} - -static inline void trace_vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) -{ -} - -static inline void trace_savevm_section_start(void) -{ -} - -static inline void trace_savevm_section_end(unsigned int section_id) -{ -} - -static inline void trace_migration_bitmap_sync_start(void) -{ -} - -static inline void trace_migration_bitmap_sync_end(uint64_t dirty_pages) -{ -} - -static inline void trace_migration_throttle(void) -{ -} - -static inline void trace_qxl_create_guest_primary(int qid, uint32_t width, uint32_t height, uint64_t mem, uint32_t format, uint32_t position) -{ -} - -static inline void trace_qxl_create_guest_primary_rest(int qid, int32_t stride, uint32_t type, uint32_t flags) -{ -} - -static inline void trace_qxl_destroy_primary(int qid) -{ -} - -static inline void trace_qxl_enter_vga_mode(int qid) -{ -} - -static inline void trace_qxl_exit_vga_mode(int qid) -{ -} - -static inline void trace_qxl_hard_reset(int qid, int64_t loadvm) -{ -} - -static inline void trace_qxl_interface_async_complete_io(int qid, uint32_t current_async, void * cookie) -{ -} - -static inline void trace_qxl_interface_attach_worker(int qid) -{ -} - -static inline void trace_qxl_interface_get_init_info(int qid) -{ -} - -static inline void trace_qxl_interface_set_compression_level(int qid, int64_t level) -{ -} - -static inline void trace_qxl_interface_update_area_complete(int qid, uint32_t surface_id, uint32_t dirty_left, uint32_t dirty_right, uint32_t dirty_top, uint32_t dirty_bottom) -{ -} - -static inline void trace_qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) -{ -} - -static inline void trace_qxl_interface_update_area_complete_overflow(int qid, int max) -{ -} - -static inline void trace_qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) -{ -} - -static inline void trace_qxl_io_destroy_primary_ignored(int qid, const char * mode) -{ -} - -static inline void trace_qxl_io_log(int qid, const uint8_t * log_buf) -{ -} - -static inline void trace_qxl_io_read_unexpected(int qid) -{ -} - -static inline void trace_qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char * desc) -{ -} - -static inline void trace_qxl_io_write(int qid, const char * mode, uint64_t addr, uint64_t val, unsigned size, int async) -{ -} - -static inline void trace_qxl_memslot_add_guest(int qid, uint32_t slot_id, uint64_t guest_start, uint64_t guest_end) -{ -} - -static inline void trace_qxl_post_load(int qid, const char * mode) -{ -} - -static inline void trace_qxl_pre_load(int qid) -{ -} - -static inline void trace_qxl_pre_save(int qid) -{ -} - -static inline void trace_qxl_reset_surfaces(int qid) -{ -} - -static inline void trace_qxl_ring_command_check(int qid, const char * mode) -{ -} - -static inline void trace_qxl_ring_command_get(int qid, const char * mode) -{ -} - -static inline void trace_qxl_ring_command_req_notification(int qid) -{ -} - -static inline void trace_qxl_ring_cursor_check(int qid, const char * mode) -{ -} - -static inline void trace_qxl_ring_cursor_get(int qid, const char * mode) -{ -} - -static inline void trace_qxl_ring_cursor_req_notification(int qid) -{ -} - -static inline void trace_qxl_ring_res_push(int qid, const char * mode, uint32_t surface_count, uint32_t free_res, void * last_release, const char * notify) -{ -} - -static inline void trace_qxl_ring_res_push_rest(int qid, uint32_t ring_has, uint32_t ring_size, uint32_t prod, uint32_t cons) -{ -} - -static inline void trace_qxl_ring_res_put(int qid, uint32_t free_res) -{ -} - -static inline void trace_qxl_set_mode(int qid, int modenr, uint32_t x_res, uint32_t y_res, uint32_t bits, uint64_t devmem) -{ -} - -static inline void trace_qxl_soft_reset(int qid) -{ -} - -static inline void trace_qemu_spice_add_memslot(int qid, uint32_t slot_id, unsigned long virt_start, unsigned long virt_end, int async) -{ -} - -static inline void trace_qemu_spice_del_memslot(int qid, uint32_t gid, uint32_t slot_id) -{ -} - -static inline void trace_qemu_spice_create_primary_surface(int qid, uint32_t sid, void * surface, int async) -{ -} - -static inline void trace_qemu_spice_destroy_primary_surface(int qid, uint32_t sid, int async) -{ -} - -static inline void trace_qemu_spice_wakeup(uint32_t qid) -{ -} - -static inline void trace_qemu_spice_start(uint32_t qid) -{ -} - -static inline void trace_qemu_spice_stop(uint32_t qid) -{ -} - -static inline void trace_qemu_spice_create_update(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) -{ -} - -static inline void trace_qxl_spice_destroy_surfaces_complete(int qid) -{ -} - -static inline void trace_qxl_spice_destroy_surfaces(int qid, int async) -{ -} - -static inline void trace_qxl_spice_destroy_surface_wait_complete(int qid, uint32_t id) -{ -} - -static inline void trace_qxl_spice_destroy_surface_wait(int qid, uint32_t id, int async) -{ -} - -static inline void trace_qxl_spice_flush_surfaces_async(int qid, uint32_t surface_count, uint32_t num_free_res) -{ -} - -static inline void trace_qxl_spice_monitors_config(int qid) -{ -} - -static inline void trace_qxl_spice_loadvm_commands(int qid, void * ext, uint32_t count) -{ -} - -static inline void trace_qxl_spice_oom(int qid) -{ -} - -static inline void trace_qxl_spice_reset_cursor(int qid) -{ -} - -static inline void trace_qxl_spice_reset_image_cache(int qid) -{ -} - -static inline void trace_qxl_spice_reset_memslots(int qid) -{ -} - -static inline void trace_qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) -{ -} - -static inline void trace_qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) -{ -} - -static inline void trace_qxl_surfaces_dirty(int qid, int surface, int offset, int size) -{ -} - -static inline void trace_qxl_send_events(int qid, uint32_t events) -{ -} - -static inline void trace_qxl_send_events_vm_stopped(int qid, uint32_t events) -{ -} - -static inline void trace_qxl_set_guest_bug(int qid) -{ -} - -static inline void trace_qxl_interrupt_client_monitors_config(int qid, int num_heads, void * heads) -{ -} - -static inline void trace_qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void * client_monitors_config) -{ -} - -static inline void trace_qxl_client_monitors_config_unsupported_by_device(int qid, int revision) -{ -} - -static inline void trace_qxl_client_monitors_config_capped(int qid, int requested, int limit) -{ -} - -static inline void trace_qxl_client_monitors_config_crc(int qid, unsigned size, uint32_t crc32) -{ -} - -static inline void trace_qxl_set_client_capabilities_unsupported_by_revision(int qid, int revision) -{ -} - -static inline void trace_qxl_render_blit_guest_primary_initialized(void) -{ -} - -static inline void trace_qxl_render_blit(int32_t stride, int32_t left, int32_t right, int32_t top, int32_t bottom) -{ -} - -static inline void trace_qxl_render_guest_primary_resized(int32_t width, int32_t height, int32_t stride, int32_t bytes_pp, int32_t bits_pp) -{ -} - -static inline void trace_qxl_render_update_area_done(void * cookie) -{ -} - -static inline void trace_spapr_pci_msi(const char * msg, uint32_t n, uint32_t ca) -{ -} - -static inline void trace_spapr_pci_msi_setup(const char * name, unsigned vector, uint64_t addr) -{ -} - -static inline void trace_spapr_pci_rtas_ibm_change_msi(unsigned func, unsigned req) -{ -} - -static inline void trace_spapr_pci_rtas_ibm_query_interrupt_source_number(unsigned ioa, unsigned intr) -{ -} - -static inline void trace_spapr_pci_msi_write(uint64_t addr, uint64_t data, uint32_t dt_irq) -{ -} - -static inline void trace_spapr_pci_lsi_set(const char * busname, int pin, uint32_t irq) -{ -} - -static inline void trace_xics_icp_check_ipi(int server, uint8_t mfrr) -{ -} - -static inline void trace_xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) -{ -} - -static inline void trace_xics_icp_eoi(int server, uint32_t xirr, uint32_t new_xirr) -{ -} - -static inline void trace_xics_icp_irq(int server, int nr, uint8_t priority) -{ -} - -static inline void trace_xics_icp_raise(uint32_t xirr, uint8_t pending_priority) -{ -} - -static inline void trace_xics_set_irq_msi(int srcno, int nr) -{ -} - -static inline void trace_xics_masked_pending(void) -{ -} - -static inline void trace_xics_set_irq_lsi(int srcno, int nr) -{ -} - -static inline void trace_xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) -{ -} - -static inline void trace_xics_ics_reject(int nr, int srcno) -{ -} - -static inline void trace_xics_ics_eoi(int nr) -{ -} - -static inline void trace_hbitmap_iter_skip_words(const void * hb, void * hbi, uint64_t pos, unsigned long cur) -{ -} - -static inline void trace_hbitmap_reset(void * hb, uint64_t start, uint64_t count, uint64_t sbit, uint64_t ebit) -{ -} - -static inline void trace_hbitmap_set(void * hb, uint64_t start, uint64_t count, uint64_t sbit, uint64_t ebit) -{ -} - -static inline void trace_ioinst(const char * insn) -{ -} - -static inline void trace_ioinst_sch_id(const char * insn, int cssid, int ssid, int schid) -{ -} - -static inline void trace_ioinst_chp_id(const char * insn, int cssid, int chpid) -{ -} - -static inline void trace_ioinst_chsc_cmd(uint16_t cmd, uint16_t len) -{ -} - -static inline void trace_css_enable_facility(const char * facility) -{ -} - -static inline void trace_css_crw(uint8_t rsc, uint8_t erc, uint16_t rsid, const char * chained) -{ -} - -static inline void trace_css_chpid_add(uint8_t cssid, uint8_t chpid, uint8_t type) -{ -} - -static inline void trace_css_new_image(uint8_t cssid, const char * default_cssid) -{ -} - -static inline void trace_css_assign_subch(const char * do_assign, uint8_t cssid, uint8_t ssid, uint16_t schid, uint16_t devno) -{ -} - -static inline void trace_css_io_interrupt(int cssid, int ssid, int schid, uint32_t intparm, uint8_t isc, const char * conditional) -{ -} - -static inline void trace_virtio_ccw_interpret_ccw(int cssid, int ssid, int schid, int cmd_code) -{ -} - -static inline void trace_virtio_ccw_new_device(int cssid, int ssid, int schid, int devno, const char * devno_mode) -{ -} - -static inline void trace_migrate_set_state(int new_state) -{ -} - -static inline void trace_kvm_ioctl(int type, void * arg) -{ -} - -static inline void trace_kvm_vm_ioctl(int type, void * arg) -{ -} - -static inline void trace_kvm_vcpu_ioctl(int cpu_index, int type, void * arg) -{ -} - -static inline void trace_kvm_run_exit(int cpu_index, uint32_t reason) -{ -} - -static inline void trace_object_dynamic_cast_assert(const char * type, const char * target, const char * file, int line, const char * func) -{ -} - -static inline void trace_object_class_dynamic_cast_assert(const char * type, const char * target, const char * file, int line, const char * func) -{ -} -#endif /* TRACE__GENERATED_TRACERS_H */ diff --git a/contrib/qemu/util/aes.c b/contrib/qemu/util/aes.c deleted file mode 100644 index 91e97fa6e7f..00000000000 --- a/contrib/qemu/util/aes.c +++ /dev/null @@ -1,1314 +0,0 @@ -/** - * - * aes.c - integrated in QEMU by Fabrice Bellard from the OpenSSL project. - */ -/* - * rijndael-alg-fst.c - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> - * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> - * @author Paulo Barreto <paulo.barreto@terra.com.br> - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "qemu-common.h" -#include "qemu/aes.h" - -#ifndef NDEBUG -#define NDEBUG -#endif - -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -/* This controls loop-unrolling in aes_core.c */ -#undef FULL_UNROLL -# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3])) -# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); } - -/* -AES_Te0[x] = S [x].[02, 01, 01, 03]; -AES_Te1[x] = S [x].[03, 02, 01, 01]; -AES_Te2[x] = S [x].[01, 03, 02, 01]; -AES_Te3[x] = S [x].[01, 01, 03, 02]; -AES_Te4[x] = S [x].[01, 01, 01, 01]; - -AES_Td0[x] = Si[x].[0e, 09, 0d, 0b]; -AES_Td1[x] = Si[x].[0b, 0e, 09, 0d]; -AES_Td2[x] = Si[x].[0d, 0b, 0e, 09]; -AES_Td3[x] = Si[x].[09, 0d, 0b, 0e]; -AES_Td4[x] = Si[x].[01, 01, 01, 01]; -*/ - -const uint32_t AES_Te0[256] = { -    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, -    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, -    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, -    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, -    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, -    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, -    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, -    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, -    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, -    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, -    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, -    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, -    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, -    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, -    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, -    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, -    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, -    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, -    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, -    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, -    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, -    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, -    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, -    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, -    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, -    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, -    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, -    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, -    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, -    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, -    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, -    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, -    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, -    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, -    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, -    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, -    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, -    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, -    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, -    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, -    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, -    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, -    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, -    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, -    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, -    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, -    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, -    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, -    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, -    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, -    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, -    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, -    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, -    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, -    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, -    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, -    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, -    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, -    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, -    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, -    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, -    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, -    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, -    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, -}; -const uint32_t AES_Te1[256] = { -    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, -    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, -    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, -    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, -    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, -    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, -    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, -    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, -    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, -    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, -    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, -    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, -    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, -    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, -    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, -    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, -    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, -    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, -    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, -    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, -    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, -    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, -    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, -    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, -    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, -    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, -    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, -    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, -    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, -    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, -    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, -    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, -    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, -    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, -    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, -    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, -    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, -    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, -    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, -    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, -    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, -    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, -    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, -    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, -    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, -    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, -    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, -    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, -    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, -    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, -    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, -    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, -    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, -    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, -    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, -    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, -    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, -    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, -    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, -    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, -    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, -    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, -    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, -    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, -}; -const uint32_t AES_Te2[256] = { -    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, -    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, -    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, -    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, -    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, -    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, -    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, -    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, -    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, -    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, -    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, -    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, -    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, -    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, -    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, -    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, -    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, -    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, -    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, -    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, -    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, -    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, -    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, -    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, -    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, -    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, -    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, -    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, -    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, -    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, -    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, -    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, -    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, -    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, -    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, -    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, -    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, -    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, -    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, -    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, -    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, -    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, -    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, -    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, -    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, -    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, -    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, -    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, -    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, -    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, -    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, -    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, -    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, -    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, -    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, -    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, -    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, -    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, -    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, -    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, -    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, -    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, -    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, -    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, -}; -const uint32_t AES_Te3[256] = { - -    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, -    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, -    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, -    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, -    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, -    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, -    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, -    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, -    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, -    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, -    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, -    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, -    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, -    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, -    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, -    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, -    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, -    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, -    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, -    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, -    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, -    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, -    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, -    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, -    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, -    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, -    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, -    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, -    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, -    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, -    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, -    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, -    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, -    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, -    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, -    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, -    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, -    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, -    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, -    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, -    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, -    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, -    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, -    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, -    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, -    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, -    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, -    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, -    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, -    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, -    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, -    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, -    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, -    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, -    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, -    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, -    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, -    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, -    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, -    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, -    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, -    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, -    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, -    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, -}; -const uint32_t AES_Te4[256] = { -    0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, -    0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, -    0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, -    0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, -    0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, -    0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, -    0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, -    0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, -    0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, -    0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, -    0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, -    0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, -    0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, -    0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, -    0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, -    0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, -    0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, -    0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, -    0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, -    0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, -    0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, -    0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, -    0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, -    0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, -    0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, -    0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, -    0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, -    0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, -    0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, -    0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, -    0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, -    0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, -    0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, -    0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, -    0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, -    0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, -    0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, -    0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, -    0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, -    0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, -    0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, -    0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, -    0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, -    0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, -    0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, -    0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, -    0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, -    0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, -    0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, -    0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, -    0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, -    0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, -    0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, -    0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, -    0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, -    0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, -    0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, -    0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, -    0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, -    0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, -    0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, -    0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, -    0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, -    0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, -}; -const uint32_t AES_Td0[256] = { -    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, -    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, -    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, -    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, -    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, -    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, -    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, -    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, -    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, -    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, -    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, -    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, -    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, -    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, -    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, -    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, -    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, -    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, -    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, -    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, -    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, -    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, -    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, -    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, -    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, -    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, -    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, -    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, -    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, -    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, -    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, -    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, -    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, -    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, -    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, -    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, -    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, -    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, -    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, -    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, -    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, -    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, -    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, -    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, -    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, -    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, -    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, -    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, -    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, -    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, -    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, -    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, -    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, -    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, -    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, -    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, -    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, -    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, -    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, -    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, -    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, -    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, -    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, -    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, -}; -const uint32_t AES_Td1[256] = { -    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, -    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, -    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, -    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, -    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, -    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, -    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, -    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, -    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, -    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, -    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, -    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, -    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, -    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, -    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, -    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, -    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, -    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, -    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, -    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, -    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, -    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, -    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, -    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, -    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, -    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, -    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, -    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, -    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, -    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, -    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, -    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, -    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, -    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, -    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, -    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, -    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, -    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, -    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, -    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, -    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, -    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, -    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, -    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, -    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, -    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, -    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, -    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, -    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, -    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, -    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, -    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, -    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, -    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, -    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, -    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, -    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, -    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, -    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, -    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, -    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, -    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, -    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, -    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, -}; -const uint32_t AES_Td2[256] = { -    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, -    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, -    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, -    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, -    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, -    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, -    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, -    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, -    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, -    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, -    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, -    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, -    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, -    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, -    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, -    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, -    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, -    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, -    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, -    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, - -    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, -    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, -    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, -    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, -    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, -    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, -    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, -    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, -    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, -    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, -    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, -    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, -    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, -    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, -    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, -    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, -    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, -    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, -    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, -    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, -    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, -    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, -    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, -    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, -    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, -    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, -    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, -    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, -    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, -    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, -    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, -    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, -    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, -    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, -    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, -    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, -    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, -    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, -    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, -    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, -    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, -    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, -    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, -    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, -}; -const uint32_t AES_Td3[256] = { -    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, -    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, -    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, -    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, -    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, -    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, -    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, -    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, -    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, -    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, -    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, -    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, -    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, -    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, -    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, -    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, -    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, -    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, -    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, -    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, -    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, -    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, -    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, -    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, -    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, -    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, -    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, -    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, -    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, -    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, -    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, -    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, -    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, -    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, -    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, -    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, -    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, -    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, -    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, -    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, -    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, -    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, -    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, -    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, -    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, -    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, -    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, -    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, -    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, -    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, -    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, -    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, -    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, -    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, -    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, -    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, -    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, -    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, -    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, -    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, -    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, -    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, -    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, -    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, -}; -const uint32_t AES_Td4[256] = { -    0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, -    0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, -    0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, -    0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, -    0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, -    0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, -    0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, -    0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, -    0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, -    0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, -    0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, -    0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, -    0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, -    0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, -    0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, -    0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, -    0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, -    0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, -    0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, -    0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, -    0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, -    0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, -    0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, -    0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, -    0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, -    0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, -    0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, -    0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, -    0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, -    0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, -    0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, -    0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, -    0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, -    0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, -    0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, -    0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, -    0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, -    0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, -    0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, -    0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, -    0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, -    0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, -    0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, -    0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, -    0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, -    0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, -    0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, -    0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, -    0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, -    0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, -    0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, -    0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, -    0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, -    0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, -    0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, -    0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, -    0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, -    0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, -    0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, -    0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, -    0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, -    0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, -    0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, -    0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, -}; -static const u32 rcon[] = { -	0x01000000, 0x02000000, 0x04000000, 0x08000000, -	0x10000000, 0x20000000, 0x40000000, 0x80000000, -	0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -/** - * Expand the cipher key into the encryption key schedule. - */ -int AES_set_encrypt_key(const unsigned char *userKey, const int bits, -			AES_KEY *key) { - -	u32 *rk; -   	int i = 0; -	u32 temp; - -	if (!userKey || !key) -		return -1; -	if (bits != 128 && bits != 192 && bits != 256) -		return -2; - -	rk = key->rd_key; - -	if (bits==128) -		key->rounds = 10; -	else if (bits==192) -		key->rounds = 12; -	else -		key->rounds = 14; - -	rk[0] = GETU32(userKey     ); -	rk[1] = GETU32(userKey +  4); -	rk[2] = GETU32(userKey +  8); -	rk[3] = GETU32(userKey + 12); -	if (bits == 128) { -		while (1) { -			temp  = rk[3]; -			rk[4] = rk[0] ^ -                                (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^ -                                (AES_Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^ -                                (AES_Te4[(temp      ) & 0xff] & 0x0000ff00) ^ -                                (AES_Te4[(temp >> 24)       ] & 0x000000ff) ^ -				rcon[i]; -			rk[5] = rk[1] ^ rk[4]; -			rk[6] = rk[2] ^ rk[5]; -			rk[7] = rk[3] ^ rk[6]; -			if (++i == 10) { -				return 0; -			} -			rk += 4; -		} -	} -	rk[4] = GETU32(userKey + 16); -	rk[5] = GETU32(userKey + 20); -	if (bits == 192) { -		while (1) { -			temp = rk[ 5]; -			rk[ 6] = rk[ 0] ^ -                                (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^ -                                (AES_Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^ -                                (AES_Te4[(temp      ) & 0xff] & 0x0000ff00) ^ -                                (AES_Te4[(temp >> 24)       ] & 0x000000ff) ^ -				rcon[i]; -			rk[ 7] = rk[ 1] ^ rk[ 6]; -			rk[ 8] = rk[ 2] ^ rk[ 7]; -			rk[ 9] = rk[ 3] ^ rk[ 8]; -			if (++i == 8) { -				return 0; -			} -			rk[10] = rk[ 4] ^ rk[ 9]; -			rk[11] = rk[ 5] ^ rk[10]; -			rk += 6; -		} -	} -	rk[6] = GETU32(userKey + 24); -	rk[7] = GETU32(userKey + 28); -	if (bits == 256) { -		while (1) { -			temp = rk[ 7]; -			rk[ 8] = rk[ 0] ^ -                                (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^ -                                (AES_Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^ -                                (AES_Te4[(temp      ) & 0xff] & 0x0000ff00) ^ -                                (AES_Te4[(temp >> 24)       ] & 0x000000ff) ^ -				rcon[i]; -			rk[ 9] = rk[ 1] ^ rk[ 8]; -			rk[10] = rk[ 2] ^ rk[ 9]; -			rk[11] = rk[ 3] ^ rk[10]; -			if (++i == 7) { -				return 0; -			} -			temp = rk[11]; -			rk[12] = rk[ 4] ^ -                                (AES_Te4[(temp >> 24)       ] & 0xff000000) ^ -                                (AES_Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ -                                (AES_Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^ -                                (AES_Te4[(temp      ) & 0xff] & 0x000000ff); -			rk[13] = rk[ 5] ^ rk[12]; -			rk[14] = rk[ 6] ^ rk[13]; -			rk[15] = rk[ 7] ^ rk[14]; - -			rk += 8; -        	} -	} -	return 0; -} - -/** - * Expand the cipher key into the decryption key schedule. - */ -int AES_set_decrypt_key(const unsigned char *userKey, const int bits, -			 AES_KEY *key) { - -        u32 *rk; -	int i, j, status; -	u32 temp; - -	/* first, start with an encryption schedule */ -	status = AES_set_encrypt_key(userKey, bits, key); -	if (status < 0) -		return status; - -	rk = key->rd_key; - -	/* invert the order of the round keys: */ -	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { -		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp; -		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; -		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; -		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; -	} -	/* apply the inverse MixColumn transform to all round keys but the first and the last: */ -	for (i = 1; i < (key->rounds); i++) { -		rk += 4; -		rk[0] = -                        AES_Td0[AES_Te4[(rk[0] >> 24)       ] & 0xff] ^ -                        AES_Td1[AES_Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ -                        AES_Td2[AES_Te4[(rk[0] >>  8) & 0xff] & 0xff] ^ -                        AES_Td3[AES_Te4[(rk[0]      ) & 0xff] & 0xff]; -		rk[1] = -                        AES_Td0[AES_Te4[(rk[1] >> 24)       ] & 0xff] ^ -                        AES_Td1[AES_Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ -                        AES_Td2[AES_Te4[(rk[1] >>  8) & 0xff] & 0xff] ^ -                        AES_Td3[AES_Te4[(rk[1]      ) & 0xff] & 0xff]; -		rk[2] = -                        AES_Td0[AES_Te4[(rk[2] >> 24)       ] & 0xff] ^ -                        AES_Td1[AES_Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ -                        AES_Td2[AES_Te4[(rk[2] >>  8) & 0xff] & 0xff] ^ -                        AES_Td3[AES_Te4[(rk[2]      ) & 0xff] & 0xff]; -		rk[3] = -                        AES_Td0[AES_Te4[(rk[3] >> 24)       ] & 0xff] ^ -                        AES_Td1[AES_Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ -                        AES_Td2[AES_Te4[(rk[3] >>  8) & 0xff] & 0xff] ^ -                        AES_Td3[AES_Te4[(rk[3]      ) & 0xff] & 0xff]; -	} -	return 0; -} - -#ifndef AES_ASM -/* - * Encrypt a single block - * in and out can overlap - */ -void AES_encrypt(const unsigned char *in, unsigned char *out, -		 const AES_KEY *key) { - -	const u32 *rk; -	u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL -	int r; -#endif /* ?FULL_UNROLL */ - -	assert(in && out && key); -	rk = key->rd_key; - -	/* -	 * map byte array block to cipher state -	 * and add initial round key: -	 */ -	s0 = GETU32(in     ) ^ rk[0]; -	s1 = GETU32(in +  4) ^ rk[1]; -	s2 = GETU32(in +  8) ^ rk[2]; -	s3 = GETU32(in + 12) ^ rk[3]; -#ifdef FULL_UNROLL -	/* round 1: */ -        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[ 4]; -        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[ 5]; -        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[ 6]; -        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[ 7]; -   	/* round 2: */ -        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[ 8]; -        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[ 9]; -        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[10]; -        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[11]; -	/* round 3: */ -        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[12]; -        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[13]; -        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[14]; -        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[15]; -   	/* round 4: */ -        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[16]; -        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[17]; -        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[18]; -        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[19]; -	/* round 5: */ -        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[20]; -        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[21]; -        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[22]; -        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[23]; -   	/* round 6: */ -        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[24]; -        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[25]; -        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[26]; -        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[27]; -	/* round 7: */ -        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[28]; -        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[29]; -        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[30]; -        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[31]; -   	/* round 8: */ -        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[32]; -        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[33]; -        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[34]; -        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[35]; -	/* round 9: */ -        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[36]; -        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[37]; -        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[38]; -        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[39]; -    if (key->rounds > 10) { -        /* round 10: */ -        s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[40]; -        s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[41]; -        s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[42]; -        s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[43]; -        /* round 11: */ -        t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[44]; -        t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[45]; -        t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[46]; -        t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[47]; -        if (key->rounds > 12) { -            /* round 12: */ -            s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >>  8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[48]; -            s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >>  8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[49]; -            s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >>  8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[50]; -            s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >>  8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[51]; -            /* round 13: */ -            t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >>  8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[52]; -            t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >>  8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[53]; -            t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >>  8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[54]; -            t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >>  8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[55]; -        } -    } -    rk += key->rounds << 2; -#else  /* !FULL_UNROLL */ -    /* -     * Nr - 1 full rounds: -     */ -    r = key->rounds >> 1; -    for (;;) { -        t0 = -            AES_Te0[(s0 >> 24)       ] ^ -            AES_Te1[(s1 >> 16) & 0xff] ^ -            AES_Te2[(s2 >>  8) & 0xff] ^ -            AES_Te3[(s3      ) & 0xff] ^ -            rk[4]; -        t1 = -            AES_Te0[(s1 >> 24)       ] ^ -            AES_Te1[(s2 >> 16) & 0xff] ^ -            AES_Te2[(s3 >>  8) & 0xff] ^ -            AES_Te3[(s0      ) & 0xff] ^ -            rk[5]; -        t2 = -            AES_Te0[(s2 >> 24)       ] ^ -            AES_Te1[(s3 >> 16) & 0xff] ^ -            AES_Te2[(s0 >>  8) & 0xff] ^ -            AES_Te3[(s1      ) & 0xff] ^ -            rk[6]; -        t3 = -            AES_Te0[(s3 >> 24)       ] ^ -            AES_Te1[(s0 >> 16) & 0xff] ^ -            AES_Te2[(s1 >>  8) & 0xff] ^ -            AES_Te3[(s2      ) & 0xff] ^ -            rk[7]; - -        rk += 8; -        if (--r == 0) { -            break; -        } - -        s0 = -            AES_Te0[(t0 >> 24)       ] ^ -            AES_Te1[(t1 >> 16) & 0xff] ^ -            AES_Te2[(t2 >>  8) & 0xff] ^ -            AES_Te3[(t3      ) & 0xff] ^ -            rk[0]; -        s1 = -            AES_Te0[(t1 >> 24)       ] ^ -            AES_Te1[(t2 >> 16) & 0xff] ^ -            AES_Te2[(t3 >>  8) & 0xff] ^ -            AES_Te3[(t0      ) & 0xff] ^ -            rk[1]; -        s2 = -            AES_Te0[(t2 >> 24)       ] ^ -            AES_Te1[(t3 >> 16) & 0xff] ^ -            AES_Te2[(t0 >>  8) & 0xff] ^ -            AES_Te3[(t1      ) & 0xff] ^ -            rk[2]; -        s3 = -            AES_Te0[(t3 >> 24)       ] ^ -            AES_Te1[(t0 >> 16) & 0xff] ^ -            AES_Te2[(t1 >>  8) & 0xff] ^ -            AES_Te3[(t2      ) & 0xff] ^ -            rk[3]; -    } -#endif /* ?FULL_UNROLL */ -    /* -	 * apply last round and -	 * map cipher state to byte array block: -	 */ -	s0 = -                (AES_Te4[(t0 >> 24)       ] & 0xff000000) ^ -                (AES_Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ -                (AES_Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^ -                (AES_Te4[(t3      ) & 0xff] & 0x000000ff) ^ -		rk[0]; -	PUTU32(out     , s0); -	s1 = -                (AES_Te4[(t1 >> 24)       ] & 0xff000000) ^ -                (AES_Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ -                (AES_Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^ -                (AES_Te4[(t0      ) & 0xff] & 0x000000ff) ^ -		rk[1]; -	PUTU32(out +  4, s1); -	s2 = -                (AES_Te4[(t2 >> 24)       ] & 0xff000000) ^ -                (AES_Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ -                (AES_Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^ -                (AES_Te4[(t1      ) & 0xff] & 0x000000ff) ^ -		rk[2]; -	PUTU32(out +  8, s2); -	s3 = -                (AES_Te4[(t3 >> 24)       ] & 0xff000000) ^ -                (AES_Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ -                (AES_Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^ -                (AES_Te4[(t2      ) & 0xff] & 0x000000ff) ^ -		rk[3]; -	PUTU32(out + 12, s3); -} - -/* - * Decrypt a single block - * in and out can overlap - */ -void AES_decrypt(const unsigned char *in, unsigned char *out, -		 const AES_KEY *key) { - -	const u32 *rk; -	u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL -	int r; -#endif /* ?FULL_UNROLL */ - -	assert(in && out && key); -	rk = key->rd_key; - -	/* -	 * map byte array block to cipher state -	 * and add initial round key: -	 */ -    s0 = GETU32(in     ) ^ rk[0]; -    s1 = GETU32(in +  4) ^ rk[1]; -    s2 = GETU32(in +  8) ^ rk[2]; -    s3 = GETU32(in + 12) ^ rk[3]; -#ifdef FULL_UNROLL -    /* round 1: */ -    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[ 4]; -    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[ 5]; -    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[ 6]; -    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[ 7]; -    /* round 2: */ -    s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[ 8]; -    s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[ 9]; -    s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[10]; -    s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[11]; -    /* round 3: */ -    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[12]; -    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[13]; -    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[14]; -    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[15]; -    /* round 4: */ -    s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[16]; -    s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[17]; -    s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[18]; -    s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[19]; -    /* round 5: */ -    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[20]; -    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[21]; -    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[22]; -    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[23]; -    /* round 6: */ -    s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[24]; -    s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[25]; -    s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[26]; -    s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[27]; -    /* round 7: */ -    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[28]; -    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[29]; -    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[30]; -    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[31]; -    /* round 8: */ -    s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[32]; -    s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[33]; -    s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[34]; -    s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[35]; -    /* round 9: */ -    t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[36]; -    t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[37]; -    t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[38]; -    t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[39]; -    if (key->rounds > 10) { -        /* round 10: */ -        s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[40]; -        s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[41]; -        s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[42]; -        s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[43]; -        /* round 11: */ -        t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[44]; -        t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[45]; -        t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[46]; -        t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[47]; -        if (key->rounds > 12) { -            /* round 12: */ -            s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >>  8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[48]; -            s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >>  8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[49]; -            s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >>  8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[50]; -            s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >>  8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[51]; -            /* round 13: */ -            t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >>  8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[52]; -            t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >>  8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[53]; -            t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >>  8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[54]; -            t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >>  8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[55]; -        } -    } -	rk += key->rounds << 2; -#else  /* !FULL_UNROLL */ -    /* -     * Nr - 1 full rounds: -     */ -    r = key->rounds >> 1; -    for (;;) { -        t0 = -            AES_Td0[(s0 >> 24)       ] ^ -            AES_Td1[(s3 >> 16) & 0xff] ^ -            AES_Td2[(s2 >>  8) & 0xff] ^ -            AES_Td3[(s1      ) & 0xff] ^ -            rk[4]; -        t1 = -            AES_Td0[(s1 >> 24)       ] ^ -            AES_Td1[(s0 >> 16) & 0xff] ^ -            AES_Td2[(s3 >>  8) & 0xff] ^ -            AES_Td3[(s2      ) & 0xff] ^ -            rk[5]; -        t2 = -            AES_Td0[(s2 >> 24)       ] ^ -            AES_Td1[(s1 >> 16) & 0xff] ^ -            AES_Td2[(s0 >>  8) & 0xff] ^ -            AES_Td3[(s3      ) & 0xff] ^ -            rk[6]; -        t3 = -            AES_Td0[(s3 >> 24)       ] ^ -            AES_Td1[(s2 >> 16) & 0xff] ^ -            AES_Td2[(s1 >>  8) & 0xff] ^ -            AES_Td3[(s0      ) & 0xff] ^ -            rk[7]; - -        rk += 8; -        if (--r == 0) { -            break; -        } - -        s0 = -            AES_Td0[(t0 >> 24)       ] ^ -            AES_Td1[(t3 >> 16) & 0xff] ^ -            AES_Td2[(t2 >>  8) & 0xff] ^ -            AES_Td3[(t1      ) & 0xff] ^ -            rk[0]; -        s1 = -            AES_Td0[(t1 >> 24)       ] ^ -            AES_Td1[(t0 >> 16) & 0xff] ^ -            AES_Td2[(t3 >>  8) & 0xff] ^ -            AES_Td3[(t2      ) & 0xff] ^ -            rk[1]; -        s2 = -            AES_Td0[(t2 >> 24)       ] ^ -            AES_Td1[(t1 >> 16) & 0xff] ^ -            AES_Td2[(t0 >>  8) & 0xff] ^ -            AES_Td3[(t3      ) & 0xff] ^ -            rk[2]; -        s3 = -            AES_Td0[(t3 >> 24)       ] ^ -            AES_Td1[(t2 >> 16) & 0xff] ^ -            AES_Td2[(t1 >>  8) & 0xff] ^ -            AES_Td3[(t0      ) & 0xff] ^ -            rk[3]; -    } -#endif /* ?FULL_UNROLL */ -    /* -	 * apply last round and -	 * map cipher state to byte array block: -	 */ -   	s0 = -                (AES_Td4[(t0 >> 24)       ] & 0xff000000) ^ -                (AES_Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ -                (AES_Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^ -                (AES_Td4[(t1      ) & 0xff] & 0x000000ff) ^ -   		rk[0]; -	PUTU32(out     , s0); -   	s1 = -                (AES_Td4[(t1 >> 24)       ] & 0xff000000) ^ -                (AES_Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ -                (AES_Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^ -                (AES_Td4[(t2      ) & 0xff] & 0x000000ff) ^ -   		rk[1]; -	PUTU32(out +  4, s1); -   	s2 = -                (AES_Td4[(t2 >> 24)       ] & 0xff000000) ^ -                (AES_Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ -                (AES_Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^ -                (AES_Td4[(t3      ) & 0xff] & 0x000000ff) ^ -   		rk[2]; -	PUTU32(out +  8, s2); -   	s3 = -                (AES_Td4[(t3 >> 24)       ] & 0xff000000) ^ -                (AES_Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ -                (AES_Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^ -                (AES_Td4[(t0      ) & 0xff] & 0x000000ff) ^ -   		rk[3]; -	PUTU32(out + 12, s3); -} - -#endif /* AES_ASM */ - -void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, -		     const unsigned long length, const AES_KEY *key, -		     unsigned char *ivec, const int enc) -{ - -	unsigned long n; -	unsigned long len = length; -	unsigned char tmp[AES_BLOCK_SIZE]; - -	assert(in && out && key && ivec); - -	if (enc) { -		while (len >= AES_BLOCK_SIZE) { -			for(n=0; n < AES_BLOCK_SIZE; ++n) -				tmp[n] = in[n] ^ ivec[n]; -			AES_encrypt(tmp, out, key); -			memcpy(ivec, out, AES_BLOCK_SIZE); -			len -= AES_BLOCK_SIZE; -			in += AES_BLOCK_SIZE; -			out += AES_BLOCK_SIZE; -		} -		if (len) { -			for(n=0; n < len; ++n) -				tmp[n] = in[n] ^ ivec[n]; -			for(n=len; n < AES_BLOCK_SIZE; ++n) -				tmp[n] = ivec[n]; -			AES_encrypt(tmp, tmp, key); -			memcpy(out, tmp, AES_BLOCK_SIZE); -			memcpy(ivec, tmp, AES_BLOCK_SIZE); -		} -	} else { -		while (len >= AES_BLOCK_SIZE) { -			memcpy(tmp, in, AES_BLOCK_SIZE); -			AES_decrypt(in, out, key); -			for(n=0; n < AES_BLOCK_SIZE; ++n) -				out[n] ^= ivec[n]; -			memcpy(ivec, tmp, AES_BLOCK_SIZE); -			len -= AES_BLOCK_SIZE; -			in += AES_BLOCK_SIZE; -			out += AES_BLOCK_SIZE; -		} -		if (len) { -			memcpy(tmp, in, AES_BLOCK_SIZE); -			AES_decrypt(tmp, tmp, key); -			for(n=0; n < len; ++n) -				out[n] = tmp[n] ^ ivec[n]; -			memcpy(ivec, tmp, AES_BLOCK_SIZE); -		} -	} -} diff --git a/contrib/qemu/util/bitmap.c b/contrib/qemu/util/bitmap.c deleted file mode 100644 index 687841dcec0..00000000000 --- a/contrib/qemu/util/bitmap.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Bitmap Module - * - * Stolen from linux/src/lib/bitmap.c - * - * Copyright (C) 2010 Corentin Chary - * - * This source code is licensed under the GNU General Public License, - * Version 2. - */ - -#include "qemu/bitops.h" -#include "qemu/bitmap.h" - -/* - * bitmaps provide an array of bits, implemented using an an - * array of unsigned longs.  The number of valid bits in a - * given bitmap does _not_ need to be an exact multiple of - * BITS_PER_LONG. - * - * The possible unused bits in the last, partially used word - * of a bitmap are 'don't care'.  The implementation makes - * no particular effort to keep them zero.  It ensures that - * their value will not affect the results of any operation. - * The bitmap operations that return Boolean (bitmap_empty, - * for example) or scalar (bitmap_weight, for example) results - * carefully filter out these unused bits from impacting their - * results. - * - * These operations actually hold to a slightly stronger rule: - * if you don't input any bitmaps to these ops that have some - * unused bits set, then they won't output any set unused bits - * in output bitmaps. - * - * The byte ordering of bitmaps is more natural on little - * endian architectures. - */ - -int slow_bitmap_empty(const unsigned long *bitmap, int bits) -{ -    int k, lim = bits/BITS_PER_LONG; - -    for (k = 0; k < lim; ++k) { -        if (bitmap[k]) { -            return 0; -        } -    } -    if (bits % BITS_PER_LONG) { -        if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) { -            return 0; -        } -    } - -    return 1; -} - -int slow_bitmap_full(const unsigned long *bitmap, int bits) -{ -    int k, lim = bits/BITS_PER_LONG; - -    for (k = 0; k < lim; ++k) { -        if (~bitmap[k]) { -            return 0; -        } -    } - -    if (bits % BITS_PER_LONG) { -        if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) { -            return 0; -        } -    } - -    return 1; -} - -int slow_bitmap_equal(const unsigned long *bitmap1, -                      const unsigned long *bitmap2, int bits) -{ -    int k, lim = bits/BITS_PER_LONG; - -    for (k = 0; k < lim; ++k) { -        if (bitmap1[k] != bitmap2[k]) { -            return 0; -        } -    } - -    if (bits % BITS_PER_LONG) { -        if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) { -            return 0; -        } -    } - -    return 1; -} - -void slow_bitmap_complement(unsigned long *dst, const unsigned long *src, -                            int bits) -{ -    int k, lim = bits/BITS_PER_LONG; - -    for (k = 0; k < lim; ++k) { -        dst[k] = ~src[k]; -    } - -    if (bits % BITS_PER_LONG) { -        dst[k] = ~src[k] & BITMAP_LAST_WORD_MASK(bits); -    } -} - -int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1, -                    const unsigned long *bitmap2, int bits) -{ -    int k; -    int nr = BITS_TO_LONGS(bits); -    unsigned long result = 0; - -    for (k = 0; k < nr; k++) { -        result |= (dst[k] = bitmap1[k] & bitmap2[k]); -    } -    return result != 0; -} - -void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1, -                    const unsigned long *bitmap2, int bits) -{ -    int k; -    int nr = BITS_TO_LONGS(bits); - -    for (k = 0; k < nr; k++) { -        dst[k] = bitmap1[k] | bitmap2[k]; -    } -} - -void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, -                     const unsigned long *bitmap2, int bits) -{ -    int k; -    int nr = BITS_TO_LONGS(bits); - -    for (k = 0; k < nr; k++) { -        dst[k] = bitmap1[k] ^ bitmap2[k]; -    } -} - -int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, -                       const unsigned long *bitmap2, int bits) -{ -    int k; -    int nr = BITS_TO_LONGS(bits); -    unsigned long result = 0; - -    for (k = 0; k < nr; k++) { -        result |= (dst[k] = bitmap1[k] & ~bitmap2[k]); -    } -    return result != 0; -} - -#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG)) - -void bitmap_set(unsigned long *map, int start, int nr) -{ -    unsigned long *p = map + BIT_WORD(start); -    const int size = start + nr; -    int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); -    unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); - -    while (nr - bits_to_set >= 0) { -        *p |= mask_to_set; -        nr -= bits_to_set; -        bits_to_set = BITS_PER_LONG; -        mask_to_set = ~0UL; -        p++; -    } -    if (nr) { -        mask_to_set &= BITMAP_LAST_WORD_MASK(size); -        *p |= mask_to_set; -    } -} - -void bitmap_clear(unsigned long *map, int start, int nr) -{ -    unsigned long *p = map + BIT_WORD(start); -    const int size = start + nr; -    int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); -    unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); - -    while (nr - bits_to_clear >= 0) { -        *p &= ~mask_to_clear; -        nr -= bits_to_clear; -        bits_to_clear = BITS_PER_LONG; -        mask_to_clear = ~0UL; -        p++; -    } -    if (nr) { -        mask_to_clear &= BITMAP_LAST_WORD_MASK(size); -        *p &= ~mask_to_clear; -    } -} - -#define ALIGN_MASK(x,mask)      (((x)+(mask))&~(mask)) - -/** - * bitmap_find_next_zero_area - find a contiguous aligned zero area - * @map: The address to base the search on - * @size: The bitmap size in bits - * @start: The bitnumber to start searching at - * @nr: The number of zeroed bits we're looking for - * @align_mask: Alignment mask for zero area - * - * The @align_mask should be one less than a power of 2; the effect is that - * the bit offset of all zero areas this function finds is multiples of that - * power of 2. A @align_mask of 0 means no alignment is required. - */ -unsigned long bitmap_find_next_zero_area(unsigned long *map, -					 unsigned long size, -					 unsigned long start, -					 unsigned int nr, -					 unsigned long align_mask) -{ -    unsigned long index, end, i; -again: -    index = find_next_zero_bit(map, size, start); - -    /* Align allocation */ -    index = ALIGN_MASK(index, align_mask); - -    end = index + nr; -    if (end > size) { -        return end; -    } -    i = find_next_bit(map, end, index); -    if (i < end) { -        start = i + 1; -        goto again; -    } -    return index; -} - -int slow_bitmap_intersects(const unsigned long *bitmap1, -                           const unsigned long *bitmap2, int bits) -{ -    int k, lim = bits/BITS_PER_LONG; - -    for (k = 0; k < lim; ++k) { -        if (bitmap1[k] & bitmap2[k]) { -            return 1; -        } -    } - -    if (bits % BITS_PER_LONG) { -        if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) { -            return 1; -        } -    } -    return 0; -} diff --git a/contrib/qemu/util/bitops.c b/contrib/qemu/util/bitops.c deleted file mode 100644 index 227c38b883d..00000000000 --- a/contrib/qemu/util/bitops.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * Copyright (C) 2008 IBM Corporation - * Written by Rusty Russell <rusty@rustcorp.com.au> - * (Inspired by David Howell's find_next_bit implementation) - * - * 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/bitops.h" - -#define BITOP_WORD(nr)		((nr) / BITS_PER_LONG) - -/* - * Find the next set bit in a memory region. - */ -unsigned long find_next_bit(const unsigned long *addr, unsigned long size, -			    unsigned long offset) -{ -    const unsigned long *p = addr + BITOP_WORD(offset); -    unsigned long result = offset & ~(BITS_PER_LONG-1); -    unsigned long tmp; - -    if (offset >= size) { -        return size; -    } -    size -= result; -    offset %= BITS_PER_LONG; -    if (offset) { -        tmp = *(p++); -        tmp &= (~0UL << offset); -        if (size < BITS_PER_LONG) { -            goto found_first; -        } -        if (tmp) { -            goto found_middle; -        } -        size -= BITS_PER_LONG; -        result += BITS_PER_LONG; -    } -    while (size >= 4*BITS_PER_LONG) { -        unsigned long d1, d2, d3; -        tmp = *p; -        d1 = *(p+1); -        d2 = *(p+2); -        d3 = *(p+3); -        if (tmp) { -            goto found_middle; -        } -        if (d1 | d2 | d3) { -            break; -        } -        p += 4; -        result += 4*BITS_PER_LONG; -        size -= 4*BITS_PER_LONG; -    } -    while (size >= BITS_PER_LONG) { -        if ((tmp = *(p++))) { -            goto found_middle; -        } -        result += BITS_PER_LONG; -        size -= BITS_PER_LONG; -    } -    if (!size) { -        return result; -    } -    tmp = *p; - -found_first: -    tmp &= (~0UL >> (BITS_PER_LONG - size)); -    if (tmp == 0UL) {		/* Are any bits set? */ -        return result + size;	/* Nope. */ -    } -found_middle: -    return result + ctzl(tmp); -} - -/* - * This implementation of find_{first,next}_zero_bit was stolen from - * Linus' asm-alpha/bitops.h. - */ -unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, -				 unsigned long offset) -{ -    const unsigned long *p = addr + BITOP_WORD(offset); -    unsigned long result = offset & ~(BITS_PER_LONG-1); -    unsigned long tmp; - -    if (offset >= size) { -        return size; -    } -    size -= result; -    offset %= BITS_PER_LONG; -    if (offset) { -        tmp = *(p++); -        tmp |= ~0UL >> (BITS_PER_LONG - offset); -        if (size < BITS_PER_LONG) { -            goto found_first; -        } -        if (~tmp) { -            goto found_middle; -        } -        size -= BITS_PER_LONG; -        result += BITS_PER_LONG; -    } -    while (size & ~(BITS_PER_LONG-1)) { -        if (~(tmp = *(p++))) { -            goto found_middle; -        } -        result += BITS_PER_LONG; -        size -= BITS_PER_LONG; -    } -    if (!size) { -        return result; -    } -    tmp = *p; - -found_first: -    tmp |= ~0UL << size; -    if (tmp == ~0UL) {	/* Are any bits zero? */ -        return result + size;	/* Nope. */ -    } -found_middle: -    return result + ctzl(~tmp); -} - -unsigned long find_last_bit(const unsigned long *addr, unsigned long size) -{ -    unsigned long words; -    unsigned long tmp; - -    /* Start at final word. */ -    words = size / BITS_PER_LONG; - -    /* Partial final word? */ -    if (size & (BITS_PER_LONG-1)) { -        tmp = (addr[words] & (~0UL >> (BITS_PER_LONG -                                       - (size & (BITS_PER_LONG-1))))); -        if (tmp) { -            goto found; -        } -    } - -    while (words) { -        tmp = addr[--words]; -        if (tmp) { -        found: -            return words * BITS_PER_LONG + BITS_PER_LONG - 1 - clzl(tmp); -        } -    } - -    /* Not found */ -    return size; -} diff --git a/contrib/qemu/util/cutils.c b/contrib/qemu/util/cutils.c deleted file mode 100644 index 6caa4b8ddc4..00000000000 --- a/contrib/qemu/util/cutils.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Simple C functions to supplement the C library - * - * Copyright (c) 2006 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "qemu-common.h" -#include "qemu/host-utils.h" -#include <math.h> - -#include "qemu/sockets.h" -#include "qemu/iov.h" - -void strpadcpy(char *buf, int buf_size, const char *str, char pad) -{ -    int len = qemu_strnlen(str, buf_size); -    memcpy(buf, str, len); -    memset(buf + len, pad, buf_size - len); -} - -void pstrcpy(char *buf, int buf_size, const char *str) -{ -    int c; -    char *q = buf; - -    if (buf_size <= 0) -        return; - -    for(;;) { -        c = *str++; -        if (c == 0 || q >= buf + buf_size - 1) -            break; -        *q++ = c; -    } -    *q = '\0'; -} - -/* strcat and truncate. */ -char *pstrcat(char *buf, int buf_size, const char *s) -{ -    int len; -    len = strlen(buf); -    if (len < buf_size) -        pstrcpy(buf + len, buf_size - len, s); -    return buf; -} - -int strstart(const char *str, const char *val, const char **ptr) -{ -    const char *p, *q; -    p = str; -    q = val; -    while (*q != '\0') { -        if (*p != *q) -            return 0; -        p++; -        q++; -    } -    if (ptr) -        *ptr = p; -    return 1; -} - -int stristart(const char *str, const char *val, const char **ptr) -{ -    const char *p, *q; -    p = str; -    q = val; -    while (*q != '\0') { -        if (qemu_toupper(*p) != qemu_toupper(*q)) -            return 0; -        p++; -        q++; -    } -    if (ptr) -        *ptr = p; -    return 1; -} - -/* XXX: use host strnlen if available ? */ -int qemu_strnlen(const char *s, int max_len) -{ -    int i; - -    for(i = 0; i < max_len; i++) { -        if (s[i] == '\0') { -            break; -        } -    } -    return i; -} - -char *qemu_strsep(char **input, const char *delim) -{ -    char *result = *input; -    if (result != NULL) { -        char *p; - -        for (p = result; *p != '\0'; p++) { -            if (strchr(delim, *p)) { -                break; -            } -        } -        if (*p == '\0') { -            *input = NULL; -        } else { -            *p = '\0'; -            *input = p + 1; -        } -    } -    return result; -} - -time_t mktimegm(struct tm *tm) -{ -    time_t t; -    int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday; -    if (m < 3) { -        m += 12; -        y--; -    } -    t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +  -                 y / 400 - 719469); -    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; -    return t; -} - -int qemu_fls(int i) -{ -    return 32 - clz32(i); -} - -/* - * Make sure data goes on disk, but if possible do not bother to - * write out the inode just for timestamp updates. - * - * Unfortunately even in 2009 many operating systems do not support - * fdatasync and have to fall back to fsync. - */ -int qemu_fdatasync(int fd) -{ -#ifdef HAVE_FDATASYNC -    return fdatasync(fd); -#else -    return fsync(fd); -#endif -} - -/* - * Searches for an area with non-zero content in a buffer - * - * Attention! The len must be a multiple of - * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE) - * and addr must be a multiple of sizeof(VECTYPE) due to - * restriction of optimizations in this function. - * - * can_use_buffer_find_nonzero_offset() can be used to check - * these requirements. - * - * The return value is the offset of the non-zero area rounded - * down to a multiple of sizeof(VECTYPE) for the first - * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR chunks and down to - * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE) - * afterwards. - * - * If the buffer is all zero the return value is equal to len. - */ - -size_t buffer_find_nonzero_offset(const void *buf, size_t len) -{ -    const VECTYPE *p = buf; -    const VECTYPE zero = (VECTYPE){0}; -    size_t i; - -    assert(can_use_buffer_find_nonzero_offset(buf, len)); - -    if (!len) { -        return 0; -    } - -    for (i = 0; i < BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) { -        if (!ALL_EQ(p[i], zero)) { -            return i * sizeof(VECTYPE); -        } -    } - -    for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; -         i < len / sizeof(VECTYPE); -         i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) { -        VECTYPE tmp0 = p[i + 0] | p[i + 1]; -        VECTYPE tmp1 = p[i + 2] | p[i + 3]; -        VECTYPE tmp2 = p[i + 4] | p[i + 5]; -        VECTYPE tmp3 = p[i + 6] | p[i + 7]; -        VECTYPE tmp01 = tmp0 | tmp1; -        VECTYPE tmp23 = tmp2 | tmp3; -        if (!ALL_EQ(tmp01 | tmp23, zero)) { -            break; -        } -    } - -    return i * sizeof(VECTYPE); -} - -/* - * Checks if a buffer is all zeroes - * - * Attention! The len must be a multiple of 4 * sizeof(long) due to - * restriction of optimizations in this function. - */ -bool buffer_is_zero(const void *buf, size_t len) -{ -    /* -     * Use long as the biggest available internal data type that fits into the -     * CPU register and unroll the loop to smooth out the effect of memory -     * latency. -     */ - -    size_t i; -    long d0, d1, d2, d3; -    const long * const data = buf; - -    /* use vector optimized zero check if possible */ -    if (can_use_buffer_find_nonzero_offset(buf, len)) { -        return buffer_find_nonzero_offset(buf, len) == len; -    } - -    assert(len % (4 * sizeof(long)) == 0); -    len /= sizeof(long); - -    for (i = 0; i < len; i += 4) { -        d0 = data[i + 0]; -        d1 = data[i + 1]; -        d2 = data[i + 2]; -        d3 = data[i + 3]; - -        if (d0 || d1 || d2 || d3) { -            return false; -        } -    } - -    return true; -} - -#ifndef _WIN32 -/* Sets a specific flag */ -int fcntl_setfl(int fd, int flag) -{ -    int flags; - -    flags = fcntl(fd, F_GETFL); -    if (flags == -1) -        return -errno; - -    if (fcntl(fd, F_SETFL, flags | flag) == -1) -        return -errno; - -    return 0; -} -#endif - -static int64_t suffix_mul(char suffix, int64_t unit) -{ -    switch (qemu_toupper(suffix)) { -    case STRTOSZ_DEFSUFFIX_B: -        return 1; -    case STRTOSZ_DEFSUFFIX_KB: -        return unit; -    case STRTOSZ_DEFSUFFIX_MB: -        return unit * unit; -    case STRTOSZ_DEFSUFFIX_GB: -        return unit * unit * unit; -    case STRTOSZ_DEFSUFFIX_TB: -        return unit * unit * unit * unit; -    case STRTOSZ_DEFSUFFIX_PB: -        return unit * unit * unit * unit * unit; -    case STRTOSZ_DEFSUFFIX_EB: -        return unit * unit * unit * unit * unit * unit; -    } -    return -1; -} - -/* - * Convert string to bytes, allowing either B/b for bytes, K/k for KB, - * M/m for MB, G/g for GB or T/t for TB. End pointer will be returned - * in *end, if not NULL. Return -ERANGE on overflow, Return -EINVAL on - * other error. - */ -int64_t strtosz_suffix_unit(const char *nptr, char **end, -                            const char default_suffix, int64_t unit) -{ -    int64_t retval = -EINVAL; -    char *endptr; -    unsigned char c; -    int mul_required = 0; -    double val, mul, integral, fraction; - -    errno = 0; -    val = strtod(nptr, &endptr); -    if (isnan(val) || endptr == nptr || errno != 0) { -        goto fail; -    } -    fraction = modf(val, &integral); -    if (fraction != 0) { -        mul_required = 1; -    } -    c = *endptr; -    mul = suffix_mul(c, unit); -    if (mul >= 0) { -        endptr++; -    } else { -        mul = suffix_mul(default_suffix, unit); -        assert(mul >= 0); -    } -    if (mul == 1 && mul_required) { -        goto fail; -    } -    if ((val * mul >= INT64_MAX) || val < 0) { -        retval = -ERANGE; -        goto fail; -    } -    retval = val * mul; - -fail: -    if (end) { -        *end = endptr; -    } - -    return retval; -} - -int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) -{ -    return strtosz_suffix_unit(nptr, end, default_suffix, 1024); -} - -int64_t strtosz(const char *nptr, char **end) -{ -    return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB); -} - -/** - * parse_uint: - * - * @s: String to parse - * @value: Destination for parsed integer value - * @endptr: Destination for pointer to first character not consumed - * @base: integer base, between 2 and 36 inclusive, or 0 - * - * Parse unsigned integer - * - * Parsed syntax is like strtoull()'s: arbitrary whitespace, a single optional - * '+' or '-', an optional "0x" if @base is 0 or 16, one or more digits. - * - * If @s is null, or @base is invalid, or @s doesn't start with an - * integer in the syntax above, set *@value to 0, *@endptr to @s, and - * return -EINVAL. - * - * Set *@endptr to point right beyond the parsed integer (even if the integer - * overflows or is negative, all digits will be parsed and *@endptr will - * point right beyond them). - * - * If the integer is negative, set *@value to 0, and return -ERANGE. - * - * If the integer overflows unsigned long long, set *@value to - * ULLONG_MAX, and return -ERANGE. - * - * Else, set *@value to the parsed integer, and return 0. - */ -int parse_uint(const char *s, unsigned long long *value, char **endptr, -               int base) -{ -    int r = 0; -    char *endp = (char *)s; -    unsigned long long val = 0; - -    if (!s) { -        r = -EINVAL; -        goto out; -    } - -    errno = 0; -    val = strtoull(s, &endp, base); -    if (errno) { -        r = -errno; -        goto out; -    } - -    if (endp == s) { -        r = -EINVAL; -        goto out; -    } - -    /* make sure we reject negative numbers: */ -    while (isspace((unsigned char)*s)) { -        s++; -    } -    if (*s == '-') { -        val = 0; -        r = -ERANGE; -        goto out; -    } - -out: -    *value = val; -    *endptr = endp; -    return r; -} - -/** - * parse_uint_full: - * - * @s: String to parse - * @value: Destination for parsed integer value - * @base: integer base, between 2 and 36 inclusive, or 0 - * - * Parse unsigned integer from entire string - * - * Have the same behavior of parse_uint(), but with an additional check - * for additional data after the parsed number. If extra characters are present - * after the parsed number, the function will return -EINVAL, and *@v will - * be set to 0. - */ -int parse_uint_full(const char *s, unsigned long long *value, int base) -{ -    char *endp; -    int r; - -    r = parse_uint(s, value, &endp, base); -    if (r < 0) { -        return r; -    } -    if (*endp) { -        *value = 0; -        return -EINVAL; -    } - -    return 0; -} - -int qemu_parse_fd(const char *param) -{ -    int fd; -    char *endptr = NULL; - -    fd = strtol(param, &endptr, 10); -    if (*endptr || (fd == 0 && param == endptr)) { -        return -1; -    } -    return fd; -} - -/* round down to the nearest power of 2*/ -int64_t pow2floor(int64_t value) -{ -    if (!is_power_of_2(value)) { -        value = 0x8000000000000000ULL >> clz64(value); -    } -    return value; -} - -/* - * Implementation of  ULEB128 (http://en.wikipedia.org/wiki/LEB128) - * Input is limited to 14-bit numbers - */ -int uleb128_encode_small(uint8_t *out, uint32_t n) -{ -    g_assert(n <= 0x3fff); -    if (n < 0x80) { -        *out++ = n; -        return 1; -    } else { -        *out++ = (n & 0x7f) | 0x80; -        *out++ = n >> 7; -        return 2; -    } -} - -int uleb128_decode_small(const uint8_t *in, uint32_t *n) -{ -    if (!(*in & 0x80)) { -        *n = *in++; -        return 1; -    } else { -        *n = *in++ & 0x7f; -        /* we exceed 14 bit number */ -        if (*in & 0x80) { -            return -1; -        } -        *n |= *in++ << 7; -        return 2; -    } -} - -/* - * helper to parse debug environment variables - */ -int parse_debug_env(const char *name, int max, int initial) -{ -    char *debug_env = getenv(name); -    char *inv = NULL; -    int debug; - -    if (!debug_env) { -        return initial; -    } -    debug = strtol(debug_env, &inv, 10); -    if (inv == debug_env) { -        return initial; -    } -    if (debug < 0 || debug > max) { -        fprintf(stderr, "warning: %s not in [0, %d]", name, max); -        return initial; -    } -    return debug; -} diff --git a/contrib/qemu/util/error.c b/contrib/qemu/util/error.c deleted file mode 100644 index 53b04354aef..00000000000 --- a/contrib/qemu/util/error.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * QEMU Error Objects - * - * Copyright IBM, Corp. 2011 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.  See - * the COPYING.LIB file in the top-level directory. - */ - -#include "qemu-common.h" -#include "qapi/error.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/qdict.h" -#include "qapi-types.h" -#include "qapi/qmp/qerror.h" - -struct Error -{ -    char *msg; -    ErrorClass err_class; -}; - -void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...) -{ -    Error *err; -    va_list ap; - -    if (errp == NULL) { -        return; -    } -    assert(*errp == NULL); - -    err = g_malloc0(sizeof(*err)); - -    va_start(ap, fmt); -    err->msg = g_strdup_vprintf(fmt, ap); -    va_end(ap); -    err->err_class = err_class; - -    *errp = err; -} - -void error_set_errno(Error **errp, int os_errno, ErrorClass err_class, -                     const char *fmt, ...) -{ -    Error *err; -    char *msg1; -    va_list ap; - -    if (errp == NULL) { -        return; -    } -    assert(*errp == NULL); - -    err = g_malloc0(sizeof(*err)); - -    va_start(ap, fmt); -    msg1 = g_strdup_vprintf(fmt, ap); -    if (os_errno != 0) { -        err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno)); -        g_free(msg1); -    } else { -        err->msg = msg1; -    } -    va_end(ap); -    err->err_class = err_class; - -    *errp = err; -} - -void error_setg_file_open(Error **errp, int os_errno, const char *filename) -{ -    error_setg_errno(errp, os_errno, "Could not open '%s'", filename); -} - -Error *error_copy(const Error *err) -{ -    Error *err_new; - -    err_new = g_malloc0(sizeof(*err)); -    err_new->msg = g_strdup(err->msg); -    err_new->err_class = err->err_class; - -    return err_new; -} - -bool error_is_set(Error **errp) -{ -    return (errp && *errp); -} - -ErrorClass error_get_class(const Error *err) -{ -    return err->err_class; -} - -const char *error_get_pretty(Error *err) -{ -    return err->msg; -} - -void error_free(Error *err) -{ -    if (err) { -        g_free(err->msg); -        g_free(err); -    } -} - -void error_propagate(Error **dst_err, Error *local_err) -{ -    if (dst_err && !*dst_err) { -        *dst_err = local_err; -    } else if (local_err) { -        error_free(local_err); -    } -} diff --git a/contrib/qemu/util/hbitmap.c b/contrib/qemu/util/hbitmap.c deleted file mode 100644 index e063e681f52..00000000000 --- a/contrib/qemu/util/hbitmap.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Hierarchical Bitmap Data Type - * - * Copyright Red Hat, Inc., 2012 - * - * Author: Paolo Bonzini <pbonzini@redhat.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or - * later.  See the COPYING file in the top-level directory. - */ - -#include <string.h> -#include <glib.h> -#include <assert.h> -#include "qemu/osdep.h" -#include "qemu/hbitmap.h" -#include "qemu/host-utils.h" -#include "trace.h" - -/* HBitmaps provides an array of bits.  The bits are stored as usual in an - * array of unsigned longs, but HBitmap is also optimized to provide fast - * iteration over set bits; going from one bit to the next is O(logB n) - * worst case, with B = sizeof(long) * CHAR_BIT: the result is low enough - * that the number of levels is in fact fixed. - * - * In order to do this, it stacks multiple bitmaps with progressively coarser - * granularity; in all levels except the last, bit N is set iff the N-th - * unsigned long is nonzero in the immediately next level.  When iteration - * completes on the last level it can examine the 2nd-last level to quickly - * skip entire words, and even do so recursively to skip blocks of 64 words or - * powers thereof (32 on 32-bit machines). - * - * Given an index in the bitmap, it can be split in group of bits like - * this (for the 64-bit case): - * - *   bits 0-57 => word in the last bitmap     | bits 58-63 => bit in the word - *   bits 0-51 => word in the 2nd-last bitmap | bits 52-57 => bit in the word - *   bits 0-45 => word in the 3rd-last bitmap | bits 46-51 => bit in the word - * - * So it is easy to move up simply by shifting the index right by - * log2(BITS_PER_LONG) bits.  To move down, you shift the index left - * similarly, and add the word index within the group.  Iteration uses - * ffs (find first set bit) to find the next word to examine; this - * operation can be done in constant time in most current architectures. - * - * Setting or clearing a range of m bits on all levels, the work to perform - * is O(m + m/W + m/W^2 + ...), which is O(m) like on a regular bitmap. - * - * When iterating on a bitmap, each bit (on any level) is only visited - * once.  Hence, The total cost of visiting a bitmap with m bits in it is - * the number of bits that are set in all bitmaps.  Unless the bitmap is - * extremely sparse, this is also O(m + m/W + m/W^2 + ...), so the amortized - * cost of advancing from one bit to the next is usually constant (worst case - * O(logB n) as in the non-amortized complexity). - */ - -struct HBitmap { -    /* Number of total bits in the bottom level.  */ -    uint64_t size; - -    /* Number of set bits in the bottom level.  */ -    uint64_t count; - -    /* A scaling factor.  Given a granularity of G, each bit in the bitmap will -     * will actually represent a group of 2^G elements.  Each operation on a -     * range of bits first rounds the bits to determine which group they land -     * in, and then affect the entire page; iteration will only visit the first -     * bit of each group.  Here is an example of operations in a size-16, -     * granularity-1 HBitmap: -     * -     *    initial state            00000000 -     *    set(start=0, count=9)    11111000 (iter: 0, 2, 4, 6, 8) -     *    reset(start=1, count=3)  00111000 (iter: 4, 6, 8) -     *    set(start=9, count=2)    00111100 (iter: 4, 6, 8, 10) -     *    reset(start=5, count=5)  00000000 -     * -     * From an implementation point of view, when setting or resetting bits, -     * the bitmap will scale bit numbers right by this amount of bits.  When -     * iterating, the bitmap will scale bit numbers left by this amount of -     * bits. -     */ -    int granularity; - -    /* A number of progressively less coarse bitmaps (i.e. level 0 is the -     * coarsest).  Each bit in level N represents a word in level N+1 that -     * has a set bit, except the last level where each bit represents the -     * actual bitmap. -     * -     * Note that all bitmaps have the same number of levels.  Even a 1-bit -     * bitmap will still allocate HBITMAP_LEVELS arrays. -     */ -    unsigned long *levels[HBITMAP_LEVELS]; -}; - -#ifndef __NetBSD__ /* we have it in <strings.h> */ -static inline int popcountl(unsigned long l) -{ -    return BITS_PER_LONG == 32 ? ctpop32(l) : ctpop64(l); -} -#endif - -/* Advance hbi to the next nonzero word and return it.  hbi->pos - * is updated.  Returns zero if we reach the end of the bitmap. - */ -unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi) -{ -    size_t pos = hbi->pos; -    const HBitmap *hb = hbi->hb; -    unsigned i = HBITMAP_LEVELS - 1; - -    unsigned long cur; -    do { -        cur = hbi->cur[--i]; -        pos >>= BITS_PER_LEVEL; -    } while (cur == 0); - -    /* Check for end of iteration.  We always use fewer than BITS_PER_LONG -     * bits in the level 0 bitmap; thus we can repurpose the most significant -     * bit as a sentinel.  The sentinel is set in hbitmap_alloc and ensures -     * that the above loop ends even without an explicit check on i. -     */ - -    if (i == 0 && cur == (1UL << (BITS_PER_LONG - 1))) { -        return 0; -    } -    for (; i < HBITMAP_LEVELS - 1; i++) { -        /* Shift back pos to the left, matching the right shifts above. -         * The index of this word's least significant set bit provides -         * the low-order bits. -         */ -        assert(cur); -        pos = (pos << BITS_PER_LEVEL) + ctzl(cur); -        hbi->cur[i] = cur & (cur - 1); - -        /* Set up next level for iteration.  */ -        cur = hb->levels[i + 1][pos]; -    } - -    hbi->pos = pos; -    trace_hbitmap_iter_skip_words(hbi->hb, hbi, pos, cur); - -    assert(cur); -    return cur; -} - -void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first) -{ -    unsigned i, bit; -    uint64_t pos; - -    hbi->hb = hb; -    pos = first >> hb->granularity; -    assert(pos < hb->size); -    hbi->pos = pos >> BITS_PER_LEVEL; -    hbi->granularity = hb->granularity; - -    for (i = HBITMAP_LEVELS; i-- > 0; ) { -        bit = pos & (BITS_PER_LONG - 1); -        pos >>= BITS_PER_LEVEL; - -        /* Drop bits representing items before first.  */ -        hbi->cur[i] = hb->levels[i][pos] & ~((1UL << bit) - 1); - -        /* We have already added level i+1, so the lowest set bit has -         * been processed.  Clear it. -         */ -        if (i != HBITMAP_LEVELS - 1) { -            hbi->cur[i] &= ~(1UL << bit); -        } -    } -} - -bool hbitmap_empty(const HBitmap *hb) -{ -    return hb->count == 0; -} - -int hbitmap_granularity(const HBitmap *hb) -{ -    return hb->granularity; -} - -uint64_t hbitmap_count(const HBitmap *hb) -{ -    return hb->count << hb->granularity; -} - -/* Count the number of set bits between start and end, not accounting for - * the granularity.  Also an example of how to use hbitmap_iter_next_word. - */ -static uint64_t hb_count_between(HBitmap *hb, uint64_t start, uint64_t last) -{ -    HBitmapIter hbi; -    uint64_t count = 0; -    uint64_t end = last + 1; -    unsigned long cur; -    size_t pos; - -    hbitmap_iter_init(&hbi, hb, start << hb->granularity); -    for (;;) { -        pos = hbitmap_iter_next_word(&hbi, &cur); -        if (pos >= (end >> BITS_PER_LEVEL)) { -            break; -        } -        count += popcountl(cur); -    } - -    if (pos == (end >> BITS_PER_LEVEL)) { -        /* Drop bits representing the END-th and subsequent items.  */ -        int bit = end & (BITS_PER_LONG - 1); -        cur &= (1UL << bit) - 1; -        count += popcountl(cur); -    } - -    return count; -} - -/* Setting starts at the last layer and propagates up if an element - * changes from zero to non-zero. - */ -static inline bool hb_set_elem(unsigned long *elem, uint64_t start, uint64_t last) -{ -    unsigned long mask; -    bool changed; - -    assert((last >> BITS_PER_LEVEL) == (start >> BITS_PER_LEVEL)); -    assert(start <= last); - -    mask = 2UL << (last & (BITS_PER_LONG - 1)); -    mask -= 1UL << (start & (BITS_PER_LONG - 1)); -    changed = (*elem == 0); -    *elem |= mask; -    return changed; -} - -/* The recursive workhorse (the depth is limited to HBITMAP_LEVELS)... */ -static void hb_set_between(HBitmap *hb, int level, uint64_t start, uint64_t last) -{ -    size_t pos = start >> BITS_PER_LEVEL; -    size_t lastpos = last >> BITS_PER_LEVEL; -    bool changed = false; -    size_t i; - -    i = pos; -    if (i < lastpos) { -        uint64_t next = (start | (BITS_PER_LONG - 1)) + 1; -        changed |= hb_set_elem(&hb->levels[level][i], start, next - 1); -        for (;;) { -            start = next; -            next += BITS_PER_LONG; -            if (++i == lastpos) { -                break; -            } -            changed |= (hb->levels[level][i] == 0); -            hb->levels[level][i] = ~0UL; -        } -    } -    changed |= hb_set_elem(&hb->levels[level][i], start, last); - -    /* If there was any change in this layer, we may have to update -     * the one above. -     */ -    if (level > 0 && changed) { -        hb_set_between(hb, level - 1, pos, lastpos); -    } -} - -void hbitmap_set(HBitmap *hb, uint64_t start, uint64_t count) -{ -    /* Compute range in the last layer.  */ -    uint64_t last = start + count - 1; - -    trace_hbitmap_set(hb, start, count, -                      start >> hb->granularity, last >> hb->granularity); - -    start >>= hb->granularity; -    last >>= hb->granularity; -    count = last - start + 1; - -    hb->count += count - hb_count_between(hb, start, last); -    hb_set_between(hb, HBITMAP_LEVELS - 1, start, last); -} - -/* Resetting works the other way round: propagate up if the new - * value is zero. - */ -static inline bool hb_reset_elem(unsigned long *elem, uint64_t start, uint64_t last) -{ -    unsigned long mask; -    bool blanked; - -    assert((last >> BITS_PER_LEVEL) == (start >> BITS_PER_LEVEL)); -    assert(start <= last); - -    mask = 2UL << (last & (BITS_PER_LONG - 1)); -    mask -= 1UL << (start & (BITS_PER_LONG - 1)); -    blanked = *elem != 0 && ((*elem & ~mask) == 0); -    *elem &= ~mask; -    return blanked; -} - -/* The recursive workhorse (the depth is limited to HBITMAP_LEVELS)... */ -static void hb_reset_between(HBitmap *hb, int level, uint64_t start, uint64_t last) -{ -    size_t pos = start >> BITS_PER_LEVEL; -    size_t lastpos = last >> BITS_PER_LEVEL; -    bool changed = false; -    size_t i; - -    i = pos; -    if (i < lastpos) { -        uint64_t next = (start | (BITS_PER_LONG - 1)) + 1; - -        /* Here we need a more complex test than when setting bits.  Even if -         * something was changed, we must not blank bits in the upper level -         * unless the lower-level word became entirely zero.  So, remove pos -         * from the upper-level range if bits remain set. -         */ -        if (hb_reset_elem(&hb->levels[level][i], start, next - 1)) { -            changed = true; -        } else { -            pos++; -        } - -        for (;;) { -            start = next; -            next += BITS_PER_LONG; -            if (++i == lastpos) { -                break; -            } -            changed |= (hb->levels[level][i] != 0); -            hb->levels[level][i] = 0UL; -        } -    } - -    /* Same as above, this time for lastpos.  */ -    if (hb_reset_elem(&hb->levels[level][i], start, last)) { -        changed = true; -    } else { -        lastpos--; -    } - -    if (level > 0 && changed) { -        hb_reset_between(hb, level - 1, pos, lastpos); -    } -} - -void hbitmap_reset(HBitmap *hb, uint64_t start, uint64_t count) -{ -    /* Compute range in the last layer.  */ -    uint64_t last = start + count - 1; - -    trace_hbitmap_reset(hb, start, count, -                        start >> hb->granularity, last >> hb->granularity); - -    start >>= hb->granularity; -    last >>= hb->granularity; - -    hb->count -= hb_count_between(hb, start, last); -    hb_reset_between(hb, HBITMAP_LEVELS - 1, start, last); -} - -bool hbitmap_get(const HBitmap *hb, uint64_t item) -{ -    /* Compute position and bit in the last layer.  */ -    uint64_t pos = item >> hb->granularity; -    unsigned long bit = 1UL << (pos & (BITS_PER_LONG - 1)); - -    return (hb->levels[HBITMAP_LEVELS - 1][pos >> BITS_PER_LEVEL] & bit) != 0; -} - -void hbitmap_free(HBitmap *hb) -{ -    unsigned i; -    for (i = HBITMAP_LEVELS; i-- > 0; ) { -        g_free(hb->levels[i]); -    } -    g_free(hb); -} - -HBitmap *hbitmap_alloc(uint64_t size, int granularity) -{ -    HBitmap *hb = g_malloc0(sizeof (struct HBitmap)); -    unsigned i; - -    assert(granularity >= 0 && granularity < 64); -    size = (size + (1ULL << granularity) - 1) >> granularity; -    assert(size <= ((uint64_t)1 << HBITMAP_LOG_MAX_SIZE)); - -    hb->size = size; -    hb->granularity = granularity; -    for (i = HBITMAP_LEVELS; i-- > 0; ) { -        size = MAX((size + BITS_PER_LONG - 1) >> BITS_PER_LEVEL, 1); -        hb->levels[i] = g_malloc0(size * sizeof(unsigned long)); -    } - -    /* We necessarily have free bits in level 0 due to the definition -     * of HBITMAP_LEVELS, so use one for a sentinel.  This speeds up -     * hbitmap_iter_skip_words. -     */ -    assert(size == 1); -    hb->levels[0][0] |= 1UL << (BITS_PER_LONG - 1); -    return hb; -} diff --git a/contrib/qemu/util/hexdump.c b/contrib/qemu/util/hexdump.c deleted file mode 100644 index 969b3406c07..00000000000 --- a/contrib/qemu/util/hexdump.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Helper to hexdump a buffer - * - * Copyright (c) 2013 Red Hat, Inc. - * Copyright (c) 2013 Gerd Hoffmann <kraxel@redhat.com> - * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com> - * Copyright (c) 2013 Xilinx, Inc - * - * This work is licensed under the terms of the GNU GPL, version 2.  See - * the COPYING file in the top-level directory. - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. - */ - -#include "qemu-common.h" - -void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size) -{ -    unsigned int b; - -    for (b = 0; b < size; b++) { -        if ((b % 16) == 0) { -            fprintf(fp, "%s: %04x:", prefix, b); -        } -        if ((b % 4) == 0) { -            fprintf(fp, " "); -        } -        fprintf(fp, " %02x", (unsigned char)buf[b]); -        if ((b % 16) == 15) { -            fprintf(fp, "\n"); -        } -    } -    if ((b % 16) != 0) { -        fprintf(fp, "\n"); -    } -} diff --git a/contrib/qemu/util/iov.c b/contrib/qemu/util/iov.c deleted file mode 100644 index cc6e837c836..00000000000 --- a/contrib/qemu/util/iov.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Helpers for getting linearized buffers from iov / filling buffers into iovs - * - * Copyright IBM, Corp. 2007, 2008 - * Copyright (C) 2010 Red Hat, Inc. - * - * Author(s): - *  Anthony Liguori <aliguori@us.ibm.com> - *  Amit Shah <amit.shah@redhat.com> - *  Michael Tokarev <mjt@tls.msk.ru> - * - * This work is licensed under the terms of the GNU GPL, version 2.  See - * the COPYING file in the top-level directory. - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. - */ - -#include "qemu/iov.h" - -#ifdef _WIN32 -# include <windows.h> -# include <winsock2.h> -#else -# include <sys/types.h> -# include <sys/socket.h> -#endif - -size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt, -                    size_t offset, const void *buf, size_t bytes) -{ -    size_t done; -    unsigned int i; -    for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) { -        if (offset < iov[i].iov_len) { -            size_t len = MIN(iov[i].iov_len - offset, bytes - done); -            memcpy(iov[i].iov_base + offset, buf + done, len); -            done += len; -            offset = 0; -        } else { -            offset -= iov[i].iov_len; -        } -    } -    assert(offset == 0); -    return done; -} - -size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, -                  size_t offset, void *buf, size_t bytes) -{ -    size_t done; -    unsigned int i; -    for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) { -        if (offset < iov[i].iov_len) { -            size_t len = MIN(iov[i].iov_len - offset, bytes - done); -            memcpy(buf + done, iov[i].iov_base + offset, len); -            done += len; -            offset = 0; -        } else { -            offset -= iov[i].iov_len; -        } -    } -    assert(offset == 0); -    return done; -} - -size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt, -                  size_t offset, int fillc, size_t bytes) -{ -    size_t done; -    unsigned int i; -    for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) { -        if (offset < iov[i].iov_len) { -            size_t len = MIN(iov[i].iov_len - offset, bytes - done); -            memset(iov[i].iov_base + offset, fillc, len); -            done += len; -            offset = 0; -        } else { -            offset -= iov[i].iov_len; -        } -    } -    assert(offset == 0); -    return done; -} - -size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt) -{ -    size_t len; -    unsigned int i; - -    len = 0; -    for (i = 0; i < iov_cnt; i++) { -        len += iov[i].iov_len; -    } -    return len; -} - -/* helper function for iov_send_recv() */ -static ssize_t -do_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, bool do_send) -{ -#ifdef CONFIG_POSIX -    ssize_t ret; -    struct msghdr msg; -    memset(&msg, 0, sizeof(msg)); -    msg.msg_iov = iov; -    msg.msg_iovlen = iov_cnt; -    do { -        ret = do_send -            ? sendmsg(sockfd, &msg, 0) -            : recvmsg(sockfd, &msg, 0); -    } while (ret < 0 && errno == EINTR); -    return ret; -#else -    /* else send piece-by-piece */ -    /*XXX Note: windows has WSASend() and WSARecv() */ -    unsigned i = 0; -    ssize_t ret = 0; -    while (i < iov_cnt) { -        ssize_t r = do_send -            ? send(sockfd, iov[i].iov_base, iov[i].iov_len, 0) -            : recv(sockfd, iov[i].iov_base, iov[i].iov_len, 0); -        if (r > 0) { -            ret += r; -        } else if (!r) { -            break; -        } else if (errno == EINTR) { -            continue; -        } else { -            /* else it is some "other" error, -             * only return if there was no data processed. */ -            if (ret == 0) { -                ret = -1; -            } -            break; -        } -        i++; -    } -    return ret; -#endif -} - -ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, -                      size_t offset, size_t bytes, -                      bool do_send) -{ -    ssize_t total = 0; -    ssize_t ret; -    size_t orig_len, tail; -    unsigned niov; - -    while (bytes > 0) { -        /* Find the start position, skipping `offset' bytes: -         * first, skip all full-sized vector elements, */ -        for (niov = 0; niov < iov_cnt && offset >= iov[niov].iov_len; ++niov) { -            offset -= iov[niov].iov_len; -        } - -        /* niov == iov_cnt would only be valid if bytes == 0, which -         * we already ruled out in the loop condition.  */ -        assert(niov < iov_cnt); -        iov += niov; -        iov_cnt -= niov; - -        if (offset) { -            /* second, skip `offset' bytes from the (now) first element, -             * undo it on exit */ -            iov[0].iov_base += offset; -            iov[0].iov_len -= offset; -        } -        /* Find the end position skipping `bytes' bytes: */ -        /* first, skip all full-sized elements */ -        tail = bytes; -        for (niov = 0; niov < iov_cnt && iov[niov].iov_len <= tail; ++niov) { -            tail -= iov[niov].iov_len; -        } -        if (tail) { -            /* second, fixup the last element, and remember the original -             * length */ -            assert(niov < iov_cnt); -            assert(iov[niov].iov_len > tail); -            orig_len = iov[niov].iov_len; -            iov[niov++].iov_len = tail; -        } - -        ret = do_send_recv(sockfd, iov, niov, do_send); - -        /* Undo the changes above before checking for errors */ -        if (tail) { -            iov[niov-1].iov_len = orig_len; -        } -        if (offset) { -            iov[0].iov_base -= offset; -            iov[0].iov_len += offset; -        } - -        if (ret < 0) { -            assert(errno != EINTR); -            if (errno == EAGAIN && total > 0) { -                return total; -            } -            return -1; -        } - -        /* Prepare for the next iteration */ -        offset += ret; -        total += ret; -        bytes -= ret; -    } - -    return total; -} - - -void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt, -                 FILE *fp, const char *prefix, size_t limit) -{ -    int v; -    size_t size = 0; -    char *buf; - -    for (v = 0; v < iov_cnt; v++) { -        size += iov[v].iov_len; -    } -    size = size > limit ? limit : size; -    buf = g_malloc(size); -    iov_to_buf(iov, iov_cnt, 0, buf, size); -    qemu_hexdump(buf, fp, prefix, size); -    g_free(buf); -} - -unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt, -                 const struct iovec *iov, unsigned int iov_cnt, -                 size_t offset, size_t bytes) -{ -    size_t len; -    unsigned int i, j; -    for (i = 0, j = 0; i < iov_cnt && j < dst_iov_cnt && bytes; i++) { -        if (offset >= iov[i].iov_len) { -            offset -= iov[i].iov_len; -            continue; -        } -        len = MIN(bytes, iov[i].iov_len - offset); - -        dst_iov[j].iov_base = iov[i].iov_base + offset; -        dst_iov[j].iov_len = len; -        j++; -        bytes -= len; -        offset = 0; -    } -    assert(offset == 0); -    return j; -} - -/* io vectors */ - -void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint) -{ -    qiov->iov = g_malloc(alloc_hint * sizeof(struct iovec)); -    qiov->niov = 0; -    qiov->nalloc = alloc_hint; -    qiov->size = 0; -} - -void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov) -{ -    int i; - -    qiov->iov = iov; -    qiov->niov = niov; -    qiov->nalloc = -1; -    qiov->size = 0; -    for (i = 0; i < niov; i++) -        qiov->size += iov[i].iov_len; -} - -void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len) -{ -    assert(qiov->nalloc != -1); - -    if (qiov->niov == qiov->nalloc) { -        qiov->nalloc = 2 * qiov->nalloc + 1; -        qiov->iov = g_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec)); -    } -    qiov->iov[qiov->niov].iov_base = base; -    qiov->iov[qiov->niov].iov_len = len; -    qiov->size += len; -    ++qiov->niov; -} - -/* - * Concatenates (partial) iovecs from src_iov to the end of dst. - * It starts copying after skipping `soffset' bytes at the - * beginning of src and adds individual vectors from src to - * dst copies up to `sbytes' bytes total, or up to the end - * of src_iov if it comes first.  This way, it is okay to specify - * very large value for `sbytes' to indicate "up to the end - * of src". - * Only vector pointers are processed, not the actual data buffers. - */ -void qemu_iovec_concat_iov(QEMUIOVector *dst, -                           struct iovec *src_iov, unsigned int src_cnt, -                           size_t soffset, size_t sbytes) -{ -    int i; -    size_t done; - -    if (!sbytes) { -        return; -    } -    assert(dst->nalloc != -1); -    for (i = 0, done = 0; done < sbytes && i < src_cnt; i++) { -        if (soffset < src_iov[i].iov_len) { -            size_t len = MIN(src_iov[i].iov_len - soffset, sbytes - done); -            qemu_iovec_add(dst, src_iov[i].iov_base + soffset, len); -            done += len; -            soffset = 0; -        } else { -            soffset -= src_iov[i].iov_len; -        } -    } -    assert(soffset == 0); /* offset beyond end of src */ -} - -/* - * Concatenates (partial) iovecs from src to the end of dst. - * It starts copying after skipping `soffset' bytes at the - * beginning of src and adds individual vectors from src to - * dst copies up to `sbytes' bytes total, or up to the end - * of src if it comes first.  This way, it is okay to specify - * very large value for `sbytes' to indicate "up to the end - * of src". - * Only vector pointers are processed, not the actual data buffers. - */ -void qemu_iovec_concat(QEMUIOVector *dst, -                       QEMUIOVector *src, size_t soffset, size_t sbytes) -{ -    qemu_iovec_concat_iov(dst, src->iov, src->niov, soffset, sbytes); -} - -void qemu_iovec_destroy(QEMUIOVector *qiov) -{ -    assert(qiov->nalloc != -1); - -    qemu_iovec_reset(qiov); -    g_free(qiov->iov); -    qiov->nalloc = 0; -    qiov->iov = NULL; -} - -void qemu_iovec_reset(QEMUIOVector *qiov) -{ -    assert(qiov->nalloc != -1); - -    qiov->niov = 0; -    qiov->size = 0; -} - -size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset, -                         void *buf, size_t bytes) -{ -    return iov_to_buf(qiov->iov, qiov->niov, offset, buf, bytes); -} - -size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset, -                           const void *buf, size_t bytes) -{ -    return iov_from_buf(qiov->iov, qiov->niov, offset, buf, bytes); -} - -size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, -                         int fillc, size_t bytes) -{ -    return iov_memset(qiov->iov, qiov->niov, offset, fillc, bytes); -} - -size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt, -                         size_t bytes) -{ -    size_t total = 0; -    struct iovec *cur; - -    for (cur = *iov; *iov_cnt > 0; cur++) { -        if (cur->iov_len > bytes) { -            cur->iov_base += bytes; -            cur->iov_len -= bytes; -            total += bytes; -            break; -        } - -        bytes -= cur->iov_len; -        total += cur->iov_len; -        *iov_cnt -= 1; -    } - -    *iov = cur; -    return total; -} - -size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt, -                        size_t bytes) -{ -    size_t total = 0; -    struct iovec *cur; - -    if (*iov_cnt == 0) { -        return 0; -    } - -    cur = iov + (*iov_cnt - 1); - -    while (*iov_cnt > 0) { -        if (cur->iov_len > bytes) { -            cur->iov_len -= bytes; -            total += bytes; -            break; -        } - -        bytes -= cur->iov_len; -        total += cur->iov_len; -        cur--; -        *iov_cnt -= 1; -    } - -    return total; -} diff --git a/contrib/qemu/util/module.c b/contrib/qemu/util/module.c deleted file mode 100644 index 7acc33d076a..00000000000 --- a/contrib/qemu/util/module.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * QEMU Module Infrastructure - * - * Copyright IBM, Corp. 2009 - * - * Authors: - *  Anthony Liguori   <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2.  See - * the COPYING file in the top-level directory. - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. - */ - -#include "qemu-common.h" -#include "qemu/queue.h" -#include "qemu/module.h" - -typedef struct ModuleEntry -{ -    void (*init)(void); -    QTAILQ_ENTRY(ModuleEntry) node; -} ModuleEntry; - -typedef QTAILQ_HEAD(, ModuleEntry) ModuleTypeList; - -static ModuleTypeList init_type_list[MODULE_INIT_MAX]; - -static void init_types(void) -{ -    static int inited; -    int i; - -    if (inited) { -        return; -    } - -    for (i = 0; i < MODULE_INIT_MAX; i++) { -        QTAILQ_INIT(&init_type_list[i]); -    } - -    inited = 1; -} - - -static ModuleTypeList *find_type(module_init_type type) -{ -    ModuleTypeList *l; - -    init_types(); - -    l = &init_type_list[type]; - -    return l; -} - -void register_module_init(void (*fn)(void), module_init_type type) -{ -    ModuleEntry *e; -    ModuleTypeList *l; - -    e = g_malloc0(sizeof(*e)); -    e->init = fn; - -    l = find_type(type); - -    QTAILQ_INSERT_TAIL(l, e, node); -} - -void module_call_init(module_init_type type) -{ -    ModuleTypeList *l; -    ModuleEntry *e; - -    l = find_type(type); - -    QTAILQ_FOREACH(e, l, node) { -        e->init(); -    } -} diff --git a/contrib/qemu/util/oslib-posix.c b/contrib/qemu/util/oslib-posix.c deleted file mode 100644 index 45f9ca5a156..00000000000 --- a/contrib/qemu/util/oslib-posix.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * os-posix-lib.c - * - * Copyright (c) 2003-2008 Fabrice Bellard - * Copyright (c) 2010 Red Hat, Inc. - * - * QEMU library functions on POSIX which are shared between QEMU and - * the QEMU tools. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* The following block of code temporarily renames the daemon() function so the -   compiler does not see the warning associated with it in stdlib.h on OSX */ -#ifdef __APPLE__ -#define daemon qemu_fake_daemon_function -#include <stdlib.h> -#undef daemon -extern int daemon(int, int); -#endif - -#if defined(__linux__) && (defined(__x86_64__) || defined(__arm__)) -   /* Use 2 MiB alignment so transparent hugepages can be used by KVM. -      Valgrind does not support alignments larger than 1 MiB, -      therefore we need special code which handles running on Valgrind. */ -#  define QEMU_VMALLOC_ALIGN (512 * 4096) -#elif defined(__linux__) && defined(__s390x__) -   /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */ -#  define QEMU_VMALLOC_ALIGN (256 * 4096) -#else -#  define QEMU_VMALLOC_ALIGN getpagesize() -#endif - -#include <glib/gprintf.h> - -#include "config-host.h" -#include "qemu-common.h" -#include "sysemu/sysemu.h" -#include "trace.h" -#include "qemu/sockets.h" -#include <sys/mman.h> - -#ifdef CONFIG_LINUX -#include <sys/syscall.h> -#endif - -int qemu_get_thread_id(void) -{ -#if defined(__linux__) -    return syscall(SYS_gettid); -#else -    return getpid(); -#endif -} - -int qemu_daemon(int nochdir, int noclose) -{ -    return daemon(nochdir, noclose); -} - -void *qemu_oom_check(void *ptr) -{ -    if (ptr == NULL) { -        fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno)); -        abort(); -    } -    return ptr; -} - -void *qemu_memalign(size_t alignment, size_t size) -{ -    void *ptr; -#if defined(_POSIX_C_SOURCE) && !defined(__sun__) || defined(__APPLE__) -    int ret; -    ret = posix_memalign(&ptr, alignment, size); -    if (ret != 0) { -        fprintf(stderr, "Failed to allocate %zu B: %s\n", -                size, strerror(ret)); -        abort(); -    } -#elif defined(GF_BSD_HOST_OS) -    ptr = qemu_oom_check(valloc(size)); -#else -    ptr = qemu_oom_check(memalign(alignment, size)); -#endif -    trace_qemu_memalign(alignment, size, ptr); -    return ptr; -} - -/* alloc shared memory pages */ -void *qemu_anon_ram_alloc(size_t size) -{ -    size_t align = QEMU_VMALLOC_ALIGN; -    size_t total = size + align - getpagesize(); -    void *ptr = mmap(0, total, PROT_READ | PROT_WRITE, -                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); -    size_t offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr; - -    if (ptr == MAP_FAILED) { -        fprintf(stderr, "Failed to allocate %zu B: %s\n", -                size, strerror(errno)); -        abort(); -    } - -    ptr += offset; -    total -= offset; - -    if (offset > 0) { -        munmap(ptr - offset, offset); -    } -    if (total > size) { -        munmap(ptr + size, total - size); -    } - -    trace_qemu_anon_ram_alloc(size, ptr); -    return ptr; -} - -void qemu_vfree(void *ptr) -{ -    trace_qemu_vfree(ptr); -    free(ptr); -} - -void qemu_anon_ram_free(void *ptr, size_t size) -{ -    trace_qemu_anon_ram_free(ptr, size); -    if (ptr) { -        munmap(ptr, size); -    } -} - -void qemu_set_block(int fd) -{ -    int f; -    f = fcntl(fd, F_GETFL); -    fcntl(fd, F_SETFL, f & ~O_NONBLOCK); -} - -void qemu_set_nonblock(int fd) -{ -    int f; -    f = fcntl(fd, F_GETFL); -    fcntl(fd, F_SETFL, f | O_NONBLOCK); -} - -void qemu_set_cloexec(int fd) -{ -    int f; -    f = fcntl(fd, F_GETFD); -    fcntl(fd, F_SETFD, f | FD_CLOEXEC); -} - -/* - * Creates a pipe with FD_CLOEXEC set on both file descriptors - */ -int qemu_pipe(int pipefd[2]) -{ -    int ret; - -#ifdef CONFIG_PIPE2 -#ifdef pipe2 -    ret = pipe2(pipefd, O_CLOEXEC); -    if (ret != -1 || errno != ENOSYS) { -        return ret; -    } -#endif -#endif -    ret = pipe(pipefd); -    if (ret == 0) { -        qemu_set_cloexec(pipefd[0]); -        qemu_set_cloexec(pipefd[1]); -    } - -    return ret; -} - -#ifndef UTIME_OMIT -#define UTIME_OMIT        ((1l << 30) - 2l) -#endif -#ifndef UTIME_NOW -#define UTIME_NOW      ((1l << 30) - 1l) -#endif - -int qemu_utimens(const char *path, const struct timespec *times) -{ -    struct timeval tv[2], tv_now; -    struct stat st; -    int i; -#if defined(CONFIG_UTIMENSAT) -#ifdef utimensat -    int ret; - -    ret = utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW); -    if (ret != -1 || errno != ENOSYS) { -        return ret; -    } -#endif -#endif -    /* Fallback: use utimes() instead of utimensat() */ - -    /* happy if special cases */ -    if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) { -        return 0; -    } -    if (times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW) { -        return utimes(path, NULL); -    } - -    /* prepare for hard cases */ -    if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) { -        gettimeofday(&tv_now, NULL); -    } -    if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) { -        stat(path, &st); -    } - -    for (i = 0; i < 2; i++) { -        if (times[i].tv_nsec == UTIME_NOW) { -            tv[i].tv_sec = tv_now.tv_sec; -            tv[i].tv_usec = tv_now.tv_usec; -        } else if (times[i].tv_nsec == UTIME_OMIT) { -            tv[i].tv_sec = (i == 0) ? st.st_atime : st.st_mtime; -            tv[i].tv_usec = 0; -        } else { -            tv[i].tv_sec = times[i].tv_sec; -            tv[i].tv_usec = times[i].tv_nsec / 1000; -        } -    } - -    return utimes(path, &tv[0]); -} - -char * -qemu_get_local_state_pathname(const char *relative_pathname) -{ -    return g_strdup_printf("%s/%s", CONFIG_QEMU_LOCALSTATEDIR, -                           relative_pathname); -} diff --git a/contrib/qemu/util/qemu-error.c b/contrib/qemu/util/qemu-error.c deleted file mode 100644 index fec02c60754..00000000000 --- a/contrib/qemu/util/qemu-error.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Error reporting - * - * Copyright (C) 2010 Red Hat Inc. - * - * Authors: - *  Markus Armbruster <armbru@redhat.com>, - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#include <stdio.h> -#include "monitor/monitor.h" - -/* - * Print to current monitor if we have one, else to stderr. - * TODO should return int, so callers can calculate width, but that - * requires surgery to monitor_vprintf().  Left for another day. - */ -void error_vprintf(const char *fmt, va_list ap) -{ -    if (cur_mon) { -        monitor_vprintf(cur_mon, fmt, ap); -    } else { -        vfprintf(stderr, fmt, ap); -    } -} - -/* - * Print to current monitor if we have one, else to stderr. - * TODO just like error_vprintf() - */ -void error_printf(const char *fmt, ...) -{ -    va_list ap; - -    va_start(ap, fmt); -    error_vprintf(fmt, ap); -    va_end(ap); -} - -void error_printf_unless_qmp(const char *fmt, ...) -{ -    va_list ap; - -    if (!monitor_cur_is_qmp()) { -        va_start(ap, fmt); -        error_vprintf(fmt, ap); -        va_end(ap); -    } -} - -static Location std_loc = { -    .kind = LOC_NONE -}; -static Location *cur_loc = &std_loc; - -/* - * Push location saved in LOC onto the location stack, return it. - * The top of that stack is the current location. - * Needs a matching loc_pop(). - */ -Location *loc_push_restore(Location *loc) -{ -    assert(!loc->prev); -    loc->prev = cur_loc; -    cur_loc = loc; -    return loc; -} - -/* - * Initialize *LOC to "nowhere", push it onto the location stack. - * The top of that stack is the current location. - * Needs a matching loc_pop(). - * Return LOC. - */ -Location *loc_push_none(Location *loc) -{ -    loc->kind = LOC_NONE; -    loc->prev = NULL; -    return loc_push_restore(loc); -} - -/* - * Pop the location stack. - * LOC must be the current location, i.e. the top of the stack. - */ -Location *loc_pop(Location *loc) -{ -    assert(cur_loc == loc && loc->prev); -    cur_loc = loc->prev; -    loc->prev = NULL; -    return loc; -} - -/* - * Save the current location in LOC, return LOC. - */ -Location *loc_save(Location *loc) -{ -    *loc = *cur_loc; -    loc->prev = NULL; -    return loc; -} - -/* - * Change the current location to the one saved in LOC. - */ -void loc_restore(Location *loc) -{ -    Location *prev = cur_loc->prev; -    assert(!loc->prev); -    *cur_loc = *loc; -    cur_loc->prev = prev; -} - -/* - * Change the current location to "nowhere in particular". - */ -void loc_set_none(void) -{ -    cur_loc->kind = LOC_NONE; -} - -/* - * Change the current location to argument ARGV[IDX..IDX+CNT-1]. - */ -void loc_set_cmdline(char **argv, int idx, int cnt) -{ -    cur_loc->kind = LOC_CMDLINE; -    cur_loc->num = cnt; -    cur_loc->ptr = argv + idx; -} - -/* - * Change the current location to file FNAME, line LNO. - */ -void loc_set_file(const char *fname, int lno) -{ -    assert (fname || cur_loc->kind == LOC_FILE); -    cur_loc->kind = LOC_FILE; -    cur_loc->num = lno; -    if (fname) { -        cur_loc->ptr = fname; -    } -} - -static const char *progname; - -/* - * Set the program name for error_print_loc(). - */ -void error_set_progname(const char *argv0) -{ -    const char *p = strrchr(argv0, '/'); -    progname = p ? p + 1 : argv0; -} - -const char *error_get_progname(void) -{ -    return progname; -} - -/* - * Print current location to current monitor if we have one, else to stderr. - */ -void error_print_loc(void) -{ -    const char *sep = ""; -    int i; -    const char *const *argp; - -    if (!cur_mon && progname) { -        fprintf(stderr, "%s:", progname); -        sep = " "; -    } -    switch (cur_loc->kind) { -    case LOC_CMDLINE: -        argp = cur_loc->ptr; -        for (i = 0; i < cur_loc->num; i++) { -            error_printf("%s%s", sep, argp[i]); -            sep = " "; -        } -        error_printf(": "); -        break; -    case LOC_FILE: -        error_printf("%s:", (const char *)cur_loc->ptr); -        if (cur_loc->num) { -            error_printf("%d:", cur_loc->num); -        } -        error_printf(" "); -        break; -    default: -        error_printf("%s", sep); -    } -} - -bool enable_timestamp_msg; -/* - * Print an error message to current monitor if we have one, else to stderr. - * Format arguments like sprintf().  The result should not contain - * newlines. - * Prepend the current location and append a newline. - * It's wrong to call this in a QMP monitor.  Use qerror_report() there. - */ -void error_report(const char *fmt, ...) -{ -    va_list ap; -    GTimeVal tv; -    gchar *timestr; - -    if (enable_timestamp_msg) { -        g_get_current_time(&tv); -        timestr = g_time_val_to_iso8601(&tv); -        error_printf("%s ", timestr); -        g_free(timestr); -    } - -    error_print_loc(); -    va_start(ap, fmt); -    error_vprintf(fmt, ap); -    va_end(ap); -    error_printf("\n"); -} diff --git a/contrib/qemu/util/qemu-option.c b/contrib/qemu/util/qemu-option.c deleted file mode 100644 index e0ef426daa0..00000000000 --- a/contrib/qemu/util/qemu-option.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * Commandline option parsing functions - * - * Copyright (c) 2003-2008 Fabrice Bellard - * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include <stdio.h> -#include <string.h> - -#include "qemu-common.h" -#include "qemu/error-report.h" -#include "qapi/qmp/types.h" -#include "qapi/error.h" -#include "qapi/qmp/qerror.h" -#include "qemu/option_int.h" - -/* - * Extracts the name of an option from the parameter string (p points at the - * first byte of the option name) - * - * The option name is delimited by delim (usually , or =) or the string end - * and is copied into buf. If the option name is longer than buf_size, it is - * truncated. buf is always zero terminated. - * - * The return value is the position of the delimiter/zero byte after the option - * name in p. - */ -const char *get_opt_name(char *buf, int buf_size, const char *p, char delim) -{ -    char *q; - -    q = buf; -    while (*p != '\0' && *p != delim) { -        if (q && (q - buf) < buf_size - 1) -            *q++ = *p; -        p++; -    } -    if (q) -        *q = '\0'; - -    return p; -} - -/* - * Extracts the value of an option from the parameter string p (p points at the - * first byte of the option value) - * - * This function is comparable to get_opt_name with the difference that the - * delimiter is fixed to be comma which starts a new option. To specify an - * option value that contains commas, double each comma. - */ -const char *get_opt_value(char *buf, int buf_size, const char *p) -{ -    char *q; - -    q = buf; -    while (*p != '\0') { -        if (*p == ',') { -            if (*(p + 1) != ',') -                break; -            p++; -        } -        if (q && (q - buf) < buf_size - 1) -            *q++ = *p; -        p++; -    } -    if (q) -        *q = '\0'; - -    return p; -} - -int get_next_param_value(char *buf, int buf_size, -                         const char *tag, const char **pstr) -{ -    const char *p; -    char option[128]; - -    p = *pstr; -    for(;;) { -        p = get_opt_name(option, sizeof(option), p, '='); -        if (*p != '=') -            break; -        p++; -        if (!strcmp(tag, option)) { -            *pstr = get_opt_value(buf, buf_size, p); -            if (**pstr == ',') { -                (*pstr)++; -            } -            return strlen(buf); -        } else { -            p = get_opt_value(NULL, 0, p); -        } -        if (*p != ',') -            break; -        p++; -    } -    return 0; -} - -int get_param_value(char *buf, int buf_size, -                    const char *tag, const char *str) -{ -    return get_next_param_value(buf, buf_size, tag, &str); -} - -/* - * Searches an option list for an option with the given name - */ -QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list, -    const char *name) -{ -    while (list && list->name) { -        if (!strcmp(list->name, name)) { -            return list; -        } -        list++; -    } - -    return NULL; -} - -static void parse_option_bool(const char *name, const char *value, bool *ret, -                              Error **errp) -{ -    if (value != NULL) { -        if (!strcmp(value, "on")) { -            *ret = 1; -        } else if (!strcmp(value, "off")) { -            *ret = 0; -        } else { -            error_set(errp,QERR_INVALID_PARAMETER_VALUE, name, "'on' or 'off'"); -        } -    } else { -        *ret = 1; -    } -} - -static void parse_option_number(const char *name, const char *value, -                                uint64_t *ret, Error **errp) -{ -    char *postfix; -    uint64_t number; - -    if (value != NULL) { -        number = strtoull(value, &postfix, 0); -        if (*postfix != '\0') { -            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number"); -            return; -        } -        *ret = number; -    } else { -        error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number"); -    } -} - -static void parse_option_size(const char *name, const char *value, -                              uint64_t *ret, Error **errp) -{ -    char *postfix; -    double sizef; - -    if (value != NULL) { -        sizef = strtod(value, &postfix); -        switch (*postfix) { -        case 'T': -            sizef *= 1024; -            /* fall through */ -        case 'G': -            sizef *= 1024; -            /* fall through */ -        case 'M': -            sizef *= 1024; -            /* fall through */ -        case 'K': -        case 'k': -            sizef *= 1024; -            /* fall through */ -        case 'b': -        case '\0': -            *ret = (uint64_t) sizef; -            break; -        default: -            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size"); -#if 0 /* conversion from qerror_report() to error_set() broke this: */ -            error_printf_unless_qmp("You may use k, M, G or T suffixes for " -                    "kilobytes, megabytes, gigabytes and terabytes.\n"); -#endif -            return; -        } -    } else { -        error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size"); -    } -} - -/* - * Sets the value of a parameter in a given option list. The parsing of the - * value depends on the type of option: - * - * OPT_FLAG (uses value.n): - *      If no value is given, the flag is set to 1. - *      Otherwise the value must be "on" (set to 1) or "off" (set to 0) - * - * OPT_STRING (uses value.s): - *      value is strdup()ed and assigned as option value - * - * OPT_SIZE (uses value.n): - *      The value is converted to an integer. Suffixes for kilobytes etc. are - *      allowed (powers of 1024). - * - * Returns 0 on succes, -1 in error cases - */ -int set_option_parameter(QEMUOptionParameter *list, const char *name, -    const char *value) -{ -    bool flag; -    Error *local_err = NULL; - -    // Find a matching parameter -    list = get_option_parameter(list, name); -    if (list == NULL) { -        fprintf(stderr, "Unknown option '%s'\n", name); -        return -1; -    } - -    // Process parameter -    switch (list->type) { -    case OPT_FLAG: -        parse_option_bool(name, value, &flag, &local_err); -        if (!error_is_set(&local_err)) { -            list->value.n = flag; -        } -        break; - -    case OPT_STRING: -        if (value != NULL) { -            list->value.s = g_strdup(value); -        } else { -            fprintf(stderr, "Option '%s' needs a parameter\n", name); -            return -1; -        } -        break; - -    case OPT_SIZE: -        parse_option_size(name, value, &list->value.n, &local_err); -        break; - -    default: -        fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name); -        return -1; -    } - -    if (error_is_set(&local_err)) { -        qerror_report_err(local_err); -        error_free(local_err); -        return -1; -    } - -    return 0; -} - -/* - * Sets the given parameter to an integer instead of a string. - * This function cannot be used to set string options. - * - * Returns 0 on success, -1 in error cases - */ -int set_option_parameter_int(QEMUOptionParameter *list, const char *name, -    uint64_t value) -{ -    // Find a matching parameter -    list = get_option_parameter(list, name); -    if (list == NULL) { -        fprintf(stderr, "Unknown option '%s'\n", name); -        return -1; -    } - -    // Process parameter -    switch (list->type) { -    case OPT_FLAG: -    case OPT_NUMBER: -    case OPT_SIZE: -        list->value.n = value; -        break; - -    default: -        return -1; -    } - -    return 0; -} - -/* - * Frees a option list. If it contains strings, the strings are freed as well. - */ -void free_option_parameters(QEMUOptionParameter *list) -{ -    QEMUOptionParameter *cur = list; - -    while (cur && cur->name) { -        if (cur->type == OPT_STRING) { -            g_free(cur->value.s); -        } -        cur++; -    } - -    g_free(list); -} - -/* - * Count valid options in list - */ -static size_t count_option_parameters(QEMUOptionParameter *list) -{ -    size_t num_options = 0; - -    while (list && list->name) { -        num_options++; -        list++; -    } - -    return num_options; -} - -/* - * Append an option list (list) to an option list (dest). - * - * If dest is NULL, a new copy of list is created. - * - * Returns a pointer to the first element of dest (or the newly allocated copy) - */ -QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest, -    QEMUOptionParameter *list) -{ -    size_t num_options, num_dest_options; - -    num_options = count_option_parameters(dest); -    num_dest_options = num_options; - -    num_options += count_option_parameters(list); - -    dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter)); -    dest[num_dest_options].name = NULL; - -    while (list && list->name) { -        if (get_option_parameter(dest, list->name) == NULL) { -            dest[num_dest_options++] = *list; -            dest[num_dest_options].name = NULL; -        } -        list++; -    } - -    return dest; -} - -/* - * Parses a parameter string (param) into an option list (dest). - * - * list is the template option list. If dest is NULL, a new copy of list is - * created. If list is NULL, this function fails. - * - * A parameter string consists of one or more parameters, separated by commas. - * Each parameter consists of its name and possibly of a value. In the latter - * case, the value is delimited by an = character. To specify a value which - * contains commas, double each comma so it won't be recognized as the end of - * the parameter. - * - * For more details of the parsing see above. - * - * Returns a pointer to the first element of dest (or the newly allocated copy) - * or NULL in error cases - */ -QEMUOptionParameter *parse_option_parameters(const char *param, -    QEMUOptionParameter *list, QEMUOptionParameter *dest) -{ -    QEMUOptionParameter *allocated = NULL; -    char name[256]; -    char value[256]; -    char *param_delim, *value_delim; -    char next_delim; - -    if (list == NULL) { -        return NULL; -    } - -    if (dest == NULL) { -        dest = allocated = append_option_parameters(NULL, list); -    } - -    while (*param) { - -        // Find parameter name and value in the string -        param_delim = strchr(param, ','); -        value_delim = strchr(param, '='); - -        if (value_delim && (value_delim < param_delim || !param_delim)) { -            next_delim = '='; -        } else { -            next_delim = ','; -            value_delim = NULL; -        } - -        param = get_opt_name(name, sizeof(name), param, next_delim); -        if (value_delim) { -            param = get_opt_value(value, sizeof(value), param + 1); -        } -        if (*param != '\0') { -            param++; -        } - -        // Set the parameter -        if (set_option_parameter(dest, name, value_delim ? value : NULL)) { -            goto fail; -        } -    } - -    return dest; - -fail: -    // Only free the list if it was newly allocated -    free_option_parameters(allocated); -    return NULL; -} - -/* - * Prints all options of a list that have a value to stdout - */ -void print_option_parameters(QEMUOptionParameter *list) -{ -    while (list && list->name) { -        switch (list->type) { -            case OPT_STRING: -                 if (list->value.s != NULL) { -                     printf("%s='%s' ", list->name, list->value.s); -                 } -                break; -            case OPT_FLAG: -                printf("%s=%s ", list->name, list->value.n ? "on" : "off"); -                break; -            case OPT_SIZE: -            case OPT_NUMBER: -                printf("%s=%" PRId64 " ", list->name, list->value.n); -                break; -            default: -                printf("%s=(unknown type) ", list->name); -                break; -        } -        list++; -    } -} - -/* - * Prints an overview of all available options - */ -void print_option_help(QEMUOptionParameter *list) -{ -    printf("Supported options:\n"); -    while (list && list->name) { -        printf("%-16s %s\n", list->name, -            list->help ? list->help : "No description available"); -        list++; -    } -} - -/* ------------------------------------------------------------------ */ - -static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name) -{ -    QemuOpt *opt; - -    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) { -        if (strcmp(opt->name, name) != 0) -            continue; -        return opt; -    } -    return NULL; -} - -const char *qemu_opt_get(QemuOpts *opts, const char *name) -{ -    QemuOpt *opt = qemu_opt_find(opts, name); -    return opt ? opt->str : NULL; -} - -bool qemu_opt_has_help_opt(QemuOpts *opts) -{ -    QemuOpt *opt; - -    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) { -        if (is_help_option(opt->name)) { -            return true; -        } -    } -    return false; -} - -bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval) -{ -    QemuOpt *opt = qemu_opt_find(opts, name); - -    if (opt == NULL) -        return defval; -    assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL); -    return opt->value.boolean; -} - -uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval) -{ -    QemuOpt *opt = qemu_opt_find(opts, name); - -    if (opt == NULL) -        return defval; -    assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER); -    return opt->value.uint; -} - -uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval) -{ -    QemuOpt *opt = qemu_opt_find(opts, name); - -    if (opt == NULL) -        return defval; -    assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE); -    return opt->value.uint; -} - -static void qemu_opt_parse(QemuOpt *opt, Error **errp) -{ -    if (opt->desc == NULL) -        return; - -    switch (opt->desc->type) { -    case QEMU_OPT_STRING: -        /* nothing */ -        return; -    case QEMU_OPT_BOOL: -        parse_option_bool(opt->name, opt->str, &opt->value.boolean, errp); -        break; -    case QEMU_OPT_NUMBER: -        parse_option_number(opt->name, opt->str, &opt->value.uint, errp); -        break; -    case QEMU_OPT_SIZE: -        parse_option_size(opt->name, opt->str, &opt->value.uint, errp); -        break; -    default: -        abort(); -    } -} - -static void qemu_opt_del(QemuOpt *opt) -{ -    QTAILQ_REMOVE(&opt->opts->head, opt, next); -    g_free((/* !const */ char*)opt->name); -    g_free((/* !const */ char*)opt->str); -    g_free(opt); -} - -static bool opts_accepts_any(const QemuOpts *opts) -{ -    return opts->list->desc[0].name == NULL; -} - -static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc, -                                            const char *name) -{ -    int i; - -    for (i = 0; desc[i].name != NULL; i++) { -        if (strcmp(desc[i].name, name) == 0) { -            return &desc[i]; -        } -    } - -    return NULL; -} - -static void opt_set(QemuOpts *opts, const char *name, const char *value, -                    bool prepend, Error **errp) -{ -    QemuOpt *opt; -    const QemuOptDesc *desc; -    Error *local_err = NULL; - -    desc = find_desc_by_name(opts->list->desc, name); -    if (!desc && !opts_accepts_any(opts)) { -        error_set(errp, QERR_INVALID_PARAMETER, name); -        return; -    } - -    opt = g_malloc0(sizeof(*opt)); -    opt->name = g_strdup(name); -    opt->opts = opts; -    if (prepend) { -        QTAILQ_INSERT_HEAD(&opts->head, opt, next); -    } else { -        QTAILQ_INSERT_TAIL(&opts->head, opt, next); -    } -    opt->desc = desc; -    opt->str = g_strdup(value); -    qemu_opt_parse(opt, &local_err); -    if (error_is_set(&local_err)) { -        error_propagate(errp, local_err); -        qemu_opt_del(opt); -    } -} - -int qemu_opt_set(QemuOpts *opts, const char *name, const char *value) -{ -    Error *local_err = NULL; - -    opt_set(opts, name, value, false, &local_err); -    if (error_is_set(&local_err)) { -        qerror_report_err(local_err); -        error_free(local_err); -        return -1; -    } - -    return 0; -} - -void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value, -                      Error **errp) -{ -    opt_set(opts, name, value, false, errp); -} - -int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val) -{ -    QemuOpt *opt; -    const QemuOptDesc *desc = opts->list->desc; - -    opt = g_malloc0(sizeof(*opt)); -    opt->desc = find_desc_by_name(desc, name); -    if (!opt->desc && !opts_accepts_any(opts)) { -        qerror_report(QERR_INVALID_PARAMETER, name); -        g_free(opt); -        return -1; -    } - -    opt->name = g_strdup(name); -    opt->opts = opts; -    opt->value.boolean = !!val; -    opt->str = g_strdup(val ? "on" : "off"); -    QTAILQ_INSERT_TAIL(&opts->head, opt, next); - -    return 0; -} - -int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val) -{ -    QemuOpt *opt; -    const QemuOptDesc *desc = opts->list->desc; - -    opt = g_malloc0(sizeof(*opt)); -    opt->desc = find_desc_by_name(desc, name); -    if (!opt->desc && !opts_accepts_any(opts)) { -        qerror_report(QERR_INVALID_PARAMETER, name); -        g_free(opt); -        return -1; -    } - -    opt->name = g_strdup(name); -    opt->opts = opts; -    opt->value.uint = val; -    opt->str = g_strdup_printf("%" PRId64, val); -    QTAILQ_INSERT_TAIL(&opts->head, opt, next); - -    return 0; -} - -int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, -                     int abort_on_failure) -{ -    QemuOpt *opt; -    int rc = 0; - -    QTAILQ_FOREACH(opt, &opts->head, next) { -        rc = func(opt->name, opt->str, opaque); -        if (abort_on_failure  &&  rc != 0) -            break; -    } -    return rc; -} - -QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id) -{ -    QemuOpts *opts; - -    QTAILQ_FOREACH(opts, &list->head, next) { -        if (!opts->id && !id) { -            return opts; -        } -        if (opts->id && id && !strcmp(opts->id, id)) { -            return opts; -        } -    } -    return NULL; -} - -static int id_wellformed(const char *id) -{ -    int i; - -    if (!qemu_isalpha(id[0])) { -        return 0; -    } -    for (i = 1; id[i]; i++) { -        if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) { -            return 0; -        } -    } -    return 1; -} - -QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, -                           int fail_if_exists, Error **errp) -{ -    QemuOpts *opts = NULL; - -    if (id) { -        if (!id_wellformed(id)) { -            error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier"); -#if 0 /* conversion from qerror_report() to error_set() broke this: */ -            error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n"); -#endif -            return NULL; -        } -        opts = qemu_opts_find(list, id); -        if (opts != NULL) { -            if (fail_if_exists && !list->merge_lists) { -                error_set(errp, QERR_DUPLICATE_ID, id, list->name); -                return NULL; -            } else { -                return opts; -            } -        } -    } else if (list->merge_lists) { -        opts = qemu_opts_find(list, NULL); -        if (opts) { -            return opts; -        } -    } -    opts = g_malloc0(sizeof(*opts)); -    opts->id = g_strdup(id); -    opts->list = list; -    loc_save(&opts->loc); -    QTAILQ_INIT(&opts->head); -    QTAILQ_INSERT_TAIL(&list->head, opts, next); -    return opts; -} - -QemuOpts *qemu_opts_create_nofail(QemuOptsList *list) -{ -    QemuOpts *opts; -    Error *errp = NULL; -    opts = qemu_opts_create(list, NULL, 0, &errp); -    assert_no_error(errp); -    return opts; -} - -void qemu_opts_reset(QemuOptsList *list) -{ -    QemuOpts *opts, *next_opts; - -    QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) { -        qemu_opts_del(opts); -    } -} - -void qemu_opts_loc_restore(QemuOpts *opts) -{ -    loc_restore(&opts->loc); -} - -int qemu_opts_set(QemuOptsList *list, const char *id, -                  const char *name, const char *value) -{ -    QemuOpts *opts; -    Error *local_err = NULL; - -    opts = qemu_opts_create(list, id, 1, &local_err); -    if (error_is_set(&local_err)) { -        qerror_report_err(local_err); -        error_free(local_err); -        return -1; -    } -    return qemu_opt_set(opts, name, value); -} - -const char *qemu_opts_id(QemuOpts *opts) -{ -    return opts->id; -} - -void qemu_opts_del(QemuOpts *opts) -{ -    QemuOpt *opt; - -    for (;;) { -        opt = QTAILQ_FIRST(&opts->head); -        if (opt == NULL) -            break; -        qemu_opt_del(opt); -    } -    QTAILQ_REMOVE(&opts->list->head, opts, next); -    g_free(opts->id); -    g_free(opts); -} - -int qemu_opts_print(QemuOpts *opts, void *dummy) -{ -    QemuOpt *opt; - -    fprintf(stderr, "%s: %s:", opts->list->name, -            opts->id ? opts->id : "<noid>"); -    QTAILQ_FOREACH(opt, &opts->head, next) { -        fprintf(stderr, " %s=\"%s\"", opt->name, opt->str); -    } -    fprintf(stderr, "\n"); -    return 0; -} - -static int opts_do_parse(QemuOpts *opts, const char *params, -                         const char *firstname, bool prepend) -{ -    char option[128], value[1024]; -    const char *p,*pe,*pc; -    Error *local_err = NULL; - -    for (p = params; *p != '\0'; p++) { -        pe = strchr(p, '='); -        pc = strchr(p, ','); -        if (!pe || (pc && pc < pe)) { -            /* found "foo,more" */ -            if (p == params && firstname) { -                /* implicitly named first option */ -                pstrcpy(option, sizeof(option), firstname); -                p = get_opt_value(value, sizeof(value), p); -            } else { -                /* option without value, probably a flag */ -                p = get_opt_name(option, sizeof(option), p, ','); -                if (strncmp(option, "no", 2) == 0) { -                    memmove(option, option+2, strlen(option+2)+1); -                    pstrcpy(value, sizeof(value), "off"); -                } else { -                    pstrcpy(value, sizeof(value), "on"); -                } -            } -        } else { -            /* found "foo=bar,more" */ -            p = get_opt_name(option, sizeof(option), p, '='); -            if (*p != '=') { -                break; -            } -            p++; -            p = get_opt_value(value, sizeof(value), p); -        } -        if (strcmp(option, "id") != 0) { -            /* store and parse */ -            opt_set(opts, option, value, prepend, &local_err); -            if (error_is_set(&local_err)) { -                qerror_report_err(local_err); -                error_free(local_err); -                return -1; -            } -        } -        if (*p != ',') { -            break; -        } -    } -    return 0; -} - -int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname) -{ -    return opts_do_parse(opts, params, firstname, false); -} - -static QemuOpts *opts_parse(QemuOptsList *list, const char *params, -                            int permit_abbrev, bool defaults) -{ -    const char *firstname; -    char value[1024], *id = NULL; -    const char *p; -    QemuOpts *opts; -    Error *local_err = NULL; - -    assert(!permit_abbrev || list->implied_opt_name); -    firstname = permit_abbrev ? list->implied_opt_name : NULL; - -    if (strncmp(params, "id=", 3) == 0) { -        get_opt_value(value, sizeof(value), params+3); -        id = value; -    } else if ((p = strstr(params, ",id=")) != NULL) { -        get_opt_value(value, sizeof(value), p+4); -        id = value; -    } -    opts = qemu_opts_create(list, id, !defaults, &local_err); -    if (opts == NULL) { -        if (error_is_set(&local_err)) { -            qerror_report_err(local_err); -            error_free(local_err); -        } -        return NULL; -    } - -    if (opts_do_parse(opts, params, firstname, defaults) != 0) { -        qemu_opts_del(opts); -        return NULL; -    } - -    return opts; -} - -QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, -                          int permit_abbrev) -{ -    return opts_parse(list, params, permit_abbrev, false); -} - -void qemu_opts_set_defaults(QemuOptsList *list, const char *params, -                            int permit_abbrev) -{ -    QemuOpts *opts; - -    opts = opts_parse(list, params, permit_abbrev, true); -    assert(opts); -} - -typedef struct OptsFromQDictState { -    QemuOpts *opts; -    Error **errp; -} OptsFromQDictState; - -static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque) -{ -    OptsFromQDictState *state = opaque; -    char buf[32]; -    const char *value; -    int n; - -    if (!strcmp(key, "id") || error_is_set(state->errp)) { -        return; -    } - -    switch (qobject_type(obj)) { -    case QTYPE_QSTRING: -        value = qstring_get_str(qobject_to_qstring(obj)); -        break; -    case QTYPE_QINT: -        n = snprintf(buf, sizeof(buf), "%" PRId64, -                     qint_get_int(qobject_to_qint(obj))); -        assert(n < sizeof(buf)); -        value = buf; -        break; -    case QTYPE_QFLOAT: -        n = snprintf(buf, sizeof(buf), "%.17g", -                     qfloat_get_double(qobject_to_qfloat(obj))); -        assert(n < sizeof(buf)); -        value = buf; -        break; -    case QTYPE_QBOOL: -        pstrcpy(buf, sizeof(buf), -                qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off"); -        value = buf; -        break; -    default: -        return; -    } - -    qemu_opt_set_err(state->opts, key, value, state->errp); -} - -/* - * Create QemuOpts from a QDict. - * Use value of key "id" as ID if it exists and is a QString. - * Only QStrings, QInts, QFloats and QBools are copied.  Entries with - * other types are silently ignored. - */ -QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict, -                               Error **errp) -{ -    OptsFromQDictState state; -    Error *local_err = NULL; -    QemuOpts *opts; - -    opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1, -                            &local_err); -    if (error_is_set(&local_err)) { -        error_propagate(errp, local_err); -        return NULL; -    } - -    assert(opts != NULL); - -    state.errp = &local_err; -    state.opts = opts; -    qdict_iter(qdict, qemu_opts_from_qdict_1, &state); -    if (error_is_set(&local_err)) { -        error_propagate(errp, local_err); -        qemu_opts_del(opts); -        return NULL; -    } - -    return opts; -} - -/* - * Adds all QDict entries to the QemuOpts that can be added and removes them - * from the QDict. When this function returns, the QDict contains only those - * entries that couldn't be added to the QemuOpts. - */ -void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp) -{ -    const QDictEntry *entry, *next; - -    entry = qdict_first(qdict); - -    while (entry != NULL) { -        Error *local_err = NULL; -        OptsFromQDictState state = { -            .errp = &local_err, -            .opts = opts, -        }; - -        next = qdict_next(qdict, entry); - -        if (find_desc_by_name(opts->list->desc, entry->key)) { -            qemu_opts_from_qdict_1(entry->key, entry->value, &state); -            if (error_is_set(&local_err)) { -                error_propagate(errp, local_err); -                return; -            } else { -                qdict_del(qdict, entry->key); -            } -        } - -        entry = next; -    } -} - -/* - * Convert from QemuOpts to QDict. - * The QDict values are of type QString. - * TODO We'll want to use types appropriate for opt->desc->type, but - * this is enough for now. - */ -QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict) -{ -    QemuOpt *opt; -    QObject *val; - -    if (!qdict) { -        qdict = qdict_new(); -    } -    if (opts->id) { -        qdict_put(qdict, "id", qstring_from_str(opts->id)); -    } -    QTAILQ_FOREACH(opt, &opts->head, next) { -        val = QOBJECT(qstring_from_str(opt->str)); -        qdict_put_obj(qdict, opt->name, val); -    } -    return qdict; -} - -/* Validate parsed opts against descriptions where no - * descriptions were provided in the QemuOptsList. - */ -void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp) -{ -    QemuOpt *opt; -    Error *local_err = NULL; - -    assert(opts_accepts_any(opts)); - -    QTAILQ_FOREACH(opt, &opts->head, next) { -        opt->desc = find_desc_by_name(desc, opt->name); -        if (!opt->desc) { -            error_set(errp, QERR_INVALID_PARAMETER, opt->name); -            return; -        } - -        qemu_opt_parse(opt, &local_err); -        if (error_is_set(&local_err)) { -            error_propagate(errp, local_err); -            return; -        } -    } -} - -int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, -                      int abort_on_failure) -{ -    Location loc; -    QemuOpts *opts; -    int rc = 0; - -    loc_push_none(&loc); -    QTAILQ_FOREACH(opts, &list->head, next) { -        loc_restore(&opts->loc); -        rc |= func(opts, opaque); -        if (abort_on_failure  &&  rc != 0) -            break; -    } -    loc_pop(&loc); -    return rc; -} diff --git a/contrib/qemu/util/qemu-thread-posix.c b/contrib/qemu/util/qemu-thread-posix.c deleted file mode 100644 index 4489abf1d85..00000000000 --- a/contrib/qemu/util/qemu-thread-posix.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Wrappers around mutex/cond/thread functions - * - * Copyright Red Hat, Inc. 2009 - * - * Author: - *  Marcelo Tosatti <mtosatti@redhat.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <time.h> -#include <signal.h> -#include <stdint.h> -#include <string.h> -#include <limits.h> -#include <unistd.h> -#include <sys/time.h> -#include "qemu/thread.h" - -static void error_exit(int err, const char *msg) -{ -    fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err)); -    abort(); -} - -void qemu_mutex_init(QemuMutex *mutex) -{ -    int err; -    pthread_mutexattr_t mutexattr; - -    pthread_mutexattr_init(&mutexattr); -    pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK); -    err = pthread_mutex_init(&mutex->lock, &mutexattr); -    pthread_mutexattr_destroy(&mutexattr); -    if (err) -        error_exit(err, __func__); -} - -void qemu_mutex_destroy(QemuMutex *mutex) -{ -    int err; - -    err = pthread_mutex_destroy(&mutex->lock); -    if (err) -        error_exit(err, __func__); -} - -void qemu_mutex_lock(QemuMutex *mutex) -{ -    int err; - -    err = pthread_mutex_lock(&mutex->lock); -    if (err) -        error_exit(err, __func__); -} - -int qemu_mutex_trylock(QemuMutex *mutex) -{ -    return pthread_mutex_trylock(&mutex->lock); -} - -void qemu_mutex_unlock(QemuMutex *mutex) -{ -    int err; - -    err = pthread_mutex_unlock(&mutex->lock); -    if (err) -        error_exit(err, __func__); -} - -void qemu_cond_init(QemuCond *cond) -{ -    int err; - -    err = pthread_cond_init(&cond->cond, NULL); -    if (err) -        error_exit(err, __func__); -} - -void qemu_cond_destroy(QemuCond *cond) -{ -    int err; - -    err = pthread_cond_destroy(&cond->cond); -    if (err) -        error_exit(err, __func__); -} - -void qemu_cond_signal(QemuCond *cond) -{ -    int err; - -    err = pthread_cond_signal(&cond->cond); -    if (err) -        error_exit(err, __func__); -} - -void qemu_cond_broadcast(QemuCond *cond) -{ -    int err; - -    err = pthread_cond_broadcast(&cond->cond); -    if (err) -        error_exit(err, __func__); -} - -void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) -{ -    int err; - -    err = pthread_cond_wait(&cond->cond, &mutex->lock); -    if (err) -        error_exit(err, __func__); -} - -void qemu_sem_init(QemuSemaphore *sem, int init) -{ -    int rc; - -#if defined(__APPLE__) || defined(__NetBSD__) -    rc = pthread_mutex_init(&sem->lock, NULL); -    if (rc != 0) { -        error_exit(rc, __func__); -    } -    rc = pthread_cond_init(&sem->cond, NULL); -    if (rc != 0) { -        error_exit(rc, __func__); -    } -    if (init < 0) { -        error_exit(EINVAL, __func__); -    } -    sem->count = init; -#else -    rc = sem_init(&sem->sem, 0, init); -    if (rc < 0) { -        error_exit(errno, __func__); -    } -#endif -} - -void qemu_sem_destroy(QemuSemaphore *sem) -{ -    int rc; - -#if defined(__APPLE__) || defined(__NetBSD__) -    rc = pthread_cond_destroy(&sem->cond); -    if (rc < 0) { -        error_exit(rc, __func__); -    } -    rc = pthread_mutex_destroy(&sem->lock); -    if (rc < 0) { -        error_exit(rc, __func__); -    } -#else -    rc = sem_destroy(&sem->sem); -    if (rc < 0) { -        error_exit(errno, __func__); -    } -#endif -} - -void qemu_sem_post(QemuSemaphore *sem) -{ -    int rc; - -#if defined(__APPLE__) || defined(__NetBSD__) -    pthread_mutex_lock(&sem->lock); -    if (sem->count == INT_MAX) { -        rc = EINVAL; -    } else if (sem->count++ < 0) { -        rc = pthread_cond_signal(&sem->cond); -    } else { -        rc = 0; -    } -    pthread_mutex_unlock(&sem->lock); -    if (rc != 0) { -        error_exit(rc, __func__); -    } -#else -    rc = sem_post(&sem->sem); -    if (rc < 0) { -        error_exit(errno, __func__); -    } -#endif -} - -static void compute_abs_deadline(struct timespec *ts, int ms) -{ -    struct timeval tv; -    gettimeofday(&tv, NULL); -    ts->tv_nsec = tv.tv_usec * 1000 + (ms % 1000) * 1000000; -    ts->tv_sec = tv.tv_sec + ms / 1000; -    if (ts->tv_nsec >= 1000000000) { -        ts->tv_sec++; -        ts->tv_nsec -= 1000000000; -    } -} - -int qemu_sem_timedwait(QemuSemaphore *sem, int ms) -{ -    int rc; -    struct timespec ts; - -#if defined(__APPLE__) || defined(__NetBSD__) -    compute_abs_deadline(&ts, ms); -    pthread_mutex_lock(&sem->lock); -    --sem->count; -    while (sem->count < 0) { -        rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts); -        if (rc == ETIMEDOUT) { -            ++sem->count; -            break; -        } -        if (rc != 0) { -            error_exit(rc, __func__); -        } -    } -    pthread_mutex_unlock(&sem->lock); -    return (rc == ETIMEDOUT ? -1 : 0); -#else -    if (ms <= 0) { -        /* This is cheaper than sem_timedwait.  */ -        do { -            rc = sem_trywait(&sem->sem); -        } while (rc == -1 && errno == EINTR); -        if (rc == -1 && errno == EAGAIN) { -            return -1; -        } -    } else { -        compute_abs_deadline(&ts, ms); -        do { -            rc = sem_timedwait(&sem->sem, &ts); -        } while (rc == -1 && errno == EINTR); -        if (rc == -1 && errno == ETIMEDOUT) { -            return -1; -        } -    } -    if (rc < 0) { -        error_exit(errno, __func__); -    } -    return 0; -#endif -} - -void qemu_sem_wait(QemuSemaphore *sem) -{ -#if defined(__APPLE__) || defined(__NetBSD__) -    pthread_mutex_lock(&sem->lock); -    --sem->count; -    while (sem->count < 0) { -        pthread_cond_wait(&sem->cond, &sem->lock); -    } -    pthread_mutex_unlock(&sem->lock); -#else -    int rc; - -    do { -        rc = sem_wait(&sem->sem); -    } while (rc == -1 && errno == EINTR); -    if (rc < 0) { -        error_exit(errno, __func__); -    } -#endif -} - -void qemu_thread_create(QemuThread *thread, -                       void *(*start_routine)(void*), -                       void *arg, int mode) -{ -    sigset_t set, oldset; -    int err; -    pthread_attr_t attr; - -    err = pthread_attr_init(&attr); -    if (err) { -        error_exit(err, __func__); -    } -    if (mode == QEMU_THREAD_DETACHED) { -        err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -        if (err) { -            error_exit(err, __func__); -        } -    } - -    /* Leave signal handling to the iothread.  */ -    sigfillset(&set); -    pthread_sigmask(SIG_SETMASK, &set, &oldset); -    err = pthread_create(&thread->thread, &attr, start_routine, arg); -    if (err) -        error_exit(err, __func__); - -    pthread_sigmask(SIG_SETMASK, &oldset, NULL); - -    pthread_attr_destroy(&attr); -} - -void qemu_thread_get_self(QemuThread *thread) -{ -    thread->thread = pthread_self(); -} - -bool qemu_thread_is_self(QemuThread *thread) -{ -   return pthread_equal(pthread_self(), thread->thread); -} - -void qemu_thread_exit(void *retval) -{ -    pthread_exit(retval); -} - -void *qemu_thread_join(QemuThread *thread) -{ -    int err; -    void *ret; - -    err = pthread_join(thread->thread, &ret); -    if (err) { -        error_exit(err, __func__); -    } -    return ret; -} diff --git a/contrib/qemu/util/unicode.c b/contrib/qemu/util/unicode.c deleted file mode 100644 index d1c86588505..00000000000 --- a/contrib/qemu/util/unicode.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Dealing with Unicode - * - * Copyright (C) 2013 Red Hat, Inc. - * - * Authors: - *  Markus Armbruster <armbru@redhat.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or - * later.  See the COPYING file in the top-level directory. - */ - -#include "qemu-common.h" - -/** - * mod_utf8_codepoint: - * @s: string encoded in modified UTF-8 - * @n: maximum number of bytes to read from @s, if less than 6 - * @end: set to end of sequence on return - * - * Convert the modified UTF-8 sequence at the start of @s.  Modified - * UTF-8 is exactly like UTF-8, except U+0000 is encoded as - * "\xC0\x80". - * - * If @n is zero or @s points to a zero byte, the sequence is invalid, - * and @end is set to @s. - * - * If @s points to an impossible byte (0xFE or 0xFF) or a continuation - * byte, the sequence is invalid, and @end is set to @s + 1 - * - * Else, the first byte determines how many continuation bytes are - * expected.  If there are fewer, the sequence is invalid, and @end is - * set to @s + 1 + actual number of continuation bytes.  Else, the - * sequence is well-formed, and @end is set to @s + 1 + expected - * number of continuation bytes. - * - * A well-formed sequence is valid unless it encodes a codepoint - * outside the Unicode range U+0000..U+10FFFF, one of Unicode's 66 - * noncharacters, a surrogate codepoint, or is overlong.  Except the - * overlong sequence "\xC0\x80" is valid. - * - * Conversion succeeds if and only if the sequence is valid. - * - * Returns: the Unicode codepoint on success, -1 on failure. - */ -int mod_utf8_codepoint(const char *s, size_t n, char **end) -{ -    static int min_cp[5] = { 0x80, 0x800, 0x10000, 0x200000, 0x4000000 }; -    const unsigned char *p; -    unsigned byte, mask, len, i; -    int cp; - -    if (n == 0 || *s == 0) { -        /* empty sequence */ -        *end = (char *)s; -        return -1; -    } - -    p = (const unsigned char *)s; -    byte = *p++; -    if (byte < 0x80) { -        cp = byte;              /* one byte sequence */ -    } else if (byte >= 0xFE) { -        cp = -1;                /* impossible bytes 0xFE, 0xFF */ -    } else if ((byte & 0x40) == 0) { -        cp = -1;                /* unexpected continuation byte */ -    } else { -        /* multi-byte sequence */ -        len = 0; -        for (mask = 0x80; byte & mask; mask >>= 1) { -            len++; -        } -        assert(len > 1 && len < 7); -        cp = byte & (mask - 1); -        for (i = 1; i < len; i++) { -            byte = i < n ? *p : 0; -            if ((byte & 0xC0) != 0x80) { -                cp = -1;        /* continuation byte missing */ -                goto out; -            } -            p++; -            cp <<= 6; -            cp |= byte & 0x3F; -        } -        if (cp > 0x10FFFF) { -            cp = -1;            /* beyond Unicode range */ -        } else if ((cp >= 0xFDD0 && cp <= 0xFDEF) -                   || (cp & 0xFFFE) == 0xFFFE) { -            cp = -1;            /* noncharacter */ -        } else if (cp >= 0xD800 && cp <= 0xDFFF) { -            cp = -1;            /* surrogate code point */ -        } else if (cp < min_cp[len - 2] && !(cp == 0 && len == 2)) { -            cp = -1;            /* overlong, not \xC0\x80 */ -        } -    } - -out: -    *end = (char *)p; -    return cp; -}  | 
