From 7cc07ab8daa01f100f36ab63382d491f2d278c64 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 21 Feb 2014 16:24:03 +0100 Subject: qemu-option: has_help_option() and is_valid_option_list() has_help_option() checks if any help option ('help' or '?') occurs anywhere in an option string, so that things like 'cluster_size=4k,help' are recognised. is_valid_option_list() ensures that the option list doesn't have options with leading commas or trailing unescaped commas. Signed-off-by: Kevin Wolf Reviewed-by: Jeff Cody Reviewed-by: Eric Blake --- util/qemu-option.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'util') diff --git a/util/qemu-option.c b/util/qemu-option.c index fd76cd2ada..9d898af443 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -450,6 +450,55 @@ fail: return NULL; } +bool has_help_option(const char *param) +{ + size_t buflen = strlen(param) + 1; + char *buf = g_malloc0(buflen); + const char *p = param; + bool result = false; + + while (*p) { + p = get_opt_value(buf, buflen, p); + if (*p) { + p++; + } + + if (is_help_option(buf)) { + result = true; + goto out; + } + } + +out: + free(buf); + return result; +} + +bool is_valid_option_list(const char *param) +{ + size_t buflen = strlen(param) + 1; + char *buf = g_malloc0(buflen); + const char *p = param; + bool result = true; + + while (*p) { + p = get_opt_value(buf, buflen, p); + if (*p && !*++p) { + result = false; + goto out; + } + + if (!*buf || *buf == ',') { + result = false; + goto out; + } + } + +out: + free(buf); + return result; +} + /* * Prints all options of a list that have a value to stdout */ -- cgit v1.2.1 From ae39c4b2015dd5ee35021d0f4212bb1304106524 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 21 Feb 2014 19:11:39 +0100 Subject: qemu-config: Sections must consist of keys In config_parse_qdict_section(), the QList returned by qdict_array_split() is assumed to only contain QDicts. Currently, this is true but it may (and will) change in the future. Therefore, check whether the assumption actually holds. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf --- util/qemu-config.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'util') diff --git a/util/qemu-config.c b/util/qemu-config.c index 797df71569..f6101012c0 100644 --- a/util/qemu-config.c +++ b/util/qemu-config.c @@ -413,6 +413,12 @@ static void config_parse_qdict_section(QDict *options, QemuOptsList *opts, QDict *section = qobject_to_qdict(qlist_entry_obj(list_entry)); char *opt_name; + if (!section) { + error_setg(errp, "[%s] section (index %u) does not consist of " + "keys", opts->name, i); + goto out; + } + opt_name = g_strdup_printf("%s.%u", opts->name, i++); subopts = qemu_opts_create(opts, opt_name, 1, &local_err); g_free(opt_name); -- cgit v1.2.1 From f70d7f7e4d05b7a7797815afdcb83f4375740838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Canet?= Date: Fri, 21 Feb 2014 22:21:13 +0100 Subject: blkverify: Extract qemu_iovec_clone() and qemu_iovec_compare() from blkverify. qemu_iovec_compare() will be used to compare IOs vectors in quorum blkverify mode. The patch extracts these functions in order to factorize the code. Signed-off-by: Benoit Canet Reviewed-by: Max Reitz Signed-off-by: Kevin Wolf --- util/iov.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'util') diff --git a/util/iov.c b/util/iov.c index bb46c04e4d..03934da74d 100644 --- a/util/iov.c +++ b/util/iov.c @@ -378,6 +378,112 @@ size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, return iov_memset(qiov->iov, qiov->niov, offset, fillc, bytes); } +/** + * Check that I/O vector contents are identical + * + * The IO vectors must have the same structure (same length of all parts). + * A typical usage is to compare vectors created with qemu_iovec_clone(). + * + * @a: I/O vector + * @b: I/O vector + * @ret: Offset to first mismatching byte or -1 if match + */ +ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b) +{ + int i; + ssize_t offset = 0; + + assert(a->niov == b->niov); + for (i = 0; i < a->niov; i++) { + size_t len = 0; + uint8_t *p = (uint8_t *)a->iov[i].iov_base; + uint8_t *q = (uint8_t *)b->iov[i].iov_base; + + assert(a->iov[i].iov_len == b->iov[i].iov_len); + while (len < a->iov[i].iov_len && *p++ == *q++) { + len++; + } + + offset += len; + + if (len != a->iov[i].iov_len) { + return offset; + } + } + return -1; +} + +typedef struct { + int src_index; + struct iovec *src_iov; + void *dest_base; +} IOVectorSortElem; + +static int sortelem_cmp_src_base(const void *a, const void *b) +{ + const IOVectorSortElem *elem_a = a; + const IOVectorSortElem *elem_b = b; + + /* Don't overflow */ + if (elem_a->src_iov->iov_base < elem_b->src_iov->iov_base) { + return -1; + } else if (elem_a->src_iov->iov_base > elem_b->src_iov->iov_base) { + return 1; + } else { + return 0; + } +} + +static int sortelem_cmp_src_index(const void *a, const void *b) +{ + const IOVectorSortElem *elem_a = a; + const IOVectorSortElem *elem_b = b; + + return elem_a->src_index - elem_b->src_index; +} + +/** + * Copy contents of I/O vector + * + * The relative relationships of overlapping iovecs are preserved. This is + * necessary to ensure identical semantics in the cloned I/O vector. + */ +void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void *buf) +{ + IOVectorSortElem sortelems[src->niov]; + void *last_end; + int i; + + /* Sort by source iovecs by base address */ + for (i = 0; i < src->niov; i++) { + sortelems[i].src_index = i; + sortelems[i].src_iov = &src->iov[i]; + } + qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_base); + + /* Allocate buffer space taking into account overlapping iovecs */ + last_end = NULL; + for (i = 0; i < src->niov; i++) { + struct iovec *cur = sortelems[i].src_iov; + ptrdiff_t rewind = 0; + + /* Detect overlap */ + if (last_end && last_end > cur->iov_base) { + rewind = last_end - cur->iov_base; + } + + sortelems[i].dest_base = buf - rewind; + buf += cur->iov_len - MIN(rewind, cur->iov_len); + last_end = MAX(cur->iov_base + cur->iov_len, last_end); + } + + /* Sort by source iovec index and build destination iovec */ + qsort(sortelems, src->niov, sizeof(sortelems[0]), sortelem_cmp_src_index); + for (i = 0; i < src->niov; i++) { + qemu_iovec_add(dest, sortelems[i].dest_base, src->iov[i].iov_len); + } +} + size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt, size_t bytes) { -- cgit v1.2.1