From ae3f88f60fb9f42bb3679311c2fbff8e1868ea47 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Tue, 20 May 2014 13:39:41 +0200 Subject: [PATCH 01/17] dump: fill in the flat header signature more pleasingly to the eye The "mh.signature" array field has size 16, and is zeroed by the preceding memset(). MAKEDUMPFILE_SIGNATURE expands to a string literal with string length 12 (size 13). There's no need to measure the length of MAKEDUMPFILE_SIGNATURE at runtime, nor for the extra zero-filling of "mh.signature" with strncpy(). Use memcpy() with MIN(sizeof, sizeof) for robustness (which is an integer constant expression, evaluable at compile time.) Approximately-suggested-by: Paolo Bonzini Signed-off-by: Laszlo Ersek Reviewed-by: Paolo Bonzini Signed-off-by: Luiz Capitulino --- dump.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dump.c b/dump.c index e56b7cfc25..ac4505ec80 100644 --- a/dump.c +++ b/dump.c @@ -716,8 +716,8 @@ static int write_start_flat_header(int fd) int ret = 0; memset(&mh, 0, sizeof(mh)); - strncpy(mh.signature, MAKEDUMPFILE_SIGNATURE, - strlen(MAKEDUMPFILE_SIGNATURE)); + memcpy(mh.signature, MAKEDUMPFILE_SIGNATURE, + MIN(sizeof mh.signature, sizeof MAKEDUMPFILE_SIGNATURE)); mh.type = cpu_to_be64(TYPE_FLAT_HEADER); mh.version = cpu_to_be64(VERSION_FLAT_HEADER); From 92ba1401e0f81ea170803045c1ae366bf5d9d87e Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Tue, 20 May 2014 13:39:42 +0200 Subject: [PATCH 02/17] dump: simplify write_start_flat_header() Currently, the function - defines and populates an auto variable of type MakedumpfileHeader - allocates and zeroes a buffer of size MAX_SIZE_MDF_HEADER (4096) - copies the former into the latter (covering an initial portion of the latter) Fill in the MakedumpfileHeader structure in its final place (the alignment is OK because the structure lives at the address returned by g_malloc0()). Approximately-suggested-by: Luiz Capitulino Signed-off-by: Laszlo Ersek Reviewed-by: Paolo Bonzini Signed-off-by: Luiz Capitulino --- dump.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/dump.c b/dump.c index ac4505ec80..6dec8d2cf1 100644 --- a/dump.c +++ b/dump.c @@ -711,27 +711,25 @@ static int create_vmcore(DumpState *s) static int write_start_flat_header(int fd) { - uint8_t *buf; - MakedumpfileHeader mh; + MakedumpfileHeader *mh; int ret = 0; - memset(&mh, 0, sizeof(mh)); - memcpy(mh.signature, MAKEDUMPFILE_SIGNATURE, - MIN(sizeof mh.signature, sizeof MAKEDUMPFILE_SIGNATURE)); + QEMU_BUILD_BUG_ON(sizeof *mh > MAX_SIZE_MDF_HEADER); + mh = g_malloc0(MAX_SIZE_MDF_HEADER); - mh.type = cpu_to_be64(TYPE_FLAT_HEADER); - mh.version = cpu_to_be64(VERSION_FLAT_HEADER); + memcpy(mh->signature, MAKEDUMPFILE_SIGNATURE, + MIN(sizeof mh->signature, sizeof MAKEDUMPFILE_SIGNATURE)); - buf = g_malloc0(MAX_SIZE_MDF_HEADER); - memcpy(buf, &mh, sizeof(mh)); + mh->type = cpu_to_be64(TYPE_FLAT_HEADER); + mh->version = cpu_to_be64(VERSION_FLAT_HEADER); size_t written_size; - written_size = qemu_write_full(fd, buf, MAX_SIZE_MDF_HEADER); + written_size = qemu_write_full(fd, mh, MAX_SIZE_MDF_HEADER); if (written_size != MAX_SIZE_MDF_HEADER) { ret = -1; } - g_free(buf); + g_free(mh); return ret; } From 22227f121bddb038a0335cf83a3c24f451e2e836 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Tue, 20 May 2014 13:39:43 +0200 Subject: [PATCH 03/17] dump: eliminate DumpState.page_shift ("guest's page shift") Just use TARGET_PAGE_BITS. "DumpState.page_shift" used to have type "uint32_t", while the replacement TARGET_PAGE_BITS has type "int". Since "DumpState.page_shift" was only used as bit shift counts in the paddr_to_pfn() and pfn_to_paddr() macros, this is safe. Suggested-by: Paolo Bonzini Signed-off-by: Laszlo Ersek Reviewed-by: Paolo Bonzini Signed-off-by: Luiz Capitulino --- dump.c | 10 ++++------ include/sysemu/dump.h | 8 ++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/dump.c b/dump.c index 6dec8d2cf1..cde14d9d75 100644 --- a/dump.c +++ b/dump.c @@ -91,7 +91,6 @@ typedef struct DumpState { size_t note_buf_offset; /* the writing place in note_buf */ uint32_t nr_cpus; /* number of guest's cpu */ size_t page_size; /* guest's page size */ - uint32_t page_shift; /* guest's page shift */ uint64_t max_mapnr; /* the biggest guest's phys-mem's number */ size_t len_dump_bitmap; /* the size of the place used to store dump_bitmap in vmcore */ @@ -1086,7 +1085,7 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr, *blockptr = block; assert(block->target_start % s->page_size == 0); assert(block->target_end % s->page_size == 0); - *pfnptr = paddr_to_pfn(block->target_start, s->page_shift); + *pfnptr = paddr_to_pfn(block->target_start); if (bufptr) { *bufptr = block->host_addr; } @@ -1094,7 +1093,7 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr, } *pfnptr = *pfnptr + 1; - addr = pfn_to_paddr(*pfnptr, s->page_shift); + addr = pfn_to_paddr(*pfnptr); if ((addr >= block->target_start) && (addr + s->page_size <= block->target_end)) { @@ -1108,7 +1107,7 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr, } assert(block->target_start % s->page_size == 0); assert(block->target_end % s->page_size == 0); - *pfnptr = paddr_to_pfn(block->target_start, s->page_shift); + *pfnptr = paddr_to_pfn(block->target_start); buf = block->host_addr; } @@ -1534,7 +1533,7 @@ static void get_max_mapnr(DumpState *s) GuestPhysBlock *last_block; last_block = QTAILQ_LAST(&s->guest_phys_blocks.head, GuestPhysBlockHead); - s->max_mapnr = paddr_to_pfn(last_block->target_end, s->page_shift); + s->max_mapnr = paddr_to_pfn(last_block->target_end); } static int dump_init(DumpState *s, int fd, bool has_format, @@ -1612,7 +1611,6 @@ static int dump_init(DumpState *s, int fd, bool has_format, s->nr_cpus = nr_cpus; s->page_size = TARGET_PAGE_SIZE; - s->page_shift = ffs(s->page_size) - 1; get_max_mapnr(s); diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index efab7a32f3..12af557b55 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -22,10 +22,10 @@ #define ARCH_PFN_OFFSET (0) -#define paddr_to_pfn(X, page_shift) \ - (((unsigned long long)(X) >> (page_shift)) - ARCH_PFN_OFFSET) -#define pfn_to_paddr(X, page_shift) \ - (((unsigned long long)(X) + ARCH_PFN_OFFSET) << (page_shift)) +#define paddr_to_pfn(X) \ + (((unsigned long long)(X) >> TARGET_PAGE_BITS) - ARCH_PFN_OFFSET) +#define pfn_to_paddr(X) \ + (((unsigned long long)(X) + ARCH_PFN_OFFSET) << TARGET_PAGE_BITS) /* * flag for compressed format From 2f859f80c2077e00237ea1dfae2523ebd8377f5f Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Tue, 20 May 2014 13:39:44 +0200 Subject: [PATCH 04/17] dump: eliminate DumpState.page_size ("guest's page size") Use TARGET_PAGE_SIZE and ~TARGET_PAGE_MASK instead. "DumpState.page_size" has type "size_t", whereas TARGET_PAGE_SIZE has type "int". TARGET_PAGE_MASK is of type "int" and has negative value. The patch affects the implicit type conversions as follows: - create_header32() and create_header64(): assigned to "block_size", which has type "uint32_t". No change. - get_next_page(): "block->target_start", "block->target_end" and "addr" have type "hwaddr" (uint64_t). Before the patch, - if "size_t" was "uint64_t", then no additional conversion was done as part of the usual arithmetic conversions, - If "size_t" was "uint32_t", then it was widened to uint64_t as part of the usual arithmetic conversions, for the remainder and addition operators. After the patch, - "~TARGET_PAGE_MASK" expands to ~~((1 << TARGET_PAGE_BITS) - 1). It has type "int" and positive value (only least significant bits set). That's converted (widened) to "uint64_t" for the bit-ands. No visible change. - The same holds for the (addr + TARGET_PAGE_SIZE) addition. - write_dump_pages(): - TARGET_PAGE_SIZE passed as argument to a bunch of functions that all have prototypes. No change. - When incrementing "offset_data" (of type "off_t"): given that we never build for ILP32_OFF32 (see "-D_FILE_OFFSET_BITS=64" in configure), "off_t" is always "int64_t", and we only need to consider: - ILP32_OFFBIG: "size_t" is "uint32_t". - before: int64_t += uint32_t. Page size converted to int64_t for the addition. - after: int64_t += int32_t. No change. - LP64_OFF64: "size_t" is "uint64_t". - before: int64_t += uint64_t. Offset converted to uint64_t for the addition, then the uint64_t result is converted to int64_t for storage. - after: int64_t += int32_t. Same as the ILP32_OFFBIG/after case. No visible change. - (size_out < s->page_size) comparisons, and (size_out = s->page_size) assignment: - before: "size_out" is of type "size_t", no implicit conversion for either operator. - after: TARGET_PAGE_SIZE (of type "int" and positive value) is converted to "size_t" (for the relop because the latter is one of "uint32_t" and "uint64_t"). No visible change. - dump_init(): - DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size): The innermost "DumpState.max_mapnr" field has type uint64_t, which propagates through all implicit conversions at hand: #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) regardless of the page size macro argument's type. In the outer macro replacement, the page size is converted from uint32_t and int32_t alike to uint64_t. - (tmp * s->page_size) multiplication: "tmp" has size "uint64_t"; the RHS is converted to that type from uint32_t and int32_t just the same if it's not uint64_t to begin with. Signed-off-by: Laszlo Ersek Reviewed-by: Paolo Bonzini Signed-off-by: Luiz Capitulino --- dump.c | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/dump.c b/dump.c index cde14d9d75..e0a606fbbc 100644 --- a/dump.c +++ b/dump.c @@ -90,7 +90,6 @@ typedef struct DumpState { uint8_t *note_buf; /* buffer for notes */ size_t note_buf_offset; /* the writing place in note_buf */ uint32_t nr_cpus; /* number of guest's cpu */ - size_t page_size; /* guest's page size */ uint64_t max_mapnr; /* the biggest guest's phys-mem's number */ size_t len_dump_bitmap; /* the size of the place used to store dump_bitmap in vmcore */ @@ -805,7 +804,7 @@ static int create_header32(DumpState *s) strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE)); dh->header_version = cpu_convert_to_target32(6, endian); - block_size = s->page_size; + block_size = TARGET_PAGE_SIZE; dh->block_size = cpu_convert_to_target32(block_size, endian); sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size; sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size); @@ -912,7 +911,7 @@ static int create_header64(DumpState *s) strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE)); dh->header_version = cpu_convert_to_target32(6, endian); - block_size = s->page_size; + block_size = TARGET_PAGE_SIZE; dh->block_size = cpu_convert_to_target32(block_size, endian); sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size; sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size); @@ -1083,8 +1082,8 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr, if (!block) { block = QTAILQ_FIRST(&s->guest_phys_blocks.head); *blockptr = block; - assert(block->target_start % s->page_size == 0); - assert(block->target_end % s->page_size == 0); + assert((block->target_start & ~TARGET_PAGE_MASK) == 0); + assert((block->target_end & ~TARGET_PAGE_MASK) == 0); *pfnptr = paddr_to_pfn(block->target_start); if (bufptr) { *bufptr = block->host_addr; @@ -1096,7 +1095,7 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr, addr = pfn_to_paddr(*pfnptr); if ((addr >= block->target_start) && - (addr + s->page_size <= block->target_end)) { + (addr + TARGET_PAGE_SIZE <= block->target_end)) { buf = block->host_addr + (addr - block->target_start); } else { /* the next page is in the next block */ @@ -1105,8 +1104,8 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr, if (!block) { return false; } - assert(block->target_start % s->page_size == 0); - assert(block->target_end % s->page_size == 0); + assert((block->target_start & ~TARGET_PAGE_MASK) == 0); + assert((block->target_end & ~TARGET_PAGE_MASK) == 0); *pfnptr = paddr_to_pfn(block->target_start); buf = block->host_addr; } @@ -1291,7 +1290,7 @@ static int write_dump_pages(DumpState *s) prepare_data_cache(&page_data, s, offset_data); /* prepare buffer to store compressed data */ - len_buf_out = get_len_buf_out(s->page_size, s->flag_compress); + len_buf_out = get_len_buf_out(TARGET_PAGE_SIZE, s->flag_compress); if (len_buf_out == 0) { dump_error(s, "dump: failed to get length of output buffer.\n"); goto out; @@ -1307,19 +1306,19 @@ static int write_dump_pages(DumpState *s) * init zero page's page_desc and page_data, because every zero page * uses the same page_data */ - pd_zero.size = cpu_convert_to_target32(s->page_size, endian); + pd_zero.size = cpu_convert_to_target32(TARGET_PAGE_SIZE, endian); pd_zero.flags = cpu_convert_to_target32(0, endian); pd_zero.offset = cpu_convert_to_target64(offset_data, endian); pd_zero.page_flags = cpu_convert_to_target64(0, endian); - buf = g_malloc0(s->page_size); - ret = write_cache(&page_data, buf, s->page_size, false); + buf = g_malloc0(TARGET_PAGE_SIZE); + ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false); g_free(buf); if (ret < 0) { dump_error(s, "dump: failed to write page data(zero page).\n"); goto out; } - offset_data += s->page_size; + offset_data += TARGET_PAGE_SIZE; /* * dump memory to vmcore page by page. zero page will all be resided in the @@ -1327,7 +1326,7 @@ static int write_dump_pages(DumpState *s) */ while (get_next_page(&block_iter, &pfn_iter, &buf, s)) { /* check zero page */ - if (is_zero_page(buf, s->page_size)) { + if (is_zero_page(buf, TARGET_PAGE_SIZE)) { ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor), false); if (ret < 0) { @@ -1348,8 +1347,9 @@ static int write_dump_pages(DumpState *s) */ size_out = len_buf_out; if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) && - (compress2(buf_out, (uLongf *)&size_out, buf, s->page_size, - Z_BEST_SPEED) == Z_OK) && (size_out < s->page_size)) { + (compress2(buf_out, (uLongf *)&size_out, buf, + TARGET_PAGE_SIZE, Z_BEST_SPEED) == Z_OK) && + (size_out < TARGET_PAGE_SIZE)) { pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_ZLIB, endian); pd.size = cpu_convert_to_target32(size_out, endian); @@ -1361,9 +1361,9 @@ static int write_dump_pages(DumpState *s) } #ifdef CONFIG_LZO } else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) && - (lzo1x_1_compress(buf, s->page_size, buf_out, + (lzo1x_1_compress(buf, TARGET_PAGE_SIZE, buf_out, (lzo_uint *)&size_out, wrkmem) == LZO_E_OK) && - (size_out < s->page_size)) { + (size_out < TARGET_PAGE_SIZE)) { pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_LZO, endian); pd.size = cpu_convert_to_target32(size_out, endian); @@ -1376,9 +1376,9 @@ static int write_dump_pages(DumpState *s) #endif #ifdef CONFIG_SNAPPY } else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) && - (snappy_compress((char *)buf, s->page_size, + (snappy_compress((char *)buf, TARGET_PAGE_SIZE, (char *)buf_out, &size_out) == SNAPPY_OK) && - (size_out < s->page_size)) { + (size_out < TARGET_PAGE_SIZE)) { pd.flags = cpu_convert_to_target32( DUMP_DH_COMPRESSED_SNAPPY, endian); pd.size = cpu_convert_to_target32(size_out, endian); @@ -1392,13 +1392,13 @@ static int write_dump_pages(DumpState *s) } else { /* * fall back to save in plaintext, size_out should be - * assigned to s->page_size + * assigned TARGET_PAGE_SIZE */ pd.flags = cpu_convert_to_target32(0, endian); - size_out = s->page_size; + size_out = TARGET_PAGE_SIZE; pd.size = cpu_convert_to_target32(size_out, endian); - ret = write_cache(&page_data, buf, s->page_size, false); + ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false); if (ret < 0) { dump_error(s, "dump: failed to write page data.\n"); goto out; @@ -1610,13 +1610,12 @@ static int dump_init(DumpState *s, int fd, bool has_format, } s->nr_cpus = nr_cpus; - s->page_size = TARGET_PAGE_SIZE; get_max_mapnr(s); uint64_t tmp; - tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size); - s->len_dump_bitmap = tmp * s->page_size; + tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), TARGET_PAGE_SIZE); + s->len_dump_bitmap = tmp * TARGET_PAGE_SIZE; /* init for kdump-compressed format */ if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) { From 24aeeace7a9f264688e9eda77b6c04db607cbdfd Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Tue, 20 May 2014 13:39:45 +0200 Subject: [PATCH 05/17] dump: select header bitness based on ELF class, not ELF architecture The specific ELF architecture (d_machine) carries Too Much Information (TM) for deciding between create_header32() and create_header64(), use "d_class" instead (ELFCLASS32 vs. ELFCLASS64). This change adapts write_dump_header() to write_elf_loads(), dump_begin() etc. that also rely on the ELF class of the target for bitness selection. Considering the current targets that support dumping, cpu_get_dump_info() works as follows: - target-s390x/arch_dump.c: (EM_S390, ELFCLASS64) only - target-ppc/arch_dump.c (EM_PPC64, ELFCLASS64) only - target-i386/arch_dump.c: sets (EM_X86_64, ELFCLASS64) vs. (EM_386, ELFCLASS32) keying off the same Long Mode Active flag. Hence no observable change. Approximately-suggested-by: Paolo Bonzini Signed-off-by: Laszlo Ersek Reviewed-by: Paolo Bonzini Signed-off-by: Luiz Capitulino --- dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dump.c b/dump.c index e0a606fbbc..7e0982bb5a 100644 --- a/dump.c +++ b/dump.c @@ -1000,7 +1000,7 @@ out: static int write_dump_header(DumpState *s) { - if (s->dump_info.d_machine == EM_386) { + if (s->dump_info.d_class == ELFCLASS32) { return create_header32(s); } else { return create_header64(s); From c998acb03df614ddf2f3e206582586f191d07fff Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Tue, 20 May 2014 13:42:22 +0200 Subject: [PATCH 06/17] dump: hoist lzo_init() from get_len_buf_out() to dump_init() qmp_dump_guest_memory() dump_init() lzo_init() <---------+ create_kdump_vmcore() | write_dump_pages() | get_len_buf_out() | lzo_init() ------+ This patch doesn't change the fact that lzo_init() is called for every LZO-compressed dump, but it makes get_len_buf_out() more focused (single responsibility). Suggested-by: Paolo Bonzini Signed-off-by: Laszlo Ersek Reviewed-by: Paolo Bonzini Signed-off-by: Luiz Capitulino --- dump.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dump.c b/dump.c index 7e0982bb5a..b87045e3d4 100644 --- a/dump.c +++ b/dump.c @@ -1231,13 +1231,6 @@ static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress) /* buf size for lzo */ #ifdef CONFIG_LZO - if (flag_compress & DUMP_DH_COMPRESSED_LZO) { - if (lzo_init() != LZO_E_OK) { - /* return 0 to indicate lzo is unavailable */ - return 0; - } - } - /* * LZO will expand incompressible data by a little amount. please check the * following URL to see the expansion calculation: @@ -1625,6 +1618,12 @@ static int dump_init(DumpState *s, int fd, bool has_format, break; case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO: +#ifdef CONFIG_LZO + if (lzo_init() != LZO_E_OK) { + error_setg(errp, "failed to initialize the LZO library"); + goto cleanup; + } +#endif s->flag_compress = DUMP_DH_COMPRESSED_LZO; break; From b87ef3518b2eeb9a57ee0d06d7e82a07ab5e4ffd Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Tue, 20 May 2014 13:42:53 +0200 Subject: [PATCH 07/17] dump: simplify get_len_buf_out() We can (and should) rely on the fact that s->flag_compress is exactly one of DUMP_DH_COMPRESSED_ZLIB, DUMP_DH_COMPRESSED_LZO, and DUMP_DH_COMPRESSED_SNAPPY. This is ensured by the QMP schema and dump_init() in combination. Suggested-by: Paolo Bonzini Signed-off-by: Laszlo Ersek Reviewed-by: Paolo Bonzini Signed-off-by: Luiz Capitulino --- dump.c | 44 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/dump.c b/dump.c index b87045e3d4..97d2c8dcef 100644 --- a/dump.c +++ b/dump.c @@ -1220,35 +1220,24 @@ static void free_data_cache(DataCache *data_cache) static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress) { - size_t len_buf_out_zlib, len_buf_out_lzo, len_buf_out_snappy; - size_t len_buf_out; + switch (flag_compress) { + case DUMP_DH_COMPRESSED_ZLIB: + return compressBound(page_size); - /* init buf_out */ - len_buf_out_zlib = len_buf_out_lzo = len_buf_out_snappy = 0; - - /* buf size for zlib */ - len_buf_out_zlib = compressBound(page_size); - - /* buf size for lzo */ -#ifdef CONFIG_LZO - /* - * LZO will expand incompressible data by a little amount. please check the - * following URL to see the expansion calculation: - * http://www.oberhumer.com/opensource/lzo/lzofaq.php - */ - len_buf_out_lzo = page_size + page_size / 16 + 64 + 3; -#endif + case DUMP_DH_COMPRESSED_LZO: + /* + * LZO will expand incompressible data by a little amount. Please check + * the following URL to see the expansion calculation: + * http://www.oberhumer.com/opensource/lzo/lzofaq.php + */ + return page_size + page_size / 16 + 64 + 3; #ifdef CONFIG_SNAPPY - /* buf size for snappy */ - len_buf_out_snappy = snappy_max_compressed_length(page_size); + case DUMP_DH_COMPRESSED_SNAPPY: + return snappy_max_compressed_length(page_size); #endif - - /* get the biggest that can store all kinds of compressed page */ - len_buf_out = MAX(len_buf_out_zlib, - MAX(len_buf_out_lzo, len_buf_out_snappy)); - - return len_buf_out; + } + return 0; } /* @@ -1284,10 +1273,7 @@ static int write_dump_pages(DumpState *s) /* prepare buffer to store compressed data */ len_buf_out = get_len_buf_out(TARGET_PAGE_SIZE, s->flag_compress); - if (len_buf_out == 0) { - dump_error(s, "dump: failed to get length of output buffer.\n"); - goto out; - } + assert(len_buf_out != 0); #ifdef CONFIG_LZO wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS); From 8e5977797d76e33856506c9a0c454ae9ab23034c Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Tue, 27 May 2014 23:39:30 +0100 Subject: [PATCH 08/17] monitor: Add ringbuf_write and ringbuf_read argument completion Export chr_is_ringbuf() function. Also remove left-over function prototypes while at it. Signed-off-by: Hani Benhabiles Signed-off-by: Luiz Capitulino --- hmp-commands.hx | 2 ++ hmp.h | 2 ++ include/sysemu/char.h | 3 +-- monitor.c | 39 +++++++++++++++++++++++++++++++++++++++ qemu-char.c | 2 +- 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 2e462c04aa..dcec5efab7 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -852,6 +852,7 @@ ETEXI .params = "device data", .help = "Write to a ring buffer character device", .mhandler.cmd = hmp_ringbuf_write, + .command_completion = ringbuf_write_completion, }, STEXI @@ -868,6 +869,7 @@ ETEXI .params = "device size", .help = "Read from a ring buffer character device", .mhandler.cmd = hmp_ringbuf_read, + .command_completion = ringbuf_write_completion, }, STEXI diff --git a/hmp.h b/hmp.h index aba59e95f0..212e5d2ae6 100644 --- a/hmp.h +++ b/hmp.h @@ -103,5 +103,7 @@ void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str); void set_link_completion(ReadLineState *rs, int nb_args, const char *str); void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str); void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str); +void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str); +void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str); #endif diff --git a/include/sysemu/char.h b/include/sysemu/char.h index b81a6ff185..7f5eeb38b0 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -286,9 +286,8 @@ void qemu_chr_add_handlers(CharDriverState *s, void qemu_chr_be_generic_open(CharDriverState *s); void qemu_chr_accept_input(CharDriverState *s); int qemu_chr_add_client(CharDriverState *s, int fd); -void qemu_chr_info_print(Monitor *mon, const QObject *ret_data); -void qemu_chr_info(Monitor *mon, QObject **ret_data); CharDriverState *qemu_chr_find(const char *name); +bool chr_is_ringbuf(const CharDriverState *chr); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); diff --git a/monitor.c b/monitor.c index 0565816910..e539e40b83 100644 --- a/monitor.c +++ b/monitor.c @@ -4412,6 +4412,45 @@ void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) qapi_free_ChardevInfoList(start); } +static void ringbuf_completion(ReadLineState *rs, const char *str) +{ + size_t len; + ChardevInfoList *list, *start; + + len = strlen(str); + readline_set_completion_index(rs, len); + + start = list = qmp_query_chardev(NULL); + while (list) { + ChardevInfo *chr_info = list->value; + + if (!strncmp(chr_info->label, str, len)) { + CharDriverState *chr = qemu_chr_find(chr_info->label); + if (chr && chr_is_ringbuf(chr)) { + readline_add_completion(rs, chr_info->label); + } + } + list = list->next; + } + qapi_free_ChardevInfoList(start); +} + +void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str) +{ + if (nb_args != 2) { + return; + } + ringbuf_completion(rs, str); +} + +void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str) +{ + if (nb_args != 2) { + return; + } + ringbuf_completion(rs, str); +} + void device_del_completion(ReadLineState *rs, int nb_args, const char *str) { size_t len; diff --git a/qemu-char.c b/qemu-char.c index 17b476edf0..4c04bbc24e 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2849,7 +2849,7 @@ fail: return NULL; } -static bool chr_is_ringbuf(const CharDriverState *chr) +bool chr_is_ringbuf(const CharDriverState *chr) { return chr->chr_write == ringbuf_chr_write; } From d0ece345cbe3a58a9952f0f539641009bfd7ddf9 Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Tue, 27 May 2014 23:39:31 +0100 Subject: [PATCH 09/17] monitor: Add watchdog_action argument completion Signed-off-by: Hani Benhabiles Signed-off-by: Luiz Capitulino --- hmp-commands.hx | 1 + hmp.h | 2 ++ monitor.c | 14 ++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index dcec5efab7..45e1763fbe 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1359,6 +1359,7 @@ ETEXI .params = "[reset|shutdown|poweroff|pause|debug|none]", .help = "change watchdog action", .mhandler.cmd = do_watchdog_action, + .command_completion = watchdog_action_completion, }, STEXI diff --git a/hmp.h b/hmp.h index 212e5d2ae6..a70804db46 100644 --- a/hmp.h +++ b/hmp.h @@ -105,5 +105,7 @@ void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str); void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str); void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str); void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str); +void watchdog_action_completion(ReadLineState *rs, int nb_args, + const char *str); #endif diff --git a/monitor.c b/monitor.c index e539e40b83..68d74cd351 100644 --- a/monitor.c +++ b/monitor.c @@ -4559,6 +4559,20 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) } } +void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str) +{ + if (nb_args != 2) { + return; + } + readline_set_completion_index(rs, strlen(str)); + add_completion_option(rs, str, "reset"); + add_completion_option(rs, str, "shutdown"); + add_completion_option(rs, str, "poweroff"); + add_completion_option(rs, str, "pause"); + add_completion_option(rs, str, "debug"); + add_completion_option(rs, str, "none"); +} + static void monitor_find_completion_by_table(Monitor *mon, const mon_cmd_t *cmd_table, char **args, From c68a0409b388c30c7f4ee8be44081c143f280279 Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Tue, 27 May 2014 23:39:32 +0100 Subject: [PATCH 10/17] monitor: Add migrate_set_capability completion Signed-off-by: Hani Benhabiles Signed-off-by: Luiz Capitulino --- hmp-commands.hx | 1 + hmp.h | 2 ++ monitor.c | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 45e1763fbe..919af6eaf1 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -975,6 +975,7 @@ ETEXI .params = "capability state", .help = "Enable/Disable the usage of a capability for migration", .mhandler.cmd = hmp_migrate_set_capability, + .command_completion = migrate_set_capability_completion, }, STEXI diff --git a/hmp.h b/hmp.h index a70804db46..0c814d07bd 100644 --- a/hmp.h +++ b/hmp.h @@ -107,5 +107,7 @@ void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str); void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str); void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str); +void migrate_set_capability_completion(ReadLineState *rs, int nb_args, + const char *str); #endif diff --git a/monitor.c b/monitor.c index 68d74cd351..709425ddb0 100644 --- a/monitor.c +++ b/monitor.c @@ -4573,6 +4573,27 @@ void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str) add_completion_option(rs, str, "none"); } +void migrate_set_capability_completion(ReadLineState *rs, int nb_args, + const char *str) +{ + size_t len; + + len = strlen(str); + readline_set_completion_index(rs, len); + if (nb_args == 2) { + int i; + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + const char *name = MigrationCapability_lookup[i]; + if (!strncmp(str, name, len)) { + readline_add_completion(rs, name); + } + } + } else if (nb_args == 3) { + add_completion_option(rs, str, "on"); + add_completion_option(rs, str, "off"); + } +} + static void monitor_find_completion_by_table(Monitor *mon, const mon_cmd_t *cmd_table, char **args, From 84007e81814bd1b523eb36b027ef8a84d7f00206 Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Tue, 27 May 2014 23:39:33 +0100 Subject: [PATCH 11/17] net: Export valid host network devices list Signed-off-by: Hani Benhabiles Reviewed-by: Stefan Hajnoczi Signed-off-by: Luiz Capitulino --- include/net/net.h | 1 + net/net.c | 34 ++++++++++++++++++++-------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/include/net/net.h b/include/net/net.h index 8166345a13..8b189da5ee 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -177,6 +177,7 @@ struct NICInfo { extern int nb_nics; extern NICInfo nd_table[MAX_NICS]; extern int default_net; +extern const char *host_net_devices[]; /* from net.c */ extern const char *legacy_tftp_prefix; diff --git a/net/net.c b/net/net.c index 0ff2e40f35..6344160403 100644 --- a/net/net.c +++ b/net/net.c @@ -49,6 +49,22 @@ static QTAILQ_HEAD(, NetClientState) net_clients; +const char *host_net_devices[] = { + "tap", + "socket", + "dump", +#ifdef CONFIG_NET_BRIDGE + "bridge", +#endif +#ifdef CONFIG_SLIRP + "user", +#endif +#ifdef CONFIG_VDE + "vde", +#endif + NULL, +}; + int default_net = 1; /***********************************************************/ @@ -897,21 +913,11 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error **errp) static int net_host_check_device(const char *device) { int i; - const char *valid_param_list[] = { "tap", "socket", "dump" -#ifdef CONFIG_NET_BRIDGE - , "bridge" -#endif -#ifdef CONFIG_SLIRP - ,"user" -#endif -#ifdef CONFIG_VDE - ,"vde" -#endif - }; - for (i = 0; i < ARRAY_SIZE(valid_param_list); i++) { - if (!strncmp(valid_param_list[i], device, - strlen(valid_param_list[i]))) + for (i = 0; host_net_devices[i]; i++) { + if (!strncmp(host_net_devices[i], device, + strlen(host_net_devices[i]))) { return 1; + } } return 0; From e3bb532cc795a394b74d08c9d5eb1d95bb0e1e86 Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Tue, 27 May 2014 23:39:34 +0100 Subject: [PATCH 12/17] monitor: Add host_net_add device argument completion Also fix the parameters documentation. Signed-off-by: Hani Benhabiles Reviewed-by: Stefan Hajnoczi Signed-off-by: Luiz Capitulino --- hmp-commands.hx | 3 ++- hmp.h | 1 + monitor.c | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 919af6eaf1..aab9cf59bb 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1209,9 +1209,10 @@ ETEXI { .name = "host_net_add", .args_type = "device:s,opts:s?", - .params = "tap|user|socket|vde|netmap|dump [options]", + .params = "tap|user|socket|vde|netmap|bridge|dump [options]", .help = "add host VLAN client", .mhandler.cmd = net_host_device_add, + .command_completion = host_net_add_completion, }, STEXI diff --git a/hmp.h b/hmp.h index 0c814d07bd..22ee836469 100644 --- a/hmp.h +++ b/hmp.h @@ -109,5 +109,6 @@ void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str); void migrate_set_capability_completion(ReadLineState *rs, int nb_args, const char *str); +void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str); #endif diff --git a/monitor.c b/monitor.c index 709425ddb0..0189bf879c 100644 --- a/monitor.c +++ b/monitor.c @@ -4594,6 +4594,22 @@ void migrate_set_capability_completion(ReadLineState *rs, int nb_args, } } +void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str) +{ + int i; + size_t len; + if (nb_args != 2) { + return; + } + len = strlen(str); + readline_set_completion_index(rs, len); + for (i = 0; host_net_devices[i]; i++) { + if (!strncmp(host_net_devices[i], str, len)) { + readline_add_completion(rs, host_net_devices[i]); + } + } +} + static void monitor_find_completion_by_table(Monitor *mon, const mon_cmd_t *cmd_table, char **args, From e70871d8b5c92e40cedd6fd0b7687c4f0b6ce3ff Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Tue, 27 May 2014 23:39:35 +0100 Subject: [PATCH 13/17] readline: Make completion strings always unique There is no need to clutter the user's choices with repeating the same value multiple times. Signed-off-by: Hani Benhabiles Signed-off-by: Luiz Capitulino --- util/readline.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/util/readline.c b/util/readline.c index 8baec55509..7214e8407c 100644 --- a/util/readline.c +++ b/util/readline.c @@ -263,6 +263,12 @@ static void readline_hist_add(ReadLineState *rs, const char *cmdline) void readline_add_completion(ReadLineState *rs, const char *str) { if (rs->nb_completions < READLINE_MAX_COMPLETIONS) { + int i; + for (i = 0; i < rs->nb_completions; i++) { + if (!strcmp(rs->completions[i], str)) { + return; + } + } rs->completions[rs->nb_completions++] = g_strdup(str); } } From ddd6b45ce25281a5894e2df0f7af014e83af19f7 Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Tue, 27 May 2014 23:39:36 +0100 Subject: [PATCH 14/17] monitor: Add host_net_remove arguments completion Relies on readline unique completion strings patch to make the added vlan/hub completion values unique, instead of using something like a hash table. Signed-off-by: Hani Benhabiles Reviewed-by: Stefan Hajnoczi Signed-off-by: Luiz Capitulino --- hmp-commands.hx | 1 + hmp.h | 2 ++ monitor.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index aab9cf59bb..f99da0efe4 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1227,6 +1227,7 @@ ETEXI .params = "vlan_id name", .help = "remove host VLAN client", .mhandler.cmd = net_host_device_remove, + .command_completion = host_net_remove_completion, }, STEXI diff --git a/hmp.h b/hmp.h index 22ee836469..a53ad51602 100644 --- a/hmp.h +++ b/hmp.h @@ -110,5 +110,7 @@ void watchdog_action_completion(ReadLineState *rs, int nb_args, void migrate_set_capability_completion(ReadLineState *rs, int nb_args, const char *str); void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str); +void host_net_remove_completion(ReadLineState *rs, int nb_args, + const char *str); #endif diff --git a/monitor.c b/monitor.c index 0189bf879c..d6c4f85909 100644 --- a/monitor.c +++ b/monitor.c @@ -4610,6 +4610,44 @@ void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str) } } +void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str) +{ + NetClientState *ncs[255]; + int count, i, len; + + len = strlen(str); + readline_set_completion_index(rs, len); + if (nb_args == 2) { + count = qemu_find_net_clients_except(NULL, ncs, + NET_CLIENT_OPTIONS_KIND_NONE, 255); + for (i = 0; i < count; i++) { + int id; + char name[16]; + + if (net_hub_id_for_client(ncs[i], &id)) { + continue; + } + snprintf(name, sizeof(name), "%d", id); + if (!strncmp(str, name, len)) { + readline_add_completion(rs, name); + } + } + return; + } else if (nb_args == 3) { + count = qemu_find_net_clients_except(NULL, ncs, + NET_CLIENT_OPTIONS_KIND_NIC, 255); + for (i = 0; i < count; i++) { + const char *name; + + name = ncs[i]->name; + if (!strncmp(str, name, len)) { + readline_add_completion(rs, name); + } + } + return; + } +} + static void monitor_find_completion_by_table(Monitor *mon, const mon_cmd_t *cmd_table, char **args, From b21631f3b5cdecd14114034cd9e4e7f63ed7fde1 Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Tue, 27 May 2014 23:39:37 +0100 Subject: [PATCH 15/17] monitor: Add delvm and loadvm argument completion Signed-off-by: Hani Benhabiles Signed-off-by: Luiz Capitulino --- hmp-commands.hx | 2 ++ hmp.h | 2 ++ monitor.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index f99da0efe4..5f1a677b85 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -335,6 +335,7 @@ ETEXI .params = "tag|id", .help = "restore a VM snapshot from its tag or id", .mhandler.cmd = do_loadvm, + .command_completion = loadvm_completion, }, STEXI @@ -350,6 +351,7 @@ ETEXI .params = "tag|id", .help = "delete a VM snapshot from its tag or id", .mhandler.cmd = do_delvm, + .command_completion = delvm_completion, }, STEXI diff --git a/hmp.h b/hmp.h index a53ad51602..2d9b0a2b0b 100644 --- a/hmp.h +++ b/hmp.h @@ -112,5 +112,7 @@ void migrate_set_capability_completion(ReadLineState *rs, int nb_args, void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str); void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str); +void delvm_completion(ReadLineState *rs, int nb_args, const char *str); +void loadvm_completion(ReadLineState *rs, int nb_args, const char *str); #endif diff --git a/monitor.c b/monitor.c index d6c4f85909..ee9390f659 100644 --- a/monitor.c +++ b/monitor.c @@ -70,6 +70,7 @@ #include "qmp-commands.h" #include "hmp.h" #include "qemu/thread.h" +#include "block/qapi.h" /* for pic/irq_info */ #if defined(TARGET_SPARC) @@ -4648,6 +4649,53 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str) } } +static void vm_completion(ReadLineState *rs, const char *str) +{ + size_t len; + BlockDriverState *bs = NULL; + + len = strlen(str); + readline_set_completion_index(rs, len); + while ((bs = bdrv_next(bs))) { + SnapshotInfoList *snapshots, *snapshot; + + if (!bdrv_can_snapshot(bs)) { + continue; + } + if (bdrv_query_snapshot_info_list(bs, &snapshots, NULL)) { + continue; + } + snapshot = snapshots; + while (snapshot) { + char *completion = snapshot->value->name; + if (!strncmp(str, completion, len)) { + readline_add_completion(rs, completion); + } + completion = snapshot->value->id; + if (!strncmp(str, completion, len)) { + readline_add_completion(rs, completion); + } + snapshot = snapshot->next; + } + qapi_free_SnapshotInfoList(snapshots); + } + +} + +void delvm_completion(ReadLineState *rs, int nb_args, const char *str) +{ + if (nb_args == 2) { + vm_completion(rs, str); + } +} + +void loadvm_completion(ReadLineState *rs, int nb_args, const char *str) +{ + if (nb_args == 2) { + vm_completion(rs, str); + } +} + static void monitor_find_completion_by_table(Monitor *mon, const mon_cmd_t *cmd_table, char **args, From 075ccb6cd3f7abe648a3e708ed34cfced378647f Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Sun, 1 Jun 2014 12:53:35 +0100 Subject: [PATCH 16/17] readline: Clear screen on form feed. Signed-off-by: Hani Benhabiles Signed-off-by: Luiz Capitulino --- util/readline.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/util/readline.c b/util/readline.c index 7214e8407c..cc1302ac0a 100644 --- a/util/readline.c +++ b/util/readline.c @@ -351,6 +351,12 @@ static void readline_completion(ReadLineState *rs) } } +static void readline_clear_screen(ReadLineState *rs) +{ + rs->printf_func(rs->opaque, "\033[2J\033[1;1H"); + readline_show_prompt(rs); +} + /* return true if command handled */ void readline_handle_byte(ReadLineState *rs, int ch) { @@ -369,6 +375,9 @@ void readline_handle_byte(ReadLineState *rs, int ch) case 9: readline_completion(rs); break; + case 12: + readline_clear_screen(rs); + break; case 10: case 13: rs->cmd_buf[rs->cmd_buf_size] = '\0'; From a491af471bf8f1188b2665f54d109065d4591e45 Mon Sep 17 00:00:00 2001 From: Gonglei Date: Tue, 10 Jun 2014 17:20:24 +0800 Subject: [PATCH 17/17] json-parser: drop superfluous assignment for token variable Signed-off-by: ChenLiang Signed-off-by: Gonglei Reviewed-by: Eric Blake Reviewed-by: Paolo Bonzini Signed-off-by: Luiz Capitulino --- qobject/json-parser.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/qobject/json-parser.c b/qobject/json-parser.c index e46c26448e..4288267bd3 100644 --- a/qobject/json-parser.c +++ b/qobject/json-parser.c @@ -423,7 +423,6 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap) if (!token_is_operator(token, '{')) { goto out; } - token = NULL; dict = qdict_new(); @@ -449,7 +448,6 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap) parse_error(ctxt, token, "expected separator in dict"); goto out; } - token = NULL; if (parse_pair(ctxt, dict, ap) == -1) { goto out; @@ -461,10 +459,8 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap) goto out; } } - token = NULL; } else { - token = parser_context_pop_token(ctxt); - token = NULL; + (void)parser_context_pop_token(ctxt); } return QOBJECT(dict); @@ -487,10 +483,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap) } if (!token_is_operator(token, '[')) { - token = NULL; goto out; } - token = NULL; list = qlist_new(); @@ -523,8 +517,6 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap) goto out; } - token = NULL; - obj = parse_value(ctxt, ap); if (obj == NULL) { parse_error(ctxt, token, "expecting value"); @@ -539,11 +531,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap) goto out; } } - - token = NULL; } else { - token = parser_context_pop_token(ctxt); - token = NULL; + (void)parser_context_pop_token(ctxt); } return QOBJECT(list);