34b321
import qemu-kvm-1.5.3-126.el7
@@ -0,0 +1,129 @@
|
|
1
|
+
From 0ae4c882404b4590c34bb9b03a86f9389413fd1c Mon Sep 17 00:00:00 2001
|
2
|
+
From: Alex Williamson <alex.williamson@redhat.com>
|
3
|
+
Date: Wed, 7 Sep 2016 14:09:52 +0200
|
4
|
+
Subject: [PATCH 2/2] Add skip_dump flag to ignore memory region during dump
|
5
|
+
|
6
|
+
RH-Author: Alex Williamson <alex.williamson@redhat.com>
|
7
|
+
Message-id: <20160907140817.21968.47551.stgit@gimli.home>
|
8
|
+
Patchwork-id: 72264
|
9
|
+
O-Subject: [RHEL7.3 qemu-kvm PATCH v2] Add skip_dump flag to ignore memory region during dump
|
10
|
+
Bugzilla: 1373088
|
11
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
12
|
+
RH-Acked-by: Auger Eric <eric.auger@redhat.com>
|
13
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
14
|
+
|
15
|
+
From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
|
16
|
+
|
17
|
+
Bugzilla: 1373088
|
18
|
+
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=11713365
|
19
|
+
Upstream: e4dc3f5909ab90520bc1a27b381c3017ff65ed68
|
20
|
+
|
21
|
+
The PCI MMIO might be disabled or the device in the reset state.
|
22
|
+
Make sure we do not dump these memory regions.
|
23
|
+
|
24
|
+
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
|
25
|
+
Acked-by: Alex Williamson <alex.williamson@redhat.com>
|
26
|
+
CC: Paolo Bonzini <pbonzini@redhat.com>
|
27
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
28
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
29
|
+
---
|
30
|
+
hw/misc/vfio.c | 1 +
|
31
|
+
include/exec/memory.h | 19 +++++++++++++++++++
|
32
|
+
memory.c | 10 ++++++++++
|
33
|
+
memory_mapping.c | 3 ++-
|
34
|
+
4 files changed, 32 insertions(+), 1 deletion(-)
|
35
|
+
|
36
|
+
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
|
37
|
+
index 36b9832..4fdc09a 100644
|
38
|
+
--- a/hw/misc/vfio.c
|
39
|
+
+++ b/hw/misc/vfio.c
|
40
|
+
@@ -2596,6 +2596,7 @@ static int vfio_mmap_bar(VFIOBAR *bar, MemoryRegion *mem, MemoryRegion *submem,
|
41
|
+
}
|
42
|
+
|
43
|
+
memory_region_init_ram_ptr(submem, name, size, *map);
|
44
|
+
+ memory_region_set_skip_dump(submem);
|
45
|
+
} else {
|
46
|
+
empty_region:
|
47
|
+
/* Create a zero sized sub-region to make cleanup easy. */
|
48
|
+
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
49
|
+
index 3bbe378..448d501 100644
|
50
|
+
--- a/include/exec/memory.h
|
51
|
+
+++ b/include/exec/memory.h
|
52
|
+
@@ -126,6 +126,7 @@ struct MemoryRegion {
|
53
|
+
bool terminates;
|
54
|
+
bool romd_mode;
|
55
|
+
bool ram;
|
56
|
+
+ bool skip_dump;
|
57
|
+
bool readonly; /* For RAM regions */
|
58
|
+
bool enabled;
|
59
|
+
bool rom_device;
|
60
|
+
@@ -353,6 +354,24 @@ uint64_t memory_region_size(MemoryRegion *mr);
|
61
|
+
bool memory_region_is_ram(MemoryRegion *mr);
|
62
|
+
|
63
|
+
/**
|
64
|
+
+ * memory_region_is_skip_dump: check whether a memory region should not be
|
65
|
+
+ * dumped
|
66
|
+
+ *
|
67
|
+
+ * Returns %true is a memory region should not be dumped(e.g. VFIO BAR MMAP).
|
68
|
+
+ *
|
69
|
+
+ * @mr: the memory region being queried
|
70
|
+
+ */
|
71
|
+
+bool memory_region_is_skip_dump(MemoryRegion *mr);
|
72
|
+
+
|
73
|
+
+/**
|
74
|
+
+ * memory_region_set_skip_dump: Set skip_dump flag, dump will ignore this memory
|
75
|
+
+ * region
|
76
|
+
+ *
|
77
|
+
+ * @mr: the memory region being queried
|
78
|
+
+ */
|
79
|
+
+void memory_region_set_skip_dump(MemoryRegion *mr);
|
80
|
+
+
|
81
|
+
+/**
|
82
|
+
* memory_region_is_romd: check whether a memory region is in ROMD mode
|
83
|
+
*
|
84
|
+
* Returns %true if a memory region is a ROM device and currently set to allow
|
85
|
+
diff --git a/memory.c b/memory.c
|
86
|
+
index a71d096..7bd6e87 100644
|
87
|
+
--- a/memory.c
|
88
|
+
+++ b/memory.c
|
89
|
+
@@ -957,6 +957,11 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
|
90
|
+
mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr);
|
91
|
+
}
|
92
|
+
|
93
|
+
+void memory_region_set_skip_dump(MemoryRegion *mr)
|
94
|
+
+{
|
95
|
+
+ mr->skip_dump = true;
|
96
|
+
+}
|
97
|
+
+
|
98
|
+
void memory_region_init_alias(MemoryRegion *mr,
|
99
|
+
const char *name,
|
100
|
+
MemoryRegion *orig,
|
101
|
+
@@ -1047,6 +1052,11 @@ bool memory_region_is_ram(MemoryRegion *mr)
|
102
|
+
return mr->ram;
|
103
|
+
}
|
104
|
+
|
105
|
+
+bool memory_region_is_skip_dump(MemoryRegion *mr)
|
106
|
+
+{
|
107
|
+
+ return mr->skip_dump;
|
108
|
+
+}
|
109
|
+
+
|
110
|
+
bool memory_region_is_logging(MemoryRegion *mr)
|
111
|
+
{
|
112
|
+
return mr->dirty_log_mask;
|
113
|
+
diff --git a/memory_mapping.c b/memory_mapping.c
|
114
|
+
index 65082d8..a4d59b7 100644
|
115
|
+
--- a/memory_mapping.c
|
116
|
+
+++ b/memory_mapping.c
|
117
|
+
@@ -203,7 +203,8 @@ static void guest_phys_blocks_region_add(MemoryListener *listener,
|
118
|
+
GuestPhysBlock *predecessor;
|
119
|
+
|
120
|
+
/* we only care about RAM */
|
121
|
+
- if (!memory_region_is_ram(section->mr)) {
|
122
|
+
+ if (!memory_region_is_ram(section->mr) ||
|
123
|
+
+ memory_region_is_skip_dump(section->mr)) {
|
124
|
+
return;
|
125
|
+
}
|
126
|
+
|
127
|
+
--
|
128
|
+
1.8.3.1
|
129
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
From fea907b6897cb3e644dcee3c537ce6e64d7850ed Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 11 Jul 2016 05:33:35 +0200
|
4
|
+
Subject: [PATCH 2/7] BlockLimits: introduce max_transfer_length
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1468215219-30793-3-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 71106
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 2/6] BlockLimits: introduce max_transfer_length
|
10
|
+
Bugzilla: 1318199
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Peter Lieven <pl@kamp.de>
|
16
|
+
|
17
|
+
Signed-off-by: Peter Lieven <pl@kamp.de>
|
18
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
19
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
20
|
+
(cherry picked from commit 2647fab57d5d5e38b36f8dbda367d688045e6a2d)
|
21
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
22
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
23
|
+
---
|
24
|
+
block.c | 4 ++++
|
25
|
+
include/block/block_int.h | 3 +++
|
26
|
+
2 files changed, 7 insertions(+)
|
27
|
+
|
28
|
+
diff --git a/block.c b/block.c
|
29
|
+
index ecb2b09..ae756aa 100644
|
30
|
+
--- a/block.c
|
31
|
+
+++ b/block.c
|
32
|
+
@@ -481,6 +481,7 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
|
33
|
+
return;
|
34
|
+
}
|
35
|
+
bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length;
|
36
|
+
+ bs->bl.max_transfer_length = bs->file->bl.max_transfer_length;
|
37
|
+
bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment;
|
38
|
+
} else {
|
39
|
+
bs->bl.opt_mem_alignment = 512;
|
40
|
+
@@ -495,6 +496,9 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
|
41
|
+
bs->bl.opt_transfer_length =
|
42
|
+
MAX(bs->bl.opt_transfer_length,
|
43
|
+
bs->backing_hd->bl.opt_transfer_length);
|
44
|
+
+ bs->bl.max_transfer_length =
|
45
|
+
+ MIN_NON_ZERO(bs->bl.max_transfer_length,
|
46
|
+
+ bs->backing_hd->bl.max_transfer_length);
|
47
|
+
bs->bl.opt_mem_alignment =
|
48
|
+
MAX(bs->bl.opt_mem_alignment,
|
49
|
+
bs->backing_hd->bl.opt_mem_alignment);
|
50
|
+
diff --git a/include/block/block_int.h b/include/block/block_int.h
|
51
|
+
index 3f86649..28c34d8 100644
|
52
|
+
--- a/include/block/block_int.h
|
53
|
+
+++ b/include/block/block_int.h
|
54
|
+
@@ -240,6 +240,9 @@ typedef struct BlockLimits {
|
55
|
+
/* optimal transfer length in sectors */
|
56
|
+
int opt_transfer_length;
|
57
|
+
|
58
|
+
+ /* maximal transfer length in sectors */
|
59
|
+
+ int max_transfer_length;
|
60
|
+
+
|
61
|
+
/* memory alignment so that no bounce buffer is needed */
|
62
|
+
size_t opt_mem_alignment;
|
63
|
+
} BlockLimits;
|
64
|
+
--
|
65
|
+
1.8.3.1
|
66
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
From 7530a2f3975b76711467226f8b279baf36d92e46 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Eduardo Habkost <ehabkost@redhat.com>
|
3
|
+
Date: Tue, 6 Sep 2016 21:45:05 +0200
|
4
|
+
Subject: [PATCH 1/2] Fix backport of "target-i386: add feature flags for
|
5
|
+
CPUID[EAX=0xd, ECX=1]"
|
6
|
+
|
7
|
+
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
|
8
|
+
Message-id: <1473198305-8442-1-git-send-email-ehabkost@redhat.com>
|
9
|
+
Patchwork-id: 72260
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH] Fix backport of "target-i386: add feature flags for CPUID[EAX=0xd, ECX=1]"
|
11
|
+
Bugzilla: 1371619
|
12
|
+
RH-Acked-by: Bandan Das <bsd@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
15
|
+
|
16
|
+
Upstream status: commit 0bb0b2d2fe7f645ddaf1f0ff40ac669c9feb4aa1
|
17
|
+
|
18
|
+
commit 5fcaf5176d7545518c76f3aa8ea7ce6fb063c62d (the backport of
|
19
|
+
upstream commit 0bb0b2d2fe7f645ddaf1f0ff40ac669c9feb4aa1) had a
|
20
|
+
serious bug: as the qemu-kvm-1.5.3 code doesn't have
|
21
|
+
FeatureWordInfo and loops for assigning cpu->features,
|
22
|
+
cpu->features[FEAT_XSAVE] was always zero, so that commit
|
23
|
+
basically cleared all XSAVE feature bits in all CPU models.
|
24
|
+
|
25
|
+
Fix it by handling FEAT_XSAVE everywhere it matters: in the
|
26
|
+
plus_features/minus_features handling, in the loading of CPU
|
27
|
+
model definition, and kvm_cpu_fill_host().
|
28
|
+
|
29
|
+
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
30
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
31
|
+
---
|
32
|
+
target-i386/cpu.c | 8 ++++++++
|
33
|
+
1 file changed, 8 insertions(+)
|
34
|
+
|
35
|
+
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
|
36
|
+
index 80106ba..1001c47 100644
|
37
|
+
--- a/target-i386/cpu.c
|
38
|
+
+++ b/target-i386/cpu.c
|
39
|
+
@@ -1201,6 +1201,8 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
|
40
|
+
} else {
|
41
|
+
x86_cpu_def->features[FEAT_7_0_EBX] = 0;
|
42
|
+
}
|
43
|
+
+ x86_cpu_def->features[FEAT_XSAVE] =
|
44
|
+
+ kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
|
45
|
+
|
46
|
+
x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
|
47
|
+
x86_cpu_def->features[FEAT_8000_0001_EDX] =
|
48
|
+
@@ -1281,6 +1283,9 @@ static int kvm_check_features_against_host(X86CPU *cpu)
|
49
|
+
{&env->features[FEAT_7_0_EBX],
|
50
|
+
&host_def.features[FEAT_7_0_EBX],
|
51
|
+
FEAT_7_0_EBX },
|
52
|
+
+ {&env->features[FEAT_XSAVE],
|
53
|
+
+ &host_def.features[FEAT_XSAVE],
|
54
|
+
+ FEAT_XSAVE },
|
55
|
+
{&env->features[FEAT_SVM],
|
56
|
+
&host_def.features[FEAT_SVM],
|
57
|
+
FEAT_SVM },
|
58
|
+
@@ -1819,6 +1824,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
59
|
+
env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
|
60
|
+
env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
|
61
|
+
env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
|
62
|
+
+ env->features[FEAT_XSAVE] |= plus_features[FEAT_XSAVE];
|
63
|
+
env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
|
64
|
+
env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
|
65
|
+
env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
|
66
|
+
@@ -1827,6 +1833,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
67
|
+
env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
|
68
|
+
env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
|
69
|
+
env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
|
70
|
+
+ env->features[FEAT_XSAVE] &= ~minus_features[FEAT_XSAVE];
|
71
|
+
|
72
|
+
out:
|
73
|
+
return;
|
74
|
+
@@ -1962,6 +1969,7 @@ static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
|
75
|
+
env->features[FEAT_SVM] = def->features[FEAT_SVM];
|
76
|
+
env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
|
77
|
+
env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
|
78
|
+
+ env->features[FEAT_XSAVE] = def->features[FEAT_XSAVE];
|
79
|
+
env->cpuid_xlevel2 = def->xlevel2;
|
80
|
+
|
81
|
+
object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
|
82
|
+
--
|
83
|
+
1.8.3.1
|
84
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
From 6b7e23d3e8ff46e638c9dcd769681b2e1b9da08e Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:35 +0100
|
4
|
+
Subject: [PATCH 16/27] Make qemu-io commands available in HMP
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-17-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68443
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 16/21] Make qemu-io commands available in HMP
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
It was decided to not make this command available in QMP in order to
|
18
|
+
make clear that this is not supposed to be a stable API and should be
|
19
|
+
used only for testing and debugging purposes.
|
20
|
+
|
21
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
22
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
23
|
+
(cherry picked from commit 587da2c39c9ace168f4d01fa446a54ae998a2553)
|
24
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
Makefile | 2 +-
|
28
|
+
Makefile.objs | 1 +
|
29
|
+
hmp-commands.hx | 16 ++++++++++++++++
|
30
|
+
hmp.c | 18 ++++++++++++++++++
|
31
|
+
hmp.h | 1 +
|
32
|
+
5 files changed, 37 insertions(+), 1 deletion(-)
|
33
|
+
|
34
|
+
diff --git a/Makefile b/Makefile
|
35
|
+
index f403057..76eb694 100644
|
36
|
+
--- a/Makefile
|
37
|
+
+++ b/Makefile
|
38
|
+
@@ -205,7 +205,7 @@ qemu-img.o: qemu-img-cmds.h
|
39
|
+
|
40
|
+
qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
|
41
|
+
qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
|
42
|
+
-qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o $(block-obj-y) libqemuutil.a libqemustub.a
|
43
|
+
+qemu-io$(EXESUF): qemu-io.o $(block-obj-y) libqemuutil.a libqemustub.a
|
44
|
+
|
45
|
+
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
|
46
|
+
|
47
|
+
diff --git a/Makefile.objs b/Makefile.objs
|
48
|
+
index f83a5b2..74f722e 100644
|
49
|
+
--- a/Makefile.objs
|
50
|
+
+++ b/Makefile.objs
|
51
|
+
@@ -13,6 +13,7 @@ block-obj-$(CONFIG_POSIX) += aio-posix.o
|
52
|
+
block-obj-$(CONFIG_WIN32) += aio-win32.o
|
53
|
+
block-obj-y += block/
|
54
|
+
block-obj-y += qapi-types.o qapi-visit.o
|
55
|
+
+block-obj-y += qemu-io-cmds.o
|
56
|
+
|
57
|
+
block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
|
58
|
+
block-obj-y += qemu-coroutine-sleep.o
|
59
|
+
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
60
|
+
index 58498f7..7e1855a 100644
|
61
|
+
--- a/hmp-commands.hx
|
62
|
+
+++ b/hmp-commands.hx
|
63
|
+
@@ -1592,6 +1592,22 @@ Removes the chardev @var{id}.
|
64
|
+
ETEXI
|
65
|
+
|
66
|
+
{
|
67
|
+
+ .name = "qemu-io",
|
68
|
+
+ .args_type = "device:B,command:s",
|
69
|
+
+ .params = "[device] \"[command]\"",
|
70
|
+
+ .help = "run a qemu-io command on a block device",
|
71
|
+
+ .mhandler.cmd = hmp_qemu_io,
|
72
|
+
+ },
|
73
|
+
+
|
74
|
+
+STEXI
|
75
|
+
+@item qemu-io @var{device} @var{command}
|
76
|
+
+@findex qemu-io
|
77
|
+
+
|
78
|
+
+Executes a qemu-io command on the given block device.
|
79
|
+
+
|
80
|
+
+ETEXI
|
81
|
+
+
|
82
|
+
+ {
|
83
|
+
.name = "info",
|
84
|
+
.args_type = "item:s?",
|
85
|
+
.params = "[subcommand]",
|
86
|
+
diff --git a/hmp.c b/hmp.c
|
87
|
+
index 1805926..e1d92f4 100644
|
88
|
+
--- a/hmp.c
|
89
|
+
+++ b/hmp.c
|
90
|
+
|
91
|
+
#include "qemu/sockets.h"
|
92
|
+
#include "monitor/monitor.h"
|
93
|
+
#include "ui/console.h"
|
94
|
+
+#include "qemu-io.h"
|
95
|
+
|
96
|
+
static void hmp_handle_error(Monitor *mon, Error **errp)
|
97
|
+
{
|
98
|
+
@@ -1448,3 +1449,20 @@ void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
|
99
|
+
qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
|
100
|
+
hmp_handle_error(mon, &local_err);
|
101
|
+
}
|
102
|
+
+
|
103
|
+
+void hmp_qemu_io(Monitor *mon, const QDict *qdict)
|
104
|
+
+{
|
105
|
+
+ BlockDriverState *bs;
|
106
|
+
+ const char* device = qdict_get_str(qdict, "device");
|
107
|
+
+ const char* command = qdict_get_str(qdict, "command");
|
108
|
+
+ Error *err = NULL;
|
109
|
+
+
|
110
|
+
+ bs = bdrv_find(device);
|
111
|
+
+ if (bs) {
|
112
|
+
+ qemuio_command(bs, command);
|
113
|
+
+ } else {
|
114
|
+
+ error_set(&err, QERR_DEVICE_NOT_FOUND, device);
|
115
|
+
+ }
|
116
|
+
+
|
117
|
+
+ hmp_handle_error(mon, &err);
|
118
|
+
+}
|
119
|
+
diff --git a/hmp.h b/hmp.h
|
120
|
+
index 9b2c9ce..b27ef3d 100644
|
121
|
+
--- a/hmp.h
|
122
|
+
+++ b/hmp.h
|
123
|
+
@@ -86,5 +86,6 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
|
124
|
+
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
|
125
|
+
void hmp_chardev_add(Monitor *mon, const QDict *qdict);
|
126
|
+
void hmp_chardev_remove(Monitor *mon, const QDict *qdict);
|
127
|
+
+void hmp_qemu_io(Monitor *mon, const QDict *qdict);
|
128
|
+
|
129
|
+
#endif
|
130
|
+
--
|
131
|
+
1.8.3.1
|
132
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
From 5ccdcc1c49246cce9b1536e28a4977c65d72531c Mon Sep 17 00:00:00 2001
|
2
|
+
From: Laszlo Ersek <lersek@redhat.com>
|
3
|
+
Date: Wed, 11 May 2016 12:33:47 +0200
|
4
|
+
Subject: [PATCH 08/10] acpi: add function to extract oem_id and oem_table_id
|
5
|
+
from the user's SLIC
|
6
|
+
|
7
|
+
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
8
|
+
Message-id: <1462970028-10959-7-git-send-email-lersek@redhat.com>
|
9
|
+
Patchwork-id: 70383
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 6/7] acpi: add function to extract oem_id and oem_table_id from the user's SLIC
|
11
|
+
Bugzilla: 1330969
|
12
|
+
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
13
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
14
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
15
|
+
|
16
|
+
The acpi_get_slic_oem() function stores pointers to these fields in the
|
17
|
+
(first) SLIC table that the user passes in with the -acpitable switch.
|
18
|
+
|
19
|
+
Cc: "Michael S. Tsirkin" <mst@redhat.com> (supporter:ACPI/SMBIOS)
|
20
|
+
Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
|
21
|
+
Cc: Richard W.M. Jones <rjones@redhat.com>
|
22
|
+
Cc: Aleksei Kovura <alex3kov@zoho.com>
|
23
|
+
Cc: Michael Tokarev <mjt@tls.msk.ru>
|
24
|
+
Cc: Steven Newbury <steve@snewbury.org.uk>
|
25
|
+
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
|
26
|
+
LP: https://bugs.launchpad.net/qemu/+bug/1533848
|
27
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
28
|
+
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
29
|
+
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
30
|
+
Reviewed-by: Steven Newbury <steve@snewbury.org.uk>
|
31
|
+
(cherry picked from commit 88594e4fd1e916b778968b2bdd8d7375ca2fe8d8)
|
32
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
33
|
+
---
|
34
|
+
include/hw/acpi/acpi.h | 7 +++++++
|
35
|
+
hw/acpi/core.c | 16 ++++++++++++++++
|
36
|
+
2 files changed, 23 insertions(+)
|
37
|
+
|
38
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
39
|
+
---
|
40
|
+
hw/acpi/core.c | 16 ++++++++++++++++
|
41
|
+
include/hw/acpi/acpi.h | 7 +++++++
|
42
|
+
2 files changed, 23 insertions(+)
|
43
|
+
|
44
|
+
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
|
45
|
+
index 88efba7..99c5918 100644
|
46
|
+
--- a/hw/acpi/core.c
|
47
|
+
+++ b/hw/acpi/core.c
|
48
|
+
@@ -349,6 +349,22 @@ uint8_t *acpi_table_next(uint8_t *current)
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
+int acpi_get_slic_oem(AcpiSlicOem *oem)
|
53
|
+
+{
|
54
|
+
+ uint8_t *u;
|
55
|
+
+
|
56
|
+
+ for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
|
57
|
+
+ struct acpi_table_header *hdr = (void *)(u - sizeof(hdr->_length));
|
58
|
+
+
|
59
|
+
+ if (memcmp(hdr->sig, "SLIC", 4) == 0) {
|
60
|
+
+ oem->id = hdr->oem_id;
|
61
|
+
+ oem->table_id = hdr->oem_table_id;
|
62
|
+
+ return 0;
|
63
|
+
+ }
|
64
|
+
+ }
|
65
|
+
+ return -1;
|
66
|
+
+}
|
67
|
+
+
|
68
|
+
static void acpi_notify_wakeup(Notifier *notifier, void *data)
|
69
|
+
{
|
70
|
+
ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup);
|
71
|
+
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
|
72
|
+
index bb7136d..1e59ec9 100644
|
73
|
+
--- a/include/hw/acpi/acpi.h
|
74
|
+
+++ b/include/hw/acpi/acpi.h
|
75
|
+
@@ -171,4 +171,11 @@ unsigned acpi_table_len(void *current);
|
76
|
+
void acpi_table_add(const QemuOpts *opts, Error **errp);
|
77
|
+
void acpi_table_add_builtin(const QemuOpts *opts, Error **errp);
|
78
|
+
|
79
|
+
+typedef struct AcpiSlicOem AcpiSlicOem;
|
80
|
+
+struct AcpiSlicOem {
|
81
|
+
+ char *id;
|
82
|
+
+ char *table_id;
|
83
|
+
+};
|
84
|
+
+int acpi_get_slic_oem(AcpiSlicOem *oem);
|
85
|
+
+
|
86
|
+
#endif /* !QEMU_HW_ACPI_H */
|
87
|
+
--
|
88
|
+
1.8.3.1
|
89
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
From 39f2d80c57f648afd2eab27816e8f93cf48e718d Mon Sep 17 00:00:00 2001
|
2
|
+
From: Laszlo Ersek <lersek@redhat.com>
|
3
|
+
Date: Wed, 11 May 2016 12:33:46 +0200
|
4
|
+
Subject: [PATCH 07/10] acpi: expose oem_id and oem_table_id in build_rsdt()
|
5
|
+
|
6
|
+
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
7
|
+
Message-id: <1462970028-10959-6-git-send-email-lersek@redhat.com>
|
8
|
+
Patchwork-id: 70382
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 5/7] acpi: expose oem_id and oem_table_id in build_rsdt()
|
10
|
+
Bugzilla: 1330969
|
11
|
+
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
12
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
13
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
14
|
+
|
15
|
+
Since build_rsdt() is implemented as common utility code (in
|
16
|
+
"hw/acpi/aml-build.c"), it should expose -- and forward -- the oem_id and
|
17
|
+
oem_table_id parameters between board code and the generic build_header()
|
18
|
+
function.
|
19
|
+
|
20
|
+
Cc: "Michael S. Tsirkin" <mst@redhat.com> (supporter:ACPI/SMBIOS)
|
21
|
+
Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
|
22
|
+
Cc: Shannon Zhao <zhaoshenglong@huawei.com> (maintainer:ARM ACPI Subsystem)
|
23
|
+
Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
|
24
|
+
Cc: Richard W.M. Jones <rjones@redhat.com>
|
25
|
+
Cc: Aleksei Kovura <alex3kov@zoho.com>
|
26
|
+
Cc: Michael Tokarev <mjt@tls.msk.ru>
|
27
|
+
Cc: Steven Newbury <steve@snewbury.org.uk>
|
28
|
+
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
|
29
|
+
LP: https://bugs.launchpad.net/qemu/+bug/1533848
|
30
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
31
|
+
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
32
|
+
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
33
|
+
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
|
34
|
+
(cherry picked from commit 5151355898699eb66fad0a710b8b6011690a0dfc)
|
35
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
36
|
+
|
37
|
+
Conflicts:
|
38
|
+
hw/acpi/aml-build.c
|
39
|
+
hw/arm/virt-acpi-build.c
|
40
|
+
hw/i386/acpi-build.c
|
41
|
+
include/hw/acpi/aml-build.h
|
42
|
+
|
43
|
+
RHEL-7 backport note: this is actually a manual reimplementation of the
|
44
|
+
upstream patch, which is mostly mechanic. A clean cherry-pick would depend
|
45
|
+
on a lot of reorganizatorial upstream patches (e.g., 658c27181bf3
|
46
|
+
("hw/i386/acpi-build: move generic acpi building helpers into dedictated
|
47
|
+
file")), and many new features that overlap with ACPI generation (e.g.,
|
48
|
+
the "virt" machtype of the arm/aarch64 targets).
|
49
|
+
|
50
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
51
|
+
---
|
52
|
+
hw/i386/acpi-build.c | 7 ++++---
|
53
|
+
1 file changed, 4 insertions(+), 3 deletions(-)
|
54
|
+
---
|
55
|
+
hw/i386/acpi-build.c | 7 ++++---
|
56
|
+
1 file changed, 4 insertions(+), 3 deletions(-)
|
57
|
+
|
58
|
+
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
59
|
+
index 4839b0e..d9433e6 100644
|
60
|
+
--- a/hw/i386/acpi-build.c
|
61
|
+
+++ b/hw/i386/acpi-build.c
|
62
|
+
@@ -951,7 +951,8 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
|
63
|
+
|
64
|
+
/* Build final rsdt table */
|
65
|
+
static void
|
66
|
+
-build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
|
67
|
+
+build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
|
68
|
+
+ const char *oem_id, const char *oem_table_id)
|
69
|
+
{
|
70
|
+
AcpiRsdtDescriptorRev1 *rsdt;
|
71
|
+
size_t rsdt_len;
|
72
|
+
@@ -970,7 +971,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
|
73
|
+
sizeof(uint32_t));
|
74
|
+
}
|
75
|
+
build_header(linker, table_data,
|
76
|
+
- (void *)rsdt, "RSDT", rsdt_len, 1, NULL, NULL);
|
77
|
+
+ (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
|
78
|
+
}
|
79
|
+
|
80
|
+
static GArray *
|
81
|
+
@@ -1126,7 +1127,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
82
|
+
|
83
|
+
/* RSDT is pointed to by RSDP */
|
84
|
+
rsdt = tables->table_data->len;
|
85
|
+
- build_rsdt(tables->table_data, tables->linker, table_offsets);
|
86
|
+
+ build_rsdt(tables->table_data, tables->linker, table_offsets, NULL, NULL);
|
87
|
+
|
88
|
+
/* RSDP is in FSEG memory, so allocate it separately */
|
89
|
+
build_rsdp(tables->rsdp, tables->linker, rsdt);
|
90
|
+
--
|
91
|
+
1.8.3.1
|
92
|
+
|
@@ -0,0 +1,249 @@
|
|
1
|
+
From 87f01cd69488bf39e80c422b92717029fed0bef6 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Laszlo Ersek <lersek@redhat.com>
|
3
|
+
Date: Wed, 11 May 2016 12:33:43 +0200
|
4
|
+
Subject: [PATCH 04/10] acpi: fix endian-ness for table ids
|
5
|
+
|
6
|
+
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
7
|
+
Message-id: <1462970028-10959-3-git-send-email-lersek@redhat.com>
|
8
|
+
Patchwork-id: 70379
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 2/7] acpi: fix endian-ness for table ids
|
10
|
+
Bugzilla: 1330969
|
11
|
+
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
12
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
13
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
14
|
+
|
15
|
+
From: "Michael S. Tsirkin" <mst@redhat.com>
|
16
|
+
|
17
|
+
when using signature for table ID, we forgot to byte-swap it.
|
18
|
+
signatures are really ASCII strings, let's treat them as such.
|
19
|
+
While at it, get rid of most of _SIGNATURE macros.
|
20
|
+
|
21
|
+
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
22
|
+
(cherry picked from commit 821e3227863ea8db057190e578efa0f1f57ed9de)
|
23
|
+
|
24
|
+
RHEL-7 backport notes: this patch is being backported only to decrease the
|
25
|
+
number of conflicts in the upcoming patches; we only support x86_64 hosts,
|
26
|
+
which is unaffected by the endianness issue described in the upstream
|
27
|
+
commit message.
|
28
|
+
|
29
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
30
|
+
---
|
31
|
+
hw/i386/acpi-defs.h | 14 --------------
|
32
|
+
hw/i386/acpi-build.c | 31 ++++++++++++++++---------------
|
33
|
+
2 files changed, 16 insertions(+), 29 deletions(-)
|
34
|
+
|
35
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
36
|
+
---
|
37
|
+
hw/i386/acpi-build.c | 31 ++++++++++++++++---------------
|
38
|
+
hw/i386/acpi-defs.h | 14 --------------
|
39
|
+
2 files changed, 16 insertions(+), 29 deletions(-)
|
40
|
+
|
41
|
+
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
42
|
+
index a3a4c3b..be32bc3 100644
|
43
|
+
--- a/hw/i386/acpi-build.c
|
44
|
+
+++ b/hw/i386/acpi-build.c
|
45
|
+
@@ -243,14 +243,14 @@ static void acpi_get_pci_info(PcPciInfo *info)
|
46
|
+
|
47
|
+
static void
|
48
|
+
build_header(GArray *linker, GArray *table_data,
|
49
|
+
- AcpiTableHeader *h, uint32_t sig, int len, uint8_t rev)
|
50
|
+
+ AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
|
51
|
+
{
|
52
|
+
- h->signature = cpu_to_le32(sig);
|
53
|
+
+ memcpy(&h->signature, sig, 4);
|
54
|
+
h->length = cpu_to_le32(len);
|
55
|
+
h->revision = rev;
|
56
|
+
memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
|
57
|
+
memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
|
58
|
+
- memcpy(h->oem_table_id + 4, (void *)&sig, 4);
|
59
|
+
+ memcpy(h->oem_table_id + 4, sig, 4);
|
60
|
+
h->oem_revision = cpu_to_le32(1);
|
61
|
+
memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
|
62
|
+
h->asl_compiler_revision = cpu_to_le32(1);
|
63
|
+
@@ -463,7 +463,7 @@ static void
|
64
|
+
build_facs(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
|
65
|
+
{
|
66
|
+
AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs);
|
67
|
+
- facs->signature = cpu_to_le32(ACPI_FACS_SIGNATURE);
|
68
|
+
+ memcpy(&facs->signature, "FACS", 4);
|
69
|
+
facs->length = cpu_to_le32(sizeof(*facs));
|
70
|
+
}
|
71
|
+
|
72
|
+
@@ -520,7 +520,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
|
73
|
+
fadt_setup(fadt, pm);
|
74
|
+
|
75
|
+
build_header(linker, table_data,
|
76
|
+
- (void *)fadt, ACPI_FACP_SIGNATURE, sizeof(*fadt), 1);
|
77
|
+
+ (void *)fadt, "FACP", sizeof(*fadt), 1);
|
78
|
+
}
|
79
|
+
|
80
|
+
static void
|
81
|
+
@@ -589,7 +589,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
|
82
|
+
local_nmi->lint = 1; /* ACPI_LINT1 */
|
83
|
+
|
84
|
+
build_header(linker, table_data,
|
85
|
+
- (void *)(table_data->data + madt_start), ACPI_APIC_SIGNATURE,
|
86
|
+
+ (void *)(table_data->data + madt_start), "APIC",
|
87
|
+
table_data->len - madt_start, 1);
|
88
|
+
}
|
89
|
+
|
90
|
+
@@ -782,7 +782,7 @@ build_ssdt(GArray *table_data, GArray *linker,
|
91
|
+
|
92
|
+
build_header(linker, table_data,
|
93
|
+
(void *)(table_data->data + ssdt_start),
|
94
|
+
- ACPI_SSDT_SIGNATURE, table_data->len - ssdt_start, 1);
|
95
|
+
+ "SSDT", table_data->len - ssdt_start, 1);
|
96
|
+
}
|
97
|
+
|
98
|
+
static void
|
99
|
+
@@ -797,7 +797,7 @@ build_hpet(GArray *table_data, GArray *linker)
|
100
|
+
hpet->timer_block_id = cpu_to_le32(0x8086a201);
|
101
|
+
hpet->addr.address = cpu_to_le64(HPET_BASE);
|
102
|
+
build_header(linker, table_data,
|
103
|
+
- (void *)hpet, ACPI_HPET_SIGNATURE, sizeof(*hpet), 1);
|
104
|
+
+ (void *)hpet, "HPET", sizeof(*hpet), 1);
|
105
|
+
}
|
106
|
+
|
107
|
+
static void
|
108
|
+
@@ -889,7 +889,7 @@ build_srat(GArray *table_data, GArray *linker,
|
109
|
+
|
110
|
+
build_header(linker, table_data,
|
111
|
+
(void *)(table_data->data + srat_start),
|
112
|
+
- ACPI_SRAT_SIGNATURE,
|
113
|
+
+ "SRAT",
|
114
|
+
table_data->len - srat_start, 1);
|
115
|
+
}
|
116
|
+
|
117
|
+
@@ -897,7 +897,7 @@ static void
|
118
|
+
build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
|
119
|
+
{
|
120
|
+
AcpiTableMcfg *mcfg;
|
121
|
+
- uint32_t sig;
|
122
|
+
+ const char *sig;
|
123
|
+
int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]);
|
124
|
+
|
125
|
+
mcfg = acpi_data_push(table_data, len);
|
126
|
+
@@ -914,9 +914,10 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
|
127
|
+
* ACPI spec requires OSPMs to ignore such tables.
|
128
|
+
*/
|
129
|
+
if (info->mcfg_base == PCIE_BASE_ADDR_UNMAPPED) {
|
130
|
+
- sig = ACPI_RSRV_SIGNATURE;
|
131
|
+
+ /* Reserved signature: ignored by OSPM */
|
132
|
+
+ sig = "QEMU";
|
133
|
+
} else {
|
134
|
+
- sig = ACPI_MCFG_SIGNATURE;
|
135
|
+
+ sig = "MCFG";
|
136
|
+
}
|
137
|
+
build_header(linker, table_data, (void *)mcfg, sig, len, 1);
|
138
|
+
}
|
139
|
+
@@ -932,7 +933,7 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
|
140
|
+
memcpy(dsdt, misc->dsdt_code, misc->dsdt_size);
|
141
|
+
|
142
|
+
memset(dsdt, 0, sizeof *dsdt);
|
143
|
+
- build_header(linker, table_data, dsdt, ACPI_DSDT_SIGNATURE,
|
144
|
+
+ build_header(linker, table_data, dsdt, "DSDT",
|
145
|
+
misc->dsdt_size, 1);
|
146
|
+
}
|
147
|
+
|
148
|
+
@@ -957,7 +958,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
|
149
|
+
sizeof(uint32_t));
|
150
|
+
}
|
151
|
+
build_header(linker, table_data,
|
152
|
+
- (void *)rsdt, ACPI_RSDT_SIGNATURE, rsdt_len, 1);
|
153
|
+
+ (void *)rsdt, "RSDT", rsdt_len, 1);
|
154
|
+
}
|
155
|
+
|
156
|
+
static GArray *
|
157
|
+
@@ -968,7 +969,7 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
|
158
|
+
bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 1,
|
159
|
+
true /* fseg memory */);
|
160
|
+
|
161
|
+
- rsdp->signature = cpu_to_le64(ACPI_RSDP_SIGNATURE);
|
162
|
+
+ memcpy(&rsdp->signature, "RSD PTR ", 8);
|
163
|
+
memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
|
164
|
+
rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
|
165
|
+
/* Address to be filled by Guest linker */
|
166
|
+
diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h
|
167
|
+
index 78ca204..e93babb 100644
|
168
|
+
--- a/hw/i386/acpi-defs.h
|
169
|
+
+++ b/hw/i386/acpi-defs.h
|
170
|
+
@@ -52,8 +52,6 @@ struct Acpi20GenericAddress {
|
171
|
+
} QEMU_PACKED;
|
172
|
+
typedef struct Acpi20GenericAddress Acpi20GenericAddress;
|
173
|
+
|
174
|
+
-#define ACPI_RSDP_SIGNATURE 0x2052545020445352LL // "RSD PTR "
|
175
|
+
-
|
176
|
+
struct AcpiRsdpDescriptor { /* Root System Descriptor Pointer */
|
177
|
+
uint64_t signature; /* ACPI signature, contains "RSD PTR " */
|
178
|
+
uint8_t checksum; /* To make sum of struct == 0 */
|
179
|
+
@@ -92,7 +90,6 @@ typedef struct AcpiTableHeader AcpiTableHeader;
|
180
|
+
/*
|
181
|
+
* ACPI 1.0 Fixed ACPI Description Table (FADT)
|
182
|
+
*/
|
183
|
+
-#define ACPI_FACP_SIGNATURE 0x50434146 // FACP
|
184
|
+
struct AcpiFadtDescriptorRev1
|
185
|
+
{
|
186
|
+
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
187
|
+
@@ -141,7 +138,6 @@ typedef struct AcpiFadtDescriptorRev1 AcpiFadtDescriptorRev1;
|
188
|
+
/*
|
189
|
+
* ACPI 1.0 Root System Description Table (RSDT)
|
190
|
+
*/
|
191
|
+
-#define ACPI_RSDT_SIGNATURE 0x54445352 // RSDT
|
192
|
+
struct AcpiRsdtDescriptorRev1
|
193
|
+
{
|
194
|
+
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
195
|
+
@@ -153,7 +149,6 @@ typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1;
|
196
|
+
/*
|
197
|
+
* ACPI 1.0 Firmware ACPI Control Structure (FACS)
|
198
|
+
*/
|
199
|
+
-#define ACPI_FACS_SIGNATURE 0x53434146 // FACS
|
200
|
+
struct AcpiFacsDescriptorRev1
|
201
|
+
{
|
202
|
+
uint32_t signature; /* ACPI Signature */
|
203
|
+
@@ -169,7 +164,6 @@ typedef struct AcpiFacsDescriptorRev1 AcpiFacsDescriptorRev1;
|
204
|
+
/*
|
205
|
+
* Differentiated System Description Table (DSDT)
|
206
|
+
*/
|
207
|
+
-#define ACPI_DSDT_SIGNATURE 0x54445344 // DSDT
|
208
|
+
|
209
|
+
/*
|
210
|
+
* MADT values and structures
|
211
|
+
@@ -182,7 +176,6 @@ typedef struct AcpiFacsDescriptorRev1 AcpiFacsDescriptorRev1;
|
212
|
+
|
213
|
+
/* Master MADT */
|
214
|
+
|
215
|
+
-#define ACPI_APIC_SIGNATURE 0x43495041 // APIC
|
216
|
+
struct AcpiMultipleApicTable
|
217
|
+
{
|
218
|
+
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
219
|
+
@@ -253,7 +246,6 @@ typedef struct AcpiMadtLocalNmi AcpiMadtLocalNmi;
|
220
|
+
/*
|
221
|
+
* HPET Description Table
|
222
|
+
*/
|
223
|
+
-#define ACPI_HPET_SIGNATURE 0x54455048 // HPET
|
224
|
+
struct Acpi20Hpet {
|
225
|
+
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
226
|
+
uint32_t timer_block_id;
|
227
|
+
@@ -268,7 +260,6 @@ typedef struct Acpi20Hpet Acpi20Hpet;
|
228
|
+
* SRAT (NUMA topology description) table
|
229
|
+
*/
|
230
|
+
|
231
|
+
-#define ACPI_SRAT_SIGNATURE 0x54415253 // SRAT
|
232
|
+
struct AcpiSystemResourceAffinityTable
|
233
|
+
{
|
234
|
+
ACPI_TABLE_HEADER_DEF
|
235
|
+
@@ -316,11 +307,6 @@ struct AcpiMcfgAllocation {
|
236
|
+
} QEMU_PACKED;
|
237
|
+
typedef struct AcpiMcfgAllocation AcpiMcfgAllocation;
|
238
|
+
|
239
|
+
-#define ACPI_MCFG_SIGNATURE 0x4746434d // MCFG
|
240
|
+
-
|
241
|
+
-/* Reserved signature: ignored by OSPM */
|
242
|
+
-#define ACPI_RSRV_SIGNATURE 0x554d4551 // QEMU
|
243
|
+
-
|
244
|
+
struct AcpiTableMcfg {
|
245
|
+
ACPI_TABLE_HEADER_DEF;
|
246
|
+
uint8_t reserved[8];
|
247
|
+
--
|
248
|
+
1.8.3.1
|
249
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
From 464ceecd1e9c070e613624fb896df54b7e4a3e38 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Laszlo Ersek <lersek@redhat.com>
|
3
|
+
Date: Wed, 11 May 2016 12:33:42 +0200
|
4
|
+
Subject: [PATCH 03/10] acpi: strip compiler info in built-in DSDT
|
5
|
+
|
6
|
+
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
7
|
+
Message-id: <1462970028-10959-2-git-send-email-lersek@redhat.com>
|
8
|
+
Patchwork-id: 70378
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 1/7] acpi: strip compiler info in built-in DSDT
|
10
|
+
Bugzilla: 1330969
|
11
|
+
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
12
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
13
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
14
|
+
|
15
|
+
From: "Michael S. Tsirkin" <mst@redhat.com>
|
16
|
+
|
17
|
+
IASL stores it's revision in each table header it generates.
|
18
|
+
That's not nice since guests will see a change each time they move
|
19
|
+
between hypervisors. We generally fill our own info for tables, but we
|
20
|
+
(and seabios) forgot to do this for the built-in DSDT.
|
21
|
+
|
22
|
+
Modifications in DSDT table:
|
23
|
+
OEM ID: "BXPC" -> "BOCHS "
|
24
|
+
OEM Table ID: "BXDSDT" -> "BXPCDSDT"
|
25
|
+
Compiler ID: "INTL" -> "BXPC"
|
26
|
+
Compiler Version: 0x20130823 -> 0x00000001
|
27
|
+
|
28
|
+
Tested-by: Marcel Apfelbaum <marcel.a@redhat.com>
|
29
|
+
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
30
|
+
(cherry picked from commit 53db092ad1c81c30a617f44e83e8fb9e27c001ba)
|
31
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
32
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
33
|
+
---
|
34
|
+
hw/i386/acpi-build.c | 8 +++++++-
|
35
|
+
1 file changed, 7 insertions(+), 1 deletion(-)
|
36
|
+
|
37
|
+
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
38
|
+
index 8be1286..a3a4c3b 100644
|
39
|
+
--- a/hw/i386/acpi-build.c
|
40
|
+
+++ b/hw/i386/acpi-build.c
|
41
|
+
@@ -924,10 +924,16 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
|
42
|
+
static void
|
43
|
+
build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
|
44
|
+
{
|
45
|
+
- void *dsdt;
|
46
|
+
+ AcpiTableHeader *dsdt;
|
47
|
+
+
|
48
|
+
assert(misc->dsdt_code && misc->dsdt_size);
|
49
|
+
+
|
50
|
+
dsdt = acpi_data_push(table_data, misc->dsdt_size);
|
51
|
+
memcpy(dsdt, misc->dsdt_code, misc->dsdt_size);
|
52
|
+
+
|
53
|
+
+ memset(dsdt, 0, sizeof *dsdt);
|
54
|
+
+ build_header(linker, table_data, dsdt, ACPI_DSDT_SIGNATURE,
|
55
|
+
+ misc->dsdt_size, 1);
|
56
|
+
}
|
57
|
+
|
58
|
+
/* Build final rsdt table */
|
59
|
+
--
|
60
|
+
1.8.3.1
|
61
|
+
|
@@ -0,0 +1,154 @@
|
|
1
|
+
From b36e60614f9c4a6eb3f417422c3cb99402b82963 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Laszlo Ersek <lersek@redhat.com>
|
3
|
+
Date: Wed, 11 May 2016 12:33:44 +0200
|
4
|
+
Subject: [PATCH 05/10] acpi: support specified oem table id for build_header
|
5
|
+
|
6
|
+
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
7
|
+
Message-id: <1462970028-10959-4-git-send-email-lersek@redhat.com>
|
8
|
+
Patchwork-id: 70380
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 3/7] acpi: support specified oem table id for build_header
|
10
|
+
Bugzilla: 1330969
|
11
|
+
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
12
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
13
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
14
|
+
|
15
|
+
From: Xiao Guangrong <guangrong.xiao@linux.intel.com>
|
16
|
+
|
17
|
+
Let build_header() support specified OEM table id so that we can build
|
18
|
+
multiple SSDT later
|
19
|
+
|
20
|
+
If the oem table id is not specified (aka, NULL), we use the default id
|
21
|
+
instead as the previous behavior
|
22
|
+
|
23
|
+
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
24
|
+
Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
|
25
|
+
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
26
|
+
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
27
|
+
(cherry picked from commit 8870ca0e94f2524644812dd759863c0851ffb870)
|
28
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
29
|
+
|
30
|
+
Conflicts:
|
31
|
+
hw/acpi/aml-build.c
|
32
|
+
hw/arm/virt-acpi-build.c
|
33
|
+
hw/i386/acpi-build.c
|
34
|
+
include/hw/acpi/aml-build.h
|
35
|
+
|
36
|
+
RHEL-7 backport note: this is actually a manual reimplementation of the
|
37
|
+
upstream patch, which is mostly mechanic. A clean cherry-pick would depend
|
38
|
+
on a lot of reorganizatorial upstream patches (e.g., 658c27181bf3
|
39
|
+
("hw/i386/acpi-build: move generic acpi building helpers into dedictated
|
40
|
+
file")), and many new features that overlap with ACPI generation (e.g.,
|
41
|
+
the "virt" machtype of the arm/aarch64 targets).
|
42
|
+
|
43
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
44
|
+
---
|
45
|
+
hw/i386/acpi-build.c | 29 ++++++++++++++++++-----------
|
46
|
+
1 file changed, 18 insertions(+), 11 deletions(-)
|
47
|
+
---
|
48
|
+
hw/i386/acpi-build.c | 29 ++++++++++++++++++-----------
|
49
|
+
1 file changed, 18 insertions(+), 11 deletions(-)
|
50
|
+
|
51
|
+
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
52
|
+
index be32bc3..a9d9f97 100644
|
53
|
+
--- a/hw/i386/acpi-build.c
|
54
|
+
+++ b/hw/i386/acpi-build.c
|
55
|
+
@@ -243,14 +243,21 @@ static void acpi_get_pci_info(PcPciInfo *info)
|
56
|
+
|
57
|
+
static void
|
58
|
+
build_header(GArray *linker, GArray *table_data,
|
59
|
+
- AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
|
60
|
+
+ AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
|
61
|
+
+ const char *oem_table_id)
|
62
|
+
{
|
63
|
+
memcpy(&h->signature, sig, 4);
|
64
|
+
h->length = cpu_to_le32(len);
|
65
|
+
h->revision = rev;
|
66
|
+
memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
|
67
|
+
- memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
|
68
|
+
- memcpy(h->oem_table_id + 4, sig, 4);
|
69
|
+
+
|
70
|
+
+ if (oem_table_id) {
|
71
|
+
+ strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
|
72
|
+
+ } else {
|
73
|
+
+ memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
|
74
|
+
+ memcpy(h->oem_table_id + 4, sig, 4);
|
75
|
+
+ }
|
76
|
+
+
|
77
|
+
h->oem_revision = cpu_to_le32(1);
|
78
|
+
memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
|
79
|
+
h->asl_compiler_revision = cpu_to_le32(1);
|
80
|
+
@@ -520,7 +527,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
|
81
|
+
fadt_setup(fadt, pm);
|
82
|
+
|
83
|
+
build_header(linker, table_data,
|
84
|
+
- (void *)fadt, "FACP", sizeof(*fadt), 1);
|
85
|
+
+ (void *)fadt, "FACP", sizeof(*fadt), 1, NULL);
|
86
|
+
}
|
87
|
+
|
88
|
+
static void
|
89
|
+
@@ -590,7 +597,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
|
90
|
+
|
91
|
+
build_header(linker, table_data,
|
92
|
+
(void *)(table_data->data + madt_start), "APIC",
|
93
|
+
- table_data->len - madt_start, 1);
|
94
|
+
+ table_data->len - madt_start, 1, NULL);
|
95
|
+
}
|
96
|
+
|
97
|
+
/* Encode a hex value */
|
98
|
+
@@ -782,7 +789,7 @@ build_ssdt(GArray *table_data, GArray *linker,
|
99
|
+
|
100
|
+
build_header(linker, table_data,
|
101
|
+
(void *)(table_data->data + ssdt_start),
|
102
|
+
- "SSDT", table_data->len - ssdt_start, 1);
|
103
|
+
+ "SSDT", table_data->len - ssdt_start, 1, NULL);
|
104
|
+
}
|
105
|
+
|
106
|
+
static void
|
107
|
+
@@ -797,7 +804,7 @@ build_hpet(GArray *table_data, GArray *linker)
|
108
|
+
hpet->timer_block_id = cpu_to_le32(0x8086a201);
|
109
|
+
hpet->addr.address = cpu_to_le64(HPET_BASE);
|
110
|
+
build_header(linker, table_data,
|
111
|
+
- (void *)hpet, "HPET", sizeof(*hpet), 1);
|
112
|
+
+ (void *)hpet, "HPET", sizeof(*hpet), 1, NULL);
|
113
|
+
}
|
114
|
+
|
115
|
+
static void
|
116
|
+
@@ -890,7 +897,7 @@ build_srat(GArray *table_data, GArray *linker,
|
117
|
+
build_header(linker, table_data,
|
118
|
+
(void *)(table_data->data + srat_start),
|
119
|
+
"SRAT",
|
120
|
+
- table_data->len - srat_start, 1);
|
121
|
+
+ table_data->len - srat_start, 1, NULL);
|
122
|
+
}
|
123
|
+
|
124
|
+
static void
|
125
|
+
@@ -919,7 +926,7 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
|
126
|
+
} else {
|
127
|
+
sig = "MCFG";
|
128
|
+
}
|
129
|
+
- build_header(linker, table_data, (void *)mcfg, sig, len, 1);
|
130
|
+
+ build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL);
|
131
|
+
}
|
132
|
+
|
133
|
+
static void
|
134
|
+
@@ -934,7 +941,7 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
|
135
|
+
|
136
|
+
memset(dsdt, 0, sizeof *dsdt);
|
137
|
+
build_header(linker, table_data, dsdt, "DSDT",
|
138
|
+
- misc->dsdt_size, 1);
|
139
|
+
+ misc->dsdt_size, 1, NULL);
|
140
|
+
}
|
141
|
+
|
142
|
+
/* Build final rsdt table */
|
143
|
+
@@ -958,7 +965,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
|
144
|
+
sizeof(uint32_t));
|
145
|
+
}
|
146
|
+
build_header(linker, table_data,
|
147
|
+
- (void *)rsdt, "RSDT", rsdt_len, 1);
|
148
|
+
+ (void *)rsdt, "RSDT", rsdt_len, 1, NULL);
|
149
|
+
}
|
150
|
+
|
151
|
+
static GArray *
|
152
|
+
--
|
153
|
+
1.8.3.1
|
154
|
+
|
@@ -0,0 +1,157 @@
|
|
1
|
+
From 0decede8a51451da8f5913b0ad13c8e3bdcef582 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Laszlo Ersek <lersek@redhat.com>
|
3
|
+
Date: Wed, 11 May 2016 12:33:45 +0200
|
4
|
+
Subject: [PATCH 06/10] acpi: take oem_id in build_header(), optionally
|
5
|
+
|
6
|
+
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
7
|
+
Message-id: <1462970028-10959-5-git-send-email-lersek@redhat.com>
|
8
|
+
Patchwork-id: 70381
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 4/7] acpi: take oem_id in build_header(), optionally
|
10
|
+
Bugzilla: 1330969
|
11
|
+
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
12
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
13
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
14
|
+
|
15
|
+
This patch is the continuation of commit 8870ca0e94f2 ("acpi: support
|
16
|
+
specified oem table id for build_header"). It will allow us to control the
|
17
|
+
OEM ID field too in the SDT header.
|
18
|
+
|
19
|
+
Cc: "Michael S. Tsirkin" <mst@redhat.com> (supporter:ACPI/SMBIOS)
|
20
|
+
Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
|
21
|
+
Cc: Xiao Guangrong <guangrong.xiao@linux.intel.com> (maintainer:NVDIMM)
|
22
|
+
Cc: Shannon Zhao <zhaoshenglong@huawei.com> (maintainer:ARM ACPI Subsystem)
|
23
|
+
Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
|
24
|
+
Cc: Richard W.M. Jones <rjones@redhat.com>
|
25
|
+
Cc: Aleksei Kovura <alex3kov@zoho.com>
|
26
|
+
Cc: Michael Tokarev <mjt@tls.msk.ru>
|
27
|
+
Cc: Steven Newbury <steve@snewbury.org.uk>
|
28
|
+
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
|
29
|
+
LP: https://bugs.launchpad.net/qemu/+bug/1533848
|
30
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
31
|
+
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
32
|
+
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
33
|
+
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
|
34
|
+
(cherry picked from commit 37ad223c515da2fe9f1c679768cb5ccaa42e57e1)
|
35
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
36
|
+
|
37
|
+
Conflicts:
|
38
|
+
hw/acpi/aml-build.c
|
39
|
+
hw/acpi/nvdimm.c
|
40
|
+
hw/arm/virt-acpi-build.c
|
41
|
+
hw/i386/acpi-build.c
|
42
|
+
include/hw/acpi/aml-build.h
|
43
|
+
|
44
|
+
RHEL-7 backport note: this is actually a manual reimplementation of the
|
45
|
+
upstream patch, which is mostly mechanic. A clean cherry-pick would depend
|
46
|
+
on a lot of reorganizatorial upstream patches (e.g., 658c27181bf3
|
47
|
+
("hw/i386/acpi-build: move generic acpi building helpers into dedictated
|
48
|
+
file")), and many new features that overlap with ACPI generation (e.g.,
|
49
|
+
the "virt" machtype of the arm/aarch64 targets).
|
50
|
+
|
51
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
52
|
+
---
|
53
|
+
hw/i386/acpi-build.c | 25 +++++++++++++++----------
|
54
|
+
1 file changed, 15 insertions(+), 10 deletions(-)
|
55
|
+
---
|
56
|
+
hw/i386/acpi-build.c | 25 +++++++++++++++----------
|
57
|
+
1 file changed, 15 insertions(+), 10 deletions(-)
|
58
|
+
|
59
|
+
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
60
|
+
index a9d9f97..4839b0e 100644
|
61
|
+
--- a/hw/i386/acpi-build.c
|
62
|
+
+++ b/hw/i386/acpi-build.c
|
63
|
+
@@ -244,12 +244,17 @@ static void acpi_get_pci_info(PcPciInfo *info)
|
64
|
+
static void
|
65
|
+
build_header(GArray *linker, GArray *table_data,
|
66
|
+
AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
|
67
|
+
- const char *oem_table_id)
|
68
|
+
+ const char *oem_id, const char *oem_table_id)
|
69
|
+
{
|
70
|
+
memcpy(&h->signature, sig, 4);
|
71
|
+
h->length = cpu_to_le32(len);
|
72
|
+
h->revision = rev;
|
73
|
+
- memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
|
74
|
+
+
|
75
|
+
+ if (oem_id) {
|
76
|
+
+ strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);
|
77
|
+
+ } else {
|
78
|
+
+ memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
|
79
|
+
+ }
|
80
|
+
|
81
|
+
if (oem_table_id) {
|
82
|
+
strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
|
83
|
+
@@ -527,7 +532,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
|
84
|
+
fadt_setup(fadt, pm);
|
85
|
+
|
86
|
+
build_header(linker, table_data,
|
87
|
+
- (void *)fadt, "FACP", sizeof(*fadt), 1, NULL);
|
88
|
+
+ (void *)fadt, "FACP", sizeof(*fadt), 1, NULL, NULL);
|
89
|
+
}
|
90
|
+
|
91
|
+
static void
|
92
|
+
@@ -597,7 +602,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
|
93
|
+
|
94
|
+
build_header(linker, table_data,
|
95
|
+
(void *)(table_data->data + madt_start), "APIC",
|
96
|
+
- table_data->len - madt_start, 1, NULL);
|
97
|
+
+ table_data->len - madt_start, 1, NULL, NULL);
|
98
|
+
}
|
99
|
+
|
100
|
+
/* Encode a hex value */
|
101
|
+
@@ -789,7 +794,7 @@ build_ssdt(GArray *table_data, GArray *linker,
|
102
|
+
|
103
|
+
build_header(linker, table_data,
|
104
|
+
(void *)(table_data->data + ssdt_start),
|
105
|
+
- "SSDT", table_data->len - ssdt_start, 1, NULL);
|
106
|
+
+ "SSDT", table_data->len - ssdt_start, 1, NULL, NULL);
|
107
|
+
}
|
108
|
+
|
109
|
+
static void
|
110
|
+
@@ -804,7 +809,7 @@ build_hpet(GArray *table_data, GArray *linker)
|
111
|
+
hpet->timer_block_id = cpu_to_le32(0x8086a201);
|
112
|
+
hpet->addr.address = cpu_to_le64(HPET_BASE);
|
113
|
+
build_header(linker, table_data,
|
114
|
+
- (void *)hpet, "HPET", sizeof(*hpet), 1, NULL);
|
115
|
+
+ (void *)hpet, "HPET", sizeof(*hpet), 1, NULL, NULL);
|
116
|
+
}
|
117
|
+
|
118
|
+
static void
|
119
|
+
@@ -897,7 +902,7 @@ build_srat(GArray *table_data, GArray *linker,
|
120
|
+
build_header(linker, table_data,
|
121
|
+
(void *)(table_data->data + srat_start),
|
122
|
+
"SRAT",
|
123
|
+
- table_data->len - srat_start, 1, NULL);
|
124
|
+
+ table_data->len - srat_start, 1, NULL, NULL);
|
125
|
+
}
|
126
|
+
|
127
|
+
static void
|
128
|
+
@@ -926,7 +931,7 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
|
129
|
+
} else {
|
130
|
+
sig = "MCFG";
|
131
|
+
}
|
132
|
+
- build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL);
|
133
|
+
+ build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL, NULL);
|
134
|
+
}
|
135
|
+
|
136
|
+
static void
|
137
|
+
@@ -941,7 +946,7 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
|
138
|
+
|
139
|
+
memset(dsdt, 0, sizeof *dsdt);
|
140
|
+
build_header(linker, table_data, dsdt, "DSDT",
|
141
|
+
- misc->dsdt_size, 1, NULL);
|
142
|
+
+ misc->dsdt_size, 1, NULL, NULL);
|
143
|
+
}
|
144
|
+
|
145
|
+
/* Build final rsdt table */
|
146
|
+
@@ -965,7 +970,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
|
147
|
+
sizeof(uint32_t));
|
148
|
+
}
|
149
|
+
build_header(linker, table_data,
|
150
|
+
- (void *)rsdt, "RSDT", rsdt_len, 1, NULL);
|
151
|
+
+ (void *)rsdt, "RSDT", rsdt_len, 1, NULL, NULL);
|
152
|
+
}
|
153
|
+
|
154
|
+
static GArray *
|
155
|
+
--
|
156
|
+
1.8.3.1
|
157
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
From 89f3f5eafd6aed8a79b4570553af711dffc3a1d6 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:36 +0100
|
4
|
+
Subject: [PATCH 17/27] blkdebug: Add BLKDBG_FLUSH_TO_OS/DISK events
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-18-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68448
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 17/21] blkdebug: Add BLKDBG_FLUSH_TO_OS/DISK events
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
18
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
19
|
+
(cherry picked from commit bf736fe34caba0688c9095c31b9d097ea15c1296)
|
20
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
21
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
22
|
+
|
23
|
+
Conflicts:
|
24
|
+
block/blkdebug.c: debug event ordering
|
25
|
+
include/block/block.h: debug event ordering
|
26
|
+
|
27
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
28
|
+
---
|
29
|
+
block.c | 8 ++++----
|
30
|
+
block/blkdebug.c | 3 +++
|
31
|
+
include/block/block.h | 3 +++
|
32
|
+
3 files changed, 10 insertions(+), 4 deletions(-)
|
33
|
+
|
34
|
+
diff --git a/block.c b/block.c
|
35
|
+
index bc6e75c..ecb2b09 100644
|
36
|
+
--- a/block.c
|
37
|
+
+++ b/block.c
|
38
|
+
@@ -4026,13 +4026,11 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
39
|
+
|
40
|
+
void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
|
41
|
+
{
|
42
|
+
- BlockDriver *drv = bs->drv;
|
43
|
+
-
|
44
|
+
- if (!drv || !drv->bdrv_debug_event) {
|
45
|
+
+ if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) {
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
|
49
|
+
- drv->bdrv_debug_event(bs, event);
|
50
|
+
+ bs->drv->bdrv_debug_event(bs, event);
|
51
|
+
}
|
52
|
+
|
53
|
+
int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
|
54
|
+
@@ -4879,6 +4877,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
|
55
|
+
}
|
56
|
+
|
57
|
+
/* Write back cached data to the OS even with cache=unsafe */
|
58
|
+
+ BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_OS);
|
59
|
+
if (bs->drv->bdrv_co_flush_to_os) {
|
60
|
+
ret = bs->drv->bdrv_co_flush_to_os(bs);
|
61
|
+
if (ret < 0) {
|
62
|
+
@@ -4891,6 +4890,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
|
63
|
+
goto flush_parent;
|
64
|
+
}
|
65
|
+
|
66
|
+
+ BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_DISK);
|
67
|
+
if (bs->drv->bdrv_co_flush_to_disk) {
|
68
|
+
ret = bs->drv->bdrv_co_flush_to_disk(bs);
|
69
|
+
} else if (bs->drv->bdrv_aio_flush) {
|
70
|
+
diff --git a/block/blkdebug.c b/block/blkdebug.c
|
71
|
+
index c61ce52..8e468b2 100644
|
72
|
+
--- a/block/blkdebug.c
|
73
|
+
+++ b/block/blkdebug.c
|
74
|
+
@@ -184,6 +184,9 @@ static const char *event_names[BLKDBG_EVENT_MAX] = {
|
75
|
+
[BLKDBG_CLUSTER_ALLOC_BYTES] = "cluster_alloc_bytes",
|
76
|
+
[BLKDBG_CLUSTER_FREE] = "cluster_free",
|
77
|
+
|
78
|
+
+ [BLKDBG_FLUSH_TO_OS] = "flush_to_os",
|
79
|
+
+ [BLKDBG_FLUSH_TO_DISK] = "flush_to_disk",
|
80
|
+
+
|
81
|
+
[BLKDBG_PWRITEV_RMW_HEAD] = "pwritev_rmw.head",
|
82
|
+
[BLKDBG_PWRITEV_RMW_AFTER_HEAD] = "pwritev_rmw.after_head",
|
83
|
+
[BLKDBG_PWRITEV_RMW_TAIL] = "pwritev_rmw.tail",
|
84
|
+
diff --git a/include/block/block.h b/include/block/block.h
|
85
|
+
index 8339cac..75147b2 100644
|
86
|
+
--- a/include/block/block.h
|
87
|
+
+++ b/include/block/block.h
|
88
|
+
@@ -508,6 +508,9 @@ typedef enum {
|
89
|
+
BLKDBG_CLUSTER_ALLOC_BYTES,
|
90
|
+
BLKDBG_CLUSTER_FREE,
|
91
|
+
|
92
|
+
+ BLKDBG_FLUSH_TO_OS,
|
93
|
+
+ BLKDBG_FLUSH_TO_DISK,
|
94
|
+
+
|
95
|
+
BLKDBG_PWRITEV_RMW_HEAD,
|
96
|
+
BLKDBG_PWRITEV_RMW_AFTER_HEAD,
|
97
|
+
BLKDBG_PWRITEV_RMW_TAIL,
|
98
|
+
--
|
99
|
+
1.8.3.1
|
100
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
From b9d7b6bbaa64404eb9b4a65d0af841bfae5c9089 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 11 Jul 2016 05:33:36 +0200
|
4
|
+
Subject: [PATCH 3/7] block-backend: expose bs->bl.max_transfer_length
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1468215219-30793-4-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 71107
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 3/6] block-backend: expose bs->bl.max_transfer_length
|
10
|
+
Bugzilla: 1318199
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Peter Lieven <pl@kamp.de>
|
16
|
+
|
17
|
+
Signed-off-by: Peter Lieven <pl@kamp.de>
|
18
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
19
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
20
|
+
(cherry picked from commit 454057b7d9b9ad141bd5df8c4075745e56b4870f)
|
21
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
22
|
+
|
23
|
+
Conflicts:
|
24
|
+
block/block-backend.c
|
25
|
+
include/sysemu/block-backend.h
|
26
|
+
|
27
|
+
Downstream doesn't have BlockBackend yet, so "blk_" -> "bdrv_" and put
|
28
|
+
the function in block.c.
|
29
|
+
|
30
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
31
|
+
---
|
32
|
+
block.c | 5 +++++
|
33
|
+
include/block/block.h | 1 +
|
34
|
+
2 files changed, 6 insertions(+)
|
35
|
+
|
36
|
+
diff --git a/block.c b/block.c
|
37
|
+
index ae756aa..bdcd741 100644
|
38
|
+
--- a/block.c
|
39
|
+
+++ b/block.c
|
40
|
+
@@ -3656,6 +3656,11 @@ int bdrv_get_flags(BlockDriverState *bs)
|
41
|
+
return bs->open_flags;
|
42
|
+
}
|
43
|
+
|
44
|
+
+int bdrv_get_max_transfer_length(BlockDriverState *bs)
|
45
|
+
+{
|
46
|
+
+ return bs->bl.max_transfer_length;
|
47
|
+
+}
|
48
|
+
+
|
49
|
+
int bdrv_flush_all(void)
|
50
|
+
{
|
51
|
+
BlockDriverState *bs;
|
52
|
+
diff --git a/include/block/block.h b/include/block/block.h
|
53
|
+
index 75147b2..d29733a 100644
|
54
|
+
--- a/include/block/block.h
|
55
|
+
+++ b/include/block/block.h
|
56
|
+
@@ -379,6 +379,7 @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
|
57
|
+
void *opaque);
|
58
|
+
const char *bdrv_get_device_name(BlockDriverState *bs);
|
59
|
+
int bdrv_get_flags(BlockDriverState *bs);
|
60
|
+
+int bdrv_get_max_transfer_length(BlockDriverState *bs);
|
61
|
+
int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
|
62
|
+
const uint8_t *buf, int nb_sectors);
|
63
|
+
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
|
64
|
+
--
|
65
|
+
1.8.3.1
|
66
|
+
|
@@ -1,16 +1,16 @@
|
|
1
|
-
From
|
1
|
+
From d2291657a3d6100be53008fe8206c9e72b37c584 Mon Sep 17 00:00:00 2001
|
2
2
|
From: Fam Zheng <famz@redhat.com>
|
3
|
-
Date:
|
3
|
+
Date: Wed, 22 Jun 2016 01:06:15 +0200
|
4
4
|
Subject: [PATCH] block/iscsi: avoid potential overflow of acb->task->cdb
|
5
5
|
|
6
6
|
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
-
Message-id: <
|
8
|
-
Patchwork-id:
|
9
|
-
O-Subject: [RHEL-7.
|
10
|
-
Bugzilla:
|
11
|
-
RH-Acked-by:
|
7
|
+
Message-id: <20160622010615.10307-1-famz@redhat.com>
|
8
|
+
Patchwork-id: 70730
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH] block/iscsi: avoid potential overflow of acb->task->cdb
|
10
|
+
Bugzilla: 1340929
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
-
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
12
|
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
13
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
14
14
|
|
15
15
|
From: Peter Lieven <pl@kamp.de>
|
16
16
|
|
@@ -0,0 +1,141 @@
|
|
1
|
+
From bb8aca64535578520c4b7f5186f9ae5754626694 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Jeffrey Cody <jcody@redhat.com>
|
3
|
+
Date: Thu, 5 May 2016 19:46:28 +0200
|
4
|
+
Subject: [PATCH 10/10] block jobs: qemu-kvm-rhel differentiation
|
5
|
+
|
6
|
+
RH-Author: Jeffrey Cody <jcody@redhat.com>
|
7
|
+
Message-id: <f2ce1dbde4055f710cb6f83e6edd9e93a498b366.1462477116.git.jcody@redhat.com>
|
8
|
+
Patchwork-id: 70344
|
9
|
+
O-Subject: [RHEL7.3 qemu-kvm-rhel 1/1] block jobs: qemu-kvm-rhel differentiation
|
10
|
+
Bugzilla: 1156635
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
14
|
+
|
15
|
+
The conditional block job disablement for RHEL left some QAPI / HMP
|
16
|
+
commands in place, that are vestigial without any actual block jobs to
|
17
|
+
control.
|
18
|
+
|
19
|
+
This patch envelopes those block-job related functions in the
|
20
|
+
conditional code that is disabled for RHEL:
|
21
|
+
|
22
|
+
block-job-set-speed
|
23
|
+
block-job-cancel
|
24
|
+
block-job-pause
|
25
|
+
block-job-resume
|
26
|
+
block-job-complete
|
27
|
+
|
28
|
+
Signed-off-by: Jeff Cody <jcody@redhat.com>
|
29
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
30
|
+
---
|
31
|
+
blockdev.c | 2 +-
|
32
|
+
hmp-commands.hx | 2 +-
|
33
|
+
hmp.c | 2 +-
|
34
|
+
qapi-schema.json | 2 +-
|
35
|
+
qmp-commands.hx | 3 ---
|
36
|
+
5 files changed, 4 insertions(+), 7 deletions(-)
|
37
|
+
|
38
|
+
diff --git a/blockdev.c b/blockdev.c
|
39
|
+
index b5792a2..69e951f 100644
|
40
|
+
--- a/blockdev.c
|
41
|
+
+++ b/blockdev.c
|
42
|
+
@@ -1701,7 +1701,6 @@ void qmp_drive_mirror(const char *device, const char *target,
|
43
|
+
return;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
-#endif
|
47
|
+
|
48
|
+
static BlockJob *find_block_job(const char *device)
|
49
|
+
{
|
50
|
+
@@ -1786,6 +1785,7 @@ void qmp_block_job_complete(const char *device, Error **errp)
|
51
|
+
trace_qmp_block_job_complete(job);
|
52
|
+
block_job_complete(job, errp);
|
53
|
+
}
|
54
|
+
+#endif
|
55
|
+
|
56
|
+
void qmp___com_redhat_change_backing_file(const char *device,
|
57
|
+
const char *image_node_name,
|
58
|
+
diff --git a/hmp-commands.hx b/hmp-commands.hx
|
59
|
+
index 7e1855a..dd528d2 100644
|
60
|
+
--- a/hmp-commands.hx
|
61
|
+
+++ b/hmp-commands.hx
|
62
|
+
@@ -81,7 +81,6 @@ ETEXI
|
63
|
+
.help = "copy data from a backing file into a block device",
|
64
|
+
.mhandler.cmd = hmp_block_stream,
|
65
|
+
},
|
66
|
+
-#endif
|
67
|
+
|
68
|
+
STEXI
|
69
|
+
@item block_stream
|
70
|
+
@@ -160,6 +159,7 @@ STEXI
|
71
|
+
@findex block_job_resume
|
72
|
+
Resume a paused block streaming operation.
|
73
|
+
ETEXI
|
74
|
+
+#endif
|
75
|
+
|
76
|
+
{
|
77
|
+
.name = "eject",
|
78
|
+
diff --git a/hmp.c b/hmp.c
|
79
|
+
index e1d92f4..fb9b445 100644
|
80
|
+
--- a/hmp.c
|
81
|
+
+++ b/hmp.c
|
82
|
+
@@ -1053,7 +1053,6 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
|
83
|
+
|
84
|
+
hmp_handle_error(mon, &error);
|
85
|
+
}
|
86
|
+
-#endif
|
87
|
+
|
88
|
+
void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
|
89
|
+
{
|
90
|
+
@@ -1106,6 +1105,7 @@ void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
|
91
|
+
|
92
|
+
hmp_handle_error(mon, &error);
|
93
|
+
}
|
94
|
+
+#endif
|
95
|
+
|
96
|
+
typedef struct MigrationStatus
|
97
|
+
{
|
98
|
+
diff --git a/qapi-schema.json b/qapi-schema.json
|
99
|
+
index c8732c1..5138ed9 100644
|
100
|
+
--- a/qapi-schema.json
|
101
|
+
+++ b/qapi-schema.json
|
102
|
+
|
103
|
+
{ 'command': 'block-stream',
|
104
|
+
'data': { 'device': 'str', '*base': 'str', '*backing-file': 'str',
|
105
|
+
'*speed': 'int', '*on-error': 'BlockdevOnError' } }
|
106
|
+
-#_end-rhev-only
|
107
|
+
|
108
|
+
##
|
109
|
+
# @block-job-set-speed:
|
110
|
+
|
111
|
+
# Since: 1.3
|
112
|
+
##
|
113
|
+
{ 'command': 'block-job-complete', 'data': { 'device': 'str' } }
|
114
|
+
+#_end-rhev-only
|
115
|
+
|
116
|
+
##
|
117
|
+
# @ObjectTypeInfo:
|
118
|
+
diff --git a/qmp-commands.hx b/qmp-commands.hx
|
119
|
+
index 22a09be..9522c44 100644
|
120
|
+
--- a/qmp-commands.hx
|
121
|
+
+++ b/qmp-commands.hx
|
122
|
+
@@ -1089,8 +1089,6 @@ Example:
|
123
|
+
|
124
|
+
EQMP
|
125
|
+
|
126
|
+
-#endif
|
127
|
+
-
|
128
|
+
{
|
129
|
+
.name = "block-job-set-speed",
|
130
|
+
.args_type = "device:B,speed:o",
|
131
|
+
@@ -1117,7 +1115,6 @@ EQMP
|
132
|
+
.args_type = "device:B",
|
133
|
+
.mhandler.cmd_new = qmp_marshal_input_block_job_complete,
|
134
|
+
},
|
135
|
+
-#ifdef CONFIG_LIVE_BLOCK_OPS
|
136
|
+
{
|
137
|
+
.name = "transaction",
|
138
|
+
.args_type = "actions:q",
|
139
|
+
--
|
140
|
+
1.8.3.1
|
141
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
From 9452583824b50cb6f095c5ec1894b38df7b01175 Mon Sep 17 00:00:00 2001
|
2
|
+
Message-Id: <9452583824b50cb6f095c5ec1894b38df7b01175.1464449390.git.jen@redhat.com>
|
3
|
+
In-Reply-To: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
|
4
|
+
References: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
|
5
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
6
|
+
Date: Mon, 23 May 2016 11:28:41 -0400
|
7
|
+
Subject: [CHANGE 3/3] block/raw-posix: Open file descriptor O_RDWR to work
|
8
|
+
around glibc posix_fallocate emulation issue.
|
9
|
+
To: rhvirt-patches@redhat.com,
|
10
|
+
jen@redhat.com
|
11
|
+
|
12
|
+
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
13
|
+
Message-id: <1464002921-1079-2-git-send-email-kwolf@redhat.com>
|
14
|
+
Patchwork-id: 70425
|
15
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] block/raw-posix: Open file descriptor O_RDWR to work around glibc posix_fallocate emulation issue.
|
16
|
+
Bugzilla: 1268345
|
17
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
18
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
19
|
+
RH-Acked-by: Richard Jones <rjones@redhat.com>
|
20
|
+
|
21
|
+
From: "Richard W.M. Jones" <rjones@redhat.com>
|
22
|
+
|
23
|
+
The following command fails on an NFS mountpoint:
|
24
|
+
|
25
|
+
$ qemu-img create -f qcow2 -o preallocation=falloc disk.img 262144
|
26
|
+
Formatting 'disk.img', fmt=qcow2 size=262144 encryption=off cluster_size=65536 preallocation='falloc' lazy_refcounts=off
|
27
|
+
qemu-img: disk.img: Could not preallocate data for the new file: Bad file descriptor
|
28
|
+
|
29
|
+
The reason turns out to be because NFS doesn't support the
|
30
|
+
posix_fallocate call. glibc emulates it instead. However glibc's
|
31
|
+
emulation involves using the pread(2) syscall. The pread syscall
|
32
|
+
fails with EBADF if the file descriptor is opened without the read
|
33
|
+
open-flag (ie. open (..., O_WRONLY)).
|
34
|
+
|
35
|
+
I contacted glibc upstream about this, and their response is here:
|
36
|
+
|
37
|
+
https://bugzilla.redhat.com/show_bug.cgi?id=1265196#c9
|
38
|
+
|
39
|
+
There are two possible fixes: Use Linux fallocate directly, or (this
|
40
|
+
fix) work around the problem in qemu by opening the file with O_RDWR
|
41
|
+
instead of O_WRONLY.
|
42
|
+
|
43
|
+
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
|
44
|
+
Reviewed-by: Jeff Cody <jcody@redhat.com>
|
45
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
46
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
47
|
+
(cherry picked from commit 73ba05d936e82fe01b2b2cf987bf3aecb4792af5)
|
48
|
+
Signed-off-by: Jeff E. Nelson <jen@redhat.com>
|
49
|
+
---
|
50
|
+
block/raw-posix.c | 2 +-
|
51
|
+
1 file changed, 1 insertion(+), 1 deletion(-)
|
52
|
+
|
53
|
+
diff --git a/block/raw-posix.c b/block/raw-posix.c
|
54
|
+
index 1f5275f..92fcb6c 100644
|
55
|
+
--- a/block/raw-posix.c
|
56
|
+
+++ b/block/raw-posix.c
|
57
|
+
@@ -1265,7 +1265,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
|
58
|
+
options++;
|
59
|
+
}
|
60
|
+
|
61
|
+
- fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
|
62
|
+
+ fd = qemu_open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
|
63
|
+
0644);
|
64
|
+
if (fd < 0) {
|
65
|
+
result = -errno;
|
66
|
+
--
|
67
|
+
2.5.5
|
68
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
From 37bf9db781d9507501649ee04d23b0dab103a126 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:23 +0100
|
4
|
+
Subject: [PATCH 10/18] block: vmdk - fixed sizeof() error
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-11-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69176
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 10/18] block: vmdk - fixed sizeof() error
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
From: Jeff Cody <jcody@redhat.com>
|
16
|
+
|
17
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
18
|
+
|
19
|
+
The size compared should be PATH_MAX, rather than sizeof(char *).
|
20
|
+
|
21
|
+
Reported-by: Paolo Bonzini <pbonzini@redhat.com>
|
22
|
+
Signed-off-by: Jeff Cody <jcody@redhat.com>
|
23
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
24
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
25
|
+
Message-id: 46d873261433f4527e88885582f96942d61758d6.1423592487.git.jcody@redhat.com
|
26
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
27
|
+
(cherry picked from commit a7be17bee855f26c317e99aa6582e1dc9b8ebd71)
|
28
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
29
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
30
|
+
---
|
31
|
+
block/vmdk.c | 3 +--
|
32
|
+
1 file changed, 1 insertion(+), 2 deletions(-)
|
33
|
+
|
34
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
35
|
+
index 45ecf02..32b3d4c 100644
|
36
|
+
--- a/block/vmdk.c
|
37
|
+
+++ b/block/vmdk.c
|
38
|
+
@@ -838,8 +838,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
39
|
+
}
|
40
|
+
|
41
|
+
extent_path = g_malloc0(PATH_MAX);
|
42
|
+
- path_combine(extent_path, sizeof(extent_path),
|
43
|
+
- desc_file_path, fname);
|
44
|
+
+ path_combine(extent_path, PATH_MAX, desc_file_path, fname);
|
45
|
+
extent_file = NULL;
|
46
|
+
ret = bdrv_file_open(&extent_file, extent_path, NULL, bs->open_flags,
|
47
|
+
errp);
|
48
|
+
--
|
49
|
+
1.8.3.1
|
50
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
From 931d28d0c1c1015df16fbffb8422895497193a78 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:21 +0100
|
4
|
+
Subject: [PATCH 08/18] block: vmdk - make ret variable usage clear
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-9-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69174
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 08/18] block: vmdk - make ret variable usage clear
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
From: Jeff Cody <jcody@redhat.com>
|
16
|
+
|
17
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
18
|
+
|
19
|
+
Keep the variable 'ret' something that is returned by the function it is
|
20
|
+
defined in. For the return value of 'sscanf', use a more meaningful
|
21
|
+
variable name.
|
22
|
+
|
23
|
+
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
24
|
+
Reviewed-by: John Snow <jsnow@redhat.com>
|
25
|
+
Signed-off-by: Jeff Cody <jcody@redhat.com>
|
26
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
27
|
+
(cherry picked from commit 395a22fae064df64d987d703cf70ae0f57306be8)
|
28
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
29
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
30
|
+
---
|
31
|
+
block/vmdk.c | 14 ++++++++------
|
32
|
+
1 file changed, 8 insertions(+), 6 deletions(-)
|
33
|
+
|
34
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
35
|
+
index 1247ea4..3351782 100644
|
36
|
+
--- a/block/vmdk.c
|
37
|
+
+++ b/block/vmdk.c
|
38
|
+
@@ -788,6 +788,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
39
|
+
const char *desc_file_path, Error **errp)
|
40
|
+
{
|
41
|
+
int ret;
|
42
|
+
+ int matches;
|
43
|
+
char access[11];
|
44
|
+
char type[11];
|
45
|
+
char fname[512];
|
46
|
+
@@ -799,6 +800,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
47
|
+
BDRVVmdkState *s = bs->opaque;
|
48
|
+
VmdkExtent *extent;
|
49
|
+
|
50
|
+
+
|
51
|
+
while (*p) {
|
52
|
+
/* parse extent line in one of below formats:
|
53
|
+
*
|
54
|
+
@@ -808,23 +810,23 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
55
|
+
* RW [size in sectors] VMFSSPARSE "file-name.vmdk"
|
56
|
+
*/
|
57
|
+
flat_offset = -1;
|
58
|
+
- ret = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
|
59
|
+
- access, §ors, type, fname, &flat_offset);
|
60
|
+
- if (ret < 4 || strcmp(access, "RW")) {
|
61
|
+
+ matches = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
|
62
|
+
+ access, §ors, type, fname, &flat_offset);
|
63
|
+
+ if (matches < 4 || strcmp(access, "RW")) {
|
64
|
+
goto next_line;
|
65
|
+
} else if (!strcmp(type, "FLAT")) {
|
66
|
+
- if (ret != 5 || flat_offset < 0) {
|
67
|
+
+ if (matches != 5 || flat_offset < 0) {
|
68
|
+
error_setg(errp, "Invalid extent lines: \n%s", p);
|
69
|
+
return -EINVAL;
|
70
|
+
}
|
71
|
+
} else if (!strcmp(type, "VMFS")) {
|
72
|
+
- if (ret == 4) {
|
73
|
+
+ if (matches == 4) {
|
74
|
+
flat_offset = 0;
|
75
|
+
} else {
|
76
|
+
error_setg(errp, "Invalid extent lines:\n%s", p);
|
77
|
+
return -EINVAL;
|
78
|
+
}
|
79
|
+
- } else if (ret != 4) {
|
80
|
+
+ } else if (matches != 4) {
|
81
|
+
error_setg(errp, "Invalid extent lines:\n%s", p);
|
82
|
+
return -EINVAL;
|
83
|
+
}
|
84
|
+
--
|
85
|
+
1.8.3.1
|
86
|
+
|
@@ -0,0 +1,146 @@
|
|
1
|
+
From a767838caf6c761d714a9466d008f8dddaf1a162 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:22 +0100
|
4
|
+
Subject: [PATCH 09/18] block: vmdk - move string allocations from stack to the
|
5
|
+
heap
|
6
|
+
|
7
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
8
|
+
Message-id: <1455528511-9357-10-git-send-email-famz@redhat.com>
|
9
|
+
Patchwork-id: 69175
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 09/18] block: vmdk - move string allocations from stack to the heap
|
11
|
+
Bugzilla: 1299250
|
12
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
15
|
+
|
16
|
+
From: Jeff Cody <jcody@redhat.com>
|
17
|
+
|
18
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
19
|
+
|
20
|
+
Functions 'vmdk_parse_extents' and 'vmdk_create' allocate several
|
21
|
+
PATH_MAX sized arrays on the stack. Make these dynamically allocated.
|
22
|
+
|
23
|
+
Signed-off-by: Jeff Cody <jcody@redhat.com>
|
24
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
25
|
+
(cherry picked from commit fe2065629a9c256f836770ca54449ae77b22d188)
|
26
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
27
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
28
|
+
---
|
29
|
+
block/vmdk.c | 40 ++++++++++++++++++++++++----------------
|
30
|
+
1 file changed, 24 insertions(+), 16 deletions(-)
|
31
|
+
|
32
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
33
|
+
index 3351782..45ecf02 100644
|
34
|
+
--- a/block/vmdk.c
|
35
|
+
+++ b/block/vmdk.c
|
36
|
+
@@ -795,12 +795,11 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
37
|
+
const char *p = desc;
|
38
|
+
int64_t sectors = 0;
|
39
|
+
int64_t flat_offset;
|
40
|
+
- char extent_path[PATH_MAX];
|
41
|
+
+ char *extent_path;
|
42
|
+
BlockDriverState *extent_file;
|
43
|
+
BDRVVmdkState *s = bs->opaque;
|
44
|
+
VmdkExtent *extent;
|
45
|
+
|
46
|
+
-
|
47
|
+
while (*p) {
|
48
|
+
/* parse extent line in one of below formats:
|
49
|
+
*
|
50
|
+
@@ -838,10 +837,13 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
51
|
+
goto next_line;
|
52
|
+
}
|
53
|
+
|
54
|
+
+ extent_path = g_malloc0(PATH_MAX);
|
55
|
+
path_combine(extent_path, sizeof(extent_path),
|
56
|
+
desc_file_path, fname);
|
57
|
+
+ extent_file = NULL;
|
58
|
+
ret = bdrv_file_open(&extent_file, extent_path, NULL, bs->open_flags,
|
59
|
+
errp);
|
60
|
+
+ g_free(extent_path);
|
61
|
+
if (ret) {
|
62
|
+
return ret;
|
63
|
+
}
|
64
|
+
@@ -1790,10 +1792,15 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
|
65
|
+
int ret = 0;
|
66
|
+
bool flat, split, compress;
|
67
|
+
GString *ext_desc_lines;
|
68
|
+
- char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
|
69
|
+
+ char *path = g_malloc0(PATH_MAX);
|
70
|
+
+ char *prefix = g_malloc0(PATH_MAX);
|
71
|
+
+ char *postfix = g_malloc0(PATH_MAX);
|
72
|
+
+ char *desc_line = g_malloc0(BUF_SIZE);
|
73
|
+
+ char *ext_filename = g_malloc0(PATH_MAX);
|
74
|
+
+ char *desc_filename = g_malloc0(PATH_MAX);
|
75
|
+
const int64_t split_size = 0x80000000; /* VMDK has constant split size */
|
76
|
+
const char *desc_extent_line;
|
77
|
+
- char parent_desc_line[BUF_SIZE] = "";
|
78
|
+
+ char *parent_desc_line = g_malloc0(BUF_SIZE);
|
79
|
+
uint32_t parent_cid = 0xffffffff;
|
80
|
+
uint32_t number_heads = 16;
|
81
|
+
bool zeroed_grain = false;
|
82
|
+
@@ -1902,33 +1909,27 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
|
83
|
+
}
|
84
|
+
parent_cid = vmdk_read_cid(bs, 0);
|
85
|
+
bdrv_unref(bs);
|
86
|
+
- snprintf(parent_desc_line, sizeof(parent_desc_line),
|
87
|
+
+ snprintf(parent_desc_line, BUF_SIZE,
|
88
|
+
"parentFileNameHint=\"%s\"", backing_file);
|
89
|
+
}
|
90
|
+
|
91
|
+
/* Create extents */
|
92
|
+
filesize = total_size;
|
93
|
+
while (filesize > 0) {
|
94
|
+
- char desc_line[BUF_SIZE];
|
95
|
+
- char ext_filename[PATH_MAX];
|
96
|
+
- char desc_filename[PATH_MAX];
|
97
|
+
int64_t size = filesize;
|
98
|
+
|
99
|
+
if (split && size > split_size) {
|
100
|
+
size = split_size;
|
101
|
+
}
|
102
|
+
if (split) {
|
103
|
+
- snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s",
|
104
|
+
+ snprintf(desc_filename, PATH_MAX, "%s-%c%03d%s",
|
105
|
+
prefix, flat ? 'f' : 's', ++idx, postfix);
|
106
|
+
} else if (flat) {
|
107
|
+
- snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s",
|
108
|
+
- prefix, postfix);
|
109
|
+
+ snprintf(desc_filename, PATH_MAX, "%s-flat%s", prefix, postfix);
|
110
|
+
} else {
|
111
|
+
- snprintf(desc_filename, sizeof(desc_filename), "%s%s",
|
112
|
+
- prefix, postfix);
|
113
|
+
+ snprintf(desc_filename, PATH_MAX, "%s%s", prefix, postfix);
|
114
|
+
}
|
115
|
+
- snprintf(ext_filename, sizeof(ext_filename), "%s%s",
|
116
|
+
- path, desc_filename);
|
117
|
+
+ snprintf(ext_filename, PATH_MAX, "%s%s", path, desc_filename);
|
118
|
+
|
119
|
+
if (vmdk_create_extent(ext_filename, size,
|
120
|
+
flat, compress, zeroed_grain, errp)) {
|
121
|
+
@@ -1938,7 +1939,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
|
122
|
+
filesize -= size;
|
123
|
+
|
124
|
+
/* Format description line */
|
125
|
+
- snprintf(desc_line, sizeof(desc_line),
|
126
|
+
+ snprintf(desc_line, BUF_SIZE,
|
127
|
+
desc_extent_line, size / BDRV_SECTOR_SIZE, desc_filename);
|
128
|
+
g_string_append(ext_desc_lines, desc_line);
|
129
|
+
}
|
130
|
+
@@ -1988,6 +1989,13 @@ exit:
|
131
|
+
bdrv_unref(new_bs);
|
132
|
+
}
|
133
|
+
g_free(desc);
|
134
|
+
+ g_free(path);
|
135
|
+
+ g_free(prefix);
|
136
|
+
+ g_free(postfix);
|
137
|
+
+ g_free(desc_line);
|
138
|
+
+ g_free(ext_filename);
|
139
|
+
+ g_free(desc_filename);
|
140
|
+
+ g_free(parent_desc_line);
|
141
|
+
g_string_free(ext_desc_lines, true);
|
142
|
+
return ret;
|
143
|
+
}
|
144
|
+
--
|
145
|
+
1.8.3.1
|
146
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
From 38d4fe12ad2e3bc18842201f437c480120eace2b Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:02 +0200
|
4
|
+
Subject: [PATCH 04/16] check-qjson: Add test for JSON nesting depth limit
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-6-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71481
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 04/15] check-qjson: Add test for JSON nesting depth limit
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
This would have prevented the regression mentioned in the previous
|
16
|
+
commit.
|
17
|
+
|
18
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
19
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
20
|
+
Message-Id: <1448486613-17634-4-git-send-email-armbru@redhat.com>
|
21
|
+
(cherry picked from commit f0ae0304c7a41a42b7d4a6cde450da938d3c2cc7)
|
22
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
23
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
24
|
+
---
|
25
|
+
tests/check-qjson.c | 25 +++++++++++++++++++++++++
|
26
|
+
1 file changed, 25 insertions(+)
|
27
|
+
|
28
|
+
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
|
29
|
+
index 4e74548..c5dd74d 100644
|
30
|
+
--- a/tests/check-qjson.c
|
31
|
+
+++ b/tests/check-qjson.c
|
32
|
+
@@ -1465,6 +1465,30 @@ static void unterminated_literal(void)
|
33
|
+
g_assert(obj == NULL);
|
34
|
+
}
|
35
|
+
|
36
|
+
+static char *make_nest(char *buf, size_t cnt)
|
37
|
+
+{
|
38
|
+
+ memset(buf, '[', cnt - 1);
|
39
|
+
+ buf[cnt - 1] = '{';
|
40
|
+
+ buf[cnt] = '}';
|
41
|
+
+ memset(buf + cnt + 1, ']', cnt - 1);
|
42
|
+
+ buf[2 * cnt] = 0;
|
43
|
+
+ return buf;
|
44
|
+
+}
|
45
|
+
+
|
46
|
+
+static void limits_nesting(void)
|
47
|
+
+{
|
48
|
+
+ enum { max_nesting = 1024 }; /* see qobject/json-streamer.c */
|
49
|
+
+ char buf[2 * (max_nesting + 1) + 1];
|
50
|
+
+ QObject *obj;
|
51
|
+
+
|
52
|
+
+ obj = qobject_from_json(make_nest(buf, max_nesting));
|
53
|
+
+ g_assert(obj != NULL);
|
54
|
+
+ qobject_decref(obj);
|
55
|
+
+
|
56
|
+
+ obj = qobject_from_json(make_nest(buf, max_nesting + 1));
|
57
|
+
+ g_assert(obj == NULL);
|
58
|
+
+}
|
59
|
+
+
|
60
|
+
int main(int argc, char **argv)
|
61
|
+
{
|
62
|
+
g_test_init(&argc, &argv, NULL);
|
63
|
+
@@ -1500,6 +1524,7 @@ int main(int argc, char **argv)
|
64
|
+
g_test_add_func("/errors/invalid_array_comma", invalid_array_comma);
|
65
|
+
g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma);
|
66
|
+
g_test_add_func("/errors/unterminated/literal", unterminated_literal);
|
67
|
+
+ g_test_add_func("/errors/limits/nesting", limits_nesting);
|
68
|
+
|
69
|
+
return g_test_run();
|
70
|
+
}
|
71
|
+
--
|
72
|
+
1.8.3.1
|
73
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
From b7cea737b24456765a21ed43ebd9b68ebbbf3537 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:21 +0100
|
4
|
+
Subject: [PATCH 02/27] cutils: Support 'P' and 'E' suffixes in strtosz()
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-3-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68430
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 02/21] cutils: Support 'P' and 'E' suffixes in strtosz()
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
18
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
19
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
20
|
+
(cherry picked from commit 5e00984aef7c1c317e27c0e8acf66526513c770f)
|
21
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
22
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
23
|
+
---
|
24
|
+
include/qemu-common.h | 2 ++
|
25
|
+
monitor.c | 8 ++++----
|
26
|
+
qemu-img.c | 10 ++++++----
|
27
|
+
tests/qemu-iotests/049.out | 8 ++++----
|
28
|
+
util/cutils.c | 4 ++++
|
29
|
+
5 files changed, 20 insertions(+), 12 deletions(-)
|
30
|
+
|
31
|
+
diff --git a/include/qemu-common.h b/include/qemu-common.h
|
32
|
+
index aee85e3..67f57c9 100644
|
33
|
+
--- a/include/qemu-common.h
|
34
|
+
+++ b/include/qemu-common.h
|
35
|
+
@@ -178,6 +178,8 @@ int parse_uint_full(const char *s, unsigned long long *value, int base);
|
36
|
+
* A-Z, as strtosz() will use qemu_toupper() on the given argument
|
37
|
+
* prior to comparison.
|
38
|
+
*/
|
39
|
+
+#define STRTOSZ_DEFSUFFIX_EB 'E'
|
40
|
+
+#define STRTOSZ_DEFSUFFIX_PB 'P'
|
41
|
+
#define STRTOSZ_DEFSUFFIX_TB 'T'
|
42
|
+
#define STRTOSZ_DEFSUFFIX_GB 'G'
|
43
|
+
#define STRTOSZ_DEFSUFFIX_MB 'M'
|
44
|
+
diff --git a/monitor.c b/monitor.c
|
45
|
+
index 6a1d06e..33c5bc8 100644
|
46
|
+
--- a/monitor.c
|
47
|
+
+++ b/monitor.c
|
48
|
+
|
49
|
+
* 'M' Non-negative target long (32 or 64 bit), in user mode the
|
50
|
+
* value is multiplied by 2^20 (think Mebibyte)
|
51
|
+
* 'o' octets (aka bytes)
|
52
|
+
- * user mode accepts an optional T, t, G, g, M, m, K, k
|
53
|
+
- * suffix, which multiplies the value by 2^40 for
|
54
|
+
- * suffixes T and t, 2^30 for suffixes G and g, 2^20 for
|
55
|
+
- * M and m, 2^10 for K and k
|
56
|
+
+ * user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
|
57
|
+
+ * K, k suffix, which multiplies the value by 2^60 for suffixes E
|
58
|
+
+ * and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
|
59
|
+
+ * 2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
|
60
|
+
* 'T' double
|
61
|
+
* user mode accepts an optional ms, us, ns suffix,
|
62
|
+
* which divides the value by 1e3, 1e6, 1e9, respectively
|
63
|
+
diff --git a/qemu-img.c b/qemu-img.c
|
64
|
+
index 9c021e7..eb2d4cb 100644
|
65
|
+
--- a/qemu-img.c
|
66
|
+
+++ b/qemu-img.c
|
67
|
+
@@ -87,8 +87,9 @@ static void help(void)
|
68
|
+
" 'src_cache' is the cache mode used to read input disk images, the valid\n"
|
69
|
+
" options are the same as for the 'cache' option\n"
|
70
|
+
" 'size' is the disk image size in bytes. Optional suffixes\n"
|
71
|
+
- " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
|
72
|
+
- " and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
|
73
|
+
+ " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M),\n"
|
74
|
+
+ " 'T' (terabyte, 1024G), 'P' (petabyte, 1024T) and 'E' (exabyte, 1024P) are\n"
|
75
|
+
+ " supported. 'b' is ignored.\n"
|
76
|
+
" 'output_filename' is the destination disk image filename\n"
|
77
|
+
" 'output_fmt' is the destination format\n"
|
78
|
+
" 'options' is a comma separated list of format specific options in a\n"
|
79
|
+
@@ -417,8 +418,9 @@ static int img_create(int argc, char **argv)
|
80
|
+
error_report("Image size must be less than 8 EiB!");
|
81
|
+
} else {
|
82
|
+
error_report("Invalid image size specified! You may use k, M, "
|
83
|
+
- "G or T suffixes for ");
|
84
|
+
- error_report("kilobytes, megabytes, gigabytes and terabytes.");
|
85
|
+
+ "G, T, P or E suffixes for ");
|
86
|
+
+ error_report("kilobytes, megabytes, gigabytes, terabytes, "
|
87
|
+
+ "petabytes and exabytes.");
|
88
|
+
}
|
89
|
+
goto fail;
|
90
|
+
}
|
91
|
+
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
|
92
|
+
index b2fcf0b..3e56772 100644
|
93
|
+
--- a/tests/qemu-iotests/049.out
|
94
|
+
+++ b/tests/qemu-iotests/049.out
|
95
|
+
@@ -108,15 +108,15 @@ qemu-img: TEST_DIR/t.qcow2: Could not resize image: Operation not supported
|
96
|
+
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=-1024 encryption=off cluster_size=65536 lazy_refcounts=off
|
97
|
+
|
98
|
+
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte
|
99
|
+
-qemu-img: Invalid image size specified! You may use k, M, G or T suffixes for
|
100
|
+
-qemu-img: kilobytes, megabytes, gigabytes and terabytes.
|
101
|
+
+qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
|
102
|
+
+qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
|
103
|
+
|
104
|
+
qemu-img create -f qcow2 -o size=1kilobyte TEST_DIR/t.qcow2
|
105
|
+
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off
|
106
|
+
|
107
|
+
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- foobar
|
108
|
+
-qemu-img: Invalid image size specified! You may use k, M, G or T suffixes for
|
109
|
+
-qemu-img: kilobytes, megabytes, gigabytes and terabytes.
|
110
|
+
+qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
|
111
|
+
+qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
|
112
|
+
|
113
|
+
qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2
|
114
|
+
qemu-img: Parameter 'size' expects a size
|
115
|
+
diff --git a/util/cutils.c b/util/cutils.c
|
116
|
+
index a165819..8f28896 100644
|
117
|
+
--- a/util/cutils.c
|
118
|
+
+++ b/util/cutils.c
|
119
|
+
@@ -267,6 +267,10 @@ static int64_t suffix_mul(char suffix, int64_t unit)
|
120
|
+
return unit * unit * unit;
|
121
|
+
case STRTOSZ_DEFSUFFIX_TB:
|
122
|
+
return unit * unit * unit * unit;
|
123
|
+
+ case STRTOSZ_DEFSUFFIX_PB:
|
124
|
+
+ return unit * unit * unit * unit * unit;
|
125
|
+
+ case STRTOSZ_DEFSUFFIX_EB:
|
126
|
+
+ return unit * unit * unit * unit * unit * unit;
|
127
|
+
}
|
128
|
+
return -1;
|
129
|
+
}
|
130
|
+
--
|
131
|
+
1.8.3.1
|
132
|
+
|
@@ -0,0 +1,109 @@
|
|
1
|
+
From 4fef3479339001ef3ea529fb0552533fae422240 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Laszlo Ersek <lersek@redhat.com>
|
3
|
+
Date: Fri, 5 Feb 2016 14:26:18 +0100
|
4
|
+
Subject: [PATCH 1/5] e1000: eliminate infinite loops on out-of-bounds transfer
|
5
|
+
start
|
6
|
+
|
7
|
+
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
8
|
+
Message-id: <1454682378-29144-2-git-send-email-lersek@redhat.com>
|
9
|
+
Patchwork-id: 69116
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] e1000: eliminate infinite loops on out-of-bounds transfer start
|
11
|
+
Bugzilla: 1296044
|
12
|
+
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
|
13
|
+
RH-Acked-by: P J P <ppandit@redhat.com>
|
14
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
15
|
+
|
16
|
+
The start_xmit() and e1000_receive_iov() functions implement DMA transfers
|
17
|
+
iterating over a set of descriptors that the guest's e1000 driver
|
18
|
+
prepares:
|
19
|
+
|
20
|
+
- the TDLEN and RDLEN registers store the total size of the descriptor
|
21
|
+
area,
|
22
|
+
|
23
|
+
- while the TDH and RDH registers store the offset (in whole tx / rx
|
24
|
+
descriptors) into the area where the transfer is supposed to start.
|
25
|
+
|
26
|
+
Each time a descriptor is processed, the TDH and RDH register is bumped
|
27
|
+
(as appropriate for the transfer direction).
|
28
|
+
|
29
|
+
QEMU already contains logic to deal with bogus transfers submitted by the
|
30
|
+
guest:
|
31
|
+
|
32
|
+
- Normally, the transmit case wants to increase TDH from its initial value
|
33
|
+
to TDT. (TDT is allowed to be numerically smaller than the initial TDH
|
34
|
+
value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe
|
35
|
+
that QEMU currently has here is a check against reaching the original
|
36
|
+
TDH value again -- a complete wraparound, which should never happen.
|
37
|
+
|
38
|
+
- In the receive case RDH is increased from its initial value until
|
39
|
+
"total_size" bytes have been received; preferably in a single step, or
|
40
|
+
in "s->rxbuf_size" byte steps, if the latter is smaller. However, null
|
41
|
+
RX descriptors are skipped without receiving data, while RDH is
|
42
|
+
incremented just the same. QEMU tries to prevent an infinite loop
|
43
|
+
(processing only null RX descriptors) by detecting whether RDH assumes
|
44
|
+
its original value during the loop. (Again, wrapping from RDLEN to 0 is
|
45
|
+
normal.)
|
46
|
+
|
47
|
+
What both directions miss is that the guest could program TDLEN and RDLEN
|
48
|
+
so low, and the initial TDH and RDH so high, that these registers will
|
49
|
+
immediately be truncated to zero, and then never reassume their initial
|
50
|
+
values in the loop -- a full wraparound will never occur.
|
51
|
+
|
52
|
+
The condition that expresses this is:
|
53
|
+
|
54
|
+
xdh_start >= s->mac_reg[XDLEN] / sizeof(desc)
|
55
|
+
|
56
|
+
i.e., TDH or RDH start out after the last whole rx or tx descriptor that
|
57
|
+
fits into the TDLEN or RDLEN sized area.
|
58
|
+
|
59
|
+
This condition could be checked before we enter the loops, but
|
60
|
+
pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for
|
61
|
+
bogus DMA addresses, so we just extend the existing failsafes with the
|
62
|
+
above condition.
|
63
|
+
|
64
|
+
This is CVE-2016-1981.
|
65
|
+
|
66
|
+
Cc: "Michael S. Tsirkin" <mst@redhat.com>
|
67
|
+
Cc: Petr Matousek <pmatouse@redhat.com>
|
68
|
+
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
|
69
|
+
Cc: Prasad Pandit <ppandit@redhat.com>
|
70
|
+
Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
|
71
|
+
Cc: Jason Wang <jasowang@redhat.com>
|
72
|
+
Cc: qemu-stable@nongnu.org
|
73
|
+
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044
|
74
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
75
|
+
Reviewed-by: Jason Wang <jasowang@redhat.com>
|
76
|
+
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
77
|
+
(cherry picked from commit dd793a74882477ca38d49e191110c17dfee51dcc)
|
78
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
79
|
+
---
|
80
|
+
hw/net/e1000.c | 6 ++++--
|
81
|
+
1 file changed, 4 insertions(+), 2 deletions(-)
|
82
|
+
|
83
|
+
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
|
84
|
+
index 87a84a7..2cd38bc 100644
|
85
|
+
--- a/hw/net/e1000.c
|
86
|
+
+++ b/hw/net/e1000.c
|
87
|
+
@@ -697,7 +697,8 @@ start_xmit(E1000State *s)
|
88
|
+
* bogus values to TDT/TDLEN.
|
89
|
+
* there's nothing too intelligent we could do about this.
|
90
|
+
*/
|
91
|
+
- if (s->mac_reg[TDH] == tdh_start) {
|
92
|
+
+ if (s->mac_reg[TDH] == tdh_start ||
|
93
|
+
+ tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) {
|
94
|
+
DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
|
95
|
+
tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
|
96
|
+
break;
|
97
|
+
@@ -902,7 +903,8 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
98
|
+
if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
|
99
|
+
s->mac_reg[RDH] = 0;
|
100
|
+
/* see comment in start_xmit; same here */
|
101
|
+
- if (s->mac_reg[RDH] == rdh_start) {
|
102
|
+
+ if (s->mac_reg[RDH] == rdh_start ||
|
103
|
+
+ rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) {
|
104
|
+
DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
|
105
|
+
rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
|
106
|
+
set_ics(s, 0, E1000_ICS_RXO);
|
107
|
+
--
|
108
|
+
1.8.3.1
|
109
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
From ad3f6b5b188c572bd07cc5929e844138c2d95915 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
+
Date: Fri, 13 Nov 2015 13:32:34 +0100
|
4
|
+
Subject: [PATCH 1/6] ehci: clear suspend bit on detach
|
5
|
+
|
6
|
+
Message-id: <1447421554-28366-2-git-send-email-kraxel@redhat.com>
|
7
|
+
Patchwork-id: 68349
|
8
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] ehci: clear suspend bit on detach
|
9
|
+
Bugzilla: 1268879
|
10
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
11
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
|
14
|
+
When a device is detached, clear the suspend bit (PORTSC_SUSPEND)
|
15
|
+
in the port status register.
|
16
|
+
|
17
|
+
The specs are not *that* clear what is supposed to happen in case
|
18
|
+
a suspended device is unplugged. But the enable bit (PORTSC_PED)
|
19
|
+
is cleared, and the specs mention setting suspend with enable being
|
20
|
+
unset is undefined behavior. So clearing them both looks reasonable,
|
21
|
+
and it actually fixes the reported bug.
|
22
|
+
|
23
|
+
Cc: Hans de Goede <hdegoede@redhat.com>
|
24
|
+
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
25
|
+
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
|
26
|
+
Message-id: 1445413462-18004-1-git-send-email-kraxel@redhat.com
|
27
|
+
(cherry picked from commit cbf82fa01e6fd4ecb234b235b10ffce548154a95)
|
28
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
29
|
+
---
|
30
|
+
hw/usb/hcd-ehci.c | 2 +-
|
31
|
+
1 file changed, 1 insertion(+), 1 deletion(-)
|
32
|
+
|
33
|
+
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
|
34
|
+
index 02d2ab7..3429c77 100644
|
35
|
+
--- a/hw/usb/hcd-ehci.c
|
36
|
+
+++ b/hw/usb/hcd-ehci.c
|
37
|
+
@@ -802,7 +802,7 @@ static void ehci_detach(USBPort *port)
|
38
|
+
ehci_queues_rip_device(s, port->dev, 0);
|
39
|
+
ehci_queues_rip_device(s, port->dev, 1);
|
40
|
+
|
41
|
+
- *portsc &= ~(PORTSC_CONNECT|PORTSC_PED);
|
42
|
+
+ *portsc &= ~(PORTSC_CONNECT|PORTSC_PED|PORTSC_SUSPEND);
|
43
|
+
*portsc |= PORTSC_CSC;
|
44
|
+
|
45
|
+
ehci_raise_irq(s, USBSTS_PCD);
|
46
|
+
--
|
47
|
+
1.8.3.1
|
48
|
+
|
@@ -1,16 +1,17 @@
|
|
1
|
-
From
|
1
|
+
From ba24567fd90702ea40ff320a79bc921b38510f22 Mon Sep 17 00:00:00 2001
|
2
2
|
From: Miroslav Rezanina <mrezanin@redhat.com>
|
3
3
|
Date: Thu, 21 Jan 2016 07:17:43 +0100
|
4
|
-
Subject: [PATCH] fw_cfg: add check to validate current entry value
|
4
|
+
Subject: [PATCH 2/2] fw_cfg: add check to validate current entry value
|
5
5
|
(CVE-2016-1714)
|
6
6
|
MIME-Version: 1.0
|
7
7
|
Content-Type: text/plain; charset=UTF-8
|
8
8
|
Content-Transfer-Encoding: 8bit
|
9
9
|
|
10
|
+
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
|
10
11
|
Message-id: <1453360663-5066-1-git-send-email-mrezanin@redhat.com>
|
11
12
|
Patchwork-id: 68834
|
12
13
|
O-Subject: [RHEL-7.2.z/RHEL-7.3 qemu-kvm PATCH] fw_cfg: add check to validate current entry value (CVE-2016-1714)
|
13
|
-
Bugzilla:
|
14
|
+
Bugzilla: 1298048
|
14
15
|
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
15
16
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
16
17
|
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
|
@@ -0,0 +1,50 @@
|
|
1
|
+
From 61ecb3c995018bc9ec901d376004c1d092d166ff Mon Sep 17 00:00:00 2001
|
2
|
+
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
+
Date: Wed, 1 Jun 2016 12:24:01 +0200
|
4
|
+
Subject: [PATCH 1/3] hw/input/hid.c Fix capslock hid code
|
5
|
+
|
6
|
+
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
+
Message-id: <1464783841-27701-2-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 70522
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] hw/input/hid.c Fix capslock hid code
|
10
|
+
Bugzilla: 1256741
|
11
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
12
|
+
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
13
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
14
|
+
|
15
|
+
From: Dinar Valeev <dvaleev@suse.com>
|
16
|
+
|
17
|
+
When ever USB keyboard is used, e.g. '-usbdevice keyboard' pressing
|
18
|
+
caps lock key send 0x32 hid code, which is treated as backslash.
|
19
|
+
Instead it should be 0x39 code. This affects sending uppercase keys,
|
20
|
+
as they typed whith caps lock active.
|
21
|
+
|
22
|
+
While on x86 this can be workarounded by using ps/2 protocol. On
|
23
|
+
Power it is crusial as we don't have anything else than USB.
|
24
|
+
|
25
|
+
This is fixes guest automation tasts over vnc.
|
26
|
+
|
27
|
+
Signed-off-by: Dinar Valeev <dvaleev@suse.com>
|
28
|
+
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
29
|
+
(cherry picked from commit 0ee4de5840ccc1072459ec68062bfb63c888a94d)
|
30
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
31
|
+
---
|
32
|
+
hw/input/hid.c | 2 +-
|
33
|
+
1 file changed, 1 insertion(+), 1 deletion(-)
|
34
|
+
|
35
|
+
diff --git a/hw/input/hid.c b/hw/input/hid.c
|
36
|
+
index 14b3125..db45c89 100644
|
37
|
+
--- a/hw/input/hid.c
|
38
|
+
+++ b/hw/input/hid.c
|
39
|
+
@@ -41,7 +41,7 @@ static const uint8_t hid_usage_keys[0x100] = {
|
40
|
+
0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
|
41
|
+
0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
|
42
|
+
0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
|
43
|
+
- 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
|
44
|
+
+ 0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
|
45
|
+
0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
|
46
|
+
0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
|
47
|
+
0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
|
48
|
+
--
|
49
|
+
1.8.3.1
|
50
|
+
|
@@ -0,0 +1,113 @@
|
|
1
|
+
From 31ce74359a069be69af0f6ba2f7867ed2083317a Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Tue, 8 Dec 2015 20:30:59 +0100
|
4
|
+
Subject: [PATCH 21/27] ide-test: fix failure for test_flush
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1449606659-23710-1-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68521
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v3 21/21] ide-test: fix failure for test_flush
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
This patch is a combination of two patches:
|
16
|
+
|
17
|
+
(1) Revert "qtest/ide-test: disable flush-test"
|
18
|
+
(2) ide-test: fix failure for test_flush
|
19
|
+
|
20
|
+
First, the downstream-only revert:
|
21
|
+
This reverts commit 228e49fabffa644ab7a6a03e98205f293115dc89.
|
22
|
+
|
23
|
+
Second, the backported fix:
|
24
|
+
|
25
|
+
bd07684aacfb61668ae2c25b7dd00b64f3d7c7f3 added a test to ensure BSY
|
26
|
+
flag is set when a flush request is in flight. It does this by setting
|
27
|
+
a blkdebug breakpoint on flush_to_os before issuing a CMD_FLUSH_CACHE.
|
28
|
+
It then resumes CMD_FLUSH_CACHE operation and checks that BSY is unset.
|
29
|
+
|
30
|
+
The actual unsetting of BSY does not occur until ide_flush_cb gets
|
31
|
+
called in a bh, however, so in some cases this check will race with
|
32
|
+
the actual completion.
|
33
|
+
|
34
|
+
Fix this by polling the ide status register until BSY flag gets unset
|
35
|
+
before we do our final sanity checks. According to
|
36
|
+
f68ec8379e88502b4841a110c070e9b118d3151c this is in line with how a guest
|
37
|
+
would determine whether or not the device is still busy.
|
38
|
+
|
39
|
+
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
40
|
+
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
41
|
+
(cherry picked from commit 22bfa16ed3d4c9d534dcfe6f2381a654f32296b9)
|
42
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
43
|
+
---
|
44
|
+
tests/ide-test.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
45
|
+
1 file changed, 41 insertions(+)
|
46
|
+
|
47
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
48
|
+
---
|
49
|
+
tests/ide-test.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
50
|
+
1 file changed, 41 insertions(+)
|
51
|
+
|
52
|
+
diff --git a/tests/ide-test.c b/tests/ide-test.c
|
53
|
+
index 43b7fd6..92dd0e5 100644
|
54
|
+
--- a/tests/ide-test.c
|
55
|
+
+++ b/tests/ide-test.c
|
56
|
+
@@ -425,6 +425,46 @@ static void test_identify(void)
|
57
|
+
ide_test_quit();
|
58
|
+
}
|
59
|
+
|
60
|
+
+static void test_flush(void)
|
61
|
+
+{
|
62
|
+
+ uint8_t data;
|
63
|
+
+
|
64
|
+
+ ide_test_start(
|
65
|
+
+ "-vnc none "
|
66
|
+
+ "-drive file=blkdebug::%s,if=ide,cache=writeback",
|
67
|
+
+ tmp_path);
|
68
|
+
+
|
69
|
+
+ /* Delay the completion of the flush request until we explicitly do it */
|
70
|
+
+ qmp("{'execute':'human-monitor-command', 'arguments': { "
|
71
|
+
+ "'command-line': 'qemu-io ide0-hd0 \"break flush_to_os A\"'} }");
|
72
|
+
+
|
73
|
+
+ /* FLUSH CACHE command on device 0*/
|
74
|
+
+ outb(IDE_BASE + reg_device, 0);
|
75
|
+
+ outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
|
76
|
+
+
|
77
|
+
+ /* Check status while request is in flight*/
|
78
|
+
+ data = inb(IDE_BASE + reg_status);
|
79
|
+
+ assert_bit_set(data, BSY | DRDY);
|
80
|
+
+ assert_bit_clear(data, DF | ERR | DRQ);
|
81
|
+
+
|
82
|
+
+ /* Complete the command */
|
83
|
+
+ qmp("{'execute':'human-monitor-command', 'arguments': { "
|
84
|
+
+ "'command-line': 'qemu-io ide0-hd0 \"resume A\"'} }");
|
85
|
+
+
|
86
|
+
+ /* Check registers */
|
87
|
+
+ data = inb(IDE_BASE + reg_device);
|
88
|
+
+ g_assert_cmpint(data & DEV, ==, 0);
|
89
|
+
+
|
90
|
+
+ do {
|
91
|
+
+ data = inb(IDE_BASE + reg_status);
|
92
|
+
+ } while (data & BSY);
|
93
|
+
+
|
94
|
+
+ assert_bit_set(data, DRDY);
|
95
|
+
+ assert_bit_clear(data, BSY | DF | ERR | DRQ);
|
96
|
+
+
|
97
|
+
+ ide_test_quit();
|
98
|
+
+}
|
99
|
+
+
|
100
|
+
static void test_flush_nodev(void)
|
101
|
+
{
|
102
|
+
ide_test_start("");
|
103
|
+
@@ -468,6 +508,7 @@ int main(int argc, char **argv)
|
104
|
+
qtest_add_func("/ide/bmdma/long_prdt", test_bmdma_long_prdt);
|
105
|
+
qtest_add_func("/ide/bmdma/teardown", test_bmdma_teardown);
|
106
|
+
|
107
|
+
+ qtest_add_func("/ide/flush", test_flush);
|
108
|
+
qtest_add_func("/ide/flush_nodev", test_flush_nodev);
|
109
|
+
|
110
|
+
ret = g_test_run();
|
111
|
+
--
|
112
|
+
1.8.3.1
|
113
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
From 110f5902133db4e8a46c9cc18ed0d4ed2e99aec2 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:34:59 +0200
|
4
|
+
Subject: [PATCH 01/16] json-parser: drop superfluous assignment for token
|
5
|
+
variable
|
6
|
+
|
7
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
8
|
+
Message-id: <1469604913-12442-3-git-send-email-armbru@redhat.com>
|
9
|
+
Patchwork-id: 71470
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 01/15] json-parser: drop superfluous assignment for token variable
|
11
|
+
Bugzilla: 1276036
|
12
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
13
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
14
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
15
|
+
|
16
|
+
From: Gonglei <arei.gonglei@huawei.com>
|
17
|
+
|
18
|
+
Signed-off-by: ChenLiang <chenliang88@huawei.com>
|
19
|
+
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
|
20
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
21
|
+
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
|
22
|
+
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
|
23
|
+
(cherry picked from commit a491af471bf8f1188b2665f54d109065d4591e45)
|
24
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
qobject/json-parser.c | 15 ++-------------
|
28
|
+
1 file changed, 2 insertions(+), 13 deletions(-)
|
29
|
+
|
30
|
+
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
|
31
|
+
index e7947b3..fa09769 100644
|
32
|
+
--- a/qobject/json-parser.c
|
33
|
+
+++ b/qobject/json-parser.c
|
34
|
+
@@ -423,7 +423,6 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
35
|
+
if (!token_is_operator(token, '{')) {
|
36
|
+
goto out;
|
37
|
+
}
|
38
|
+
- token = NULL;
|
39
|
+
|
40
|
+
dict = qdict_new();
|
41
|
+
|
42
|
+
@@ -449,7 +448,6 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
43
|
+
parse_error(ctxt, token, "expected separator in dict");
|
44
|
+
goto out;
|
45
|
+
}
|
46
|
+
- token = NULL;
|
47
|
+
|
48
|
+
if (parse_pair(ctxt, dict, ap) == -1) {
|
49
|
+
goto out;
|
50
|
+
@@ -461,10 +459,8 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
51
|
+
goto out;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
- token = NULL;
|
55
|
+
} else {
|
56
|
+
- token = parser_context_pop_token(ctxt);
|
57
|
+
- token = NULL;
|
58
|
+
+ (void)parser_context_pop_token(ctxt);
|
59
|
+
}
|
60
|
+
|
61
|
+
return QOBJECT(dict);
|
62
|
+
@@ -487,10 +483,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
63
|
+
}
|
64
|
+
|
65
|
+
if (!token_is_operator(token, '[')) {
|
66
|
+
- token = NULL;
|
67
|
+
goto out;
|
68
|
+
}
|
69
|
+
- token = NULL;
|
70
|
+
|
71
|
+
list = qlist_new();
|
72
|
+
|
73
|
+
@@ -523,8 +517,6 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
74
|
+
goto out;
|
75
|
+
}
|
76
|
+
|
77
|
+
- token = NULL;
|
78
|
+
-
|
79
|
+
obj = parse_value(ctxt, ap);
|
80
|
+
if (obj == NULL) {
|
81
|
+
parse_error(ctxt, token, "expecting value");
|
82
|
+
@@ -539,11 +531,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
83
|
+
goto out;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
-
|
87
|
+
- token = NULL;
|
88
|
+
} else {
|
89
|
+
- token = parser_context_pop_token(ctxt);
|
90
|
+
- token = NULL;
|
91
|
+
+ (void)parser_context_pop_token(ctxt);
|
92
|
+
}
|
93
|
+
|
94
|
+
return QOBJECT(list);
|
95
|
+
--
|
96
|
+
1.8.3.1
|
97
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
From b3e87d63aec8631b853cb86a0736af41954769a4 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:12 +0200
|
4
|
+
Subject: [PATCH 14/16] json-streamer: Don't leak tokens on incomplete parse
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-16-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71477
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 14/15] json-streamer: Don't leak tokens on incomplete parse
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Eric Blake <eblake@redhat.com>
|
16
|
+
|
17
|
+
Valgrind complained about a number of leaks in
|
18
|
+
tests/check-qobject-json:
|
19
|
+
|
20
|
+
==12657== definitely lost: 17,247 bytes in 1,234 blocks
|
21
|
+
|
22
|
+
All of which had the same root cause: on an incomplete parse,
|
23
|
+
we were abandoning the token queue without cleaning up the
|
24
|
+
allocated data within each queue element. Introduced in
|
25
|
+
commit 95385fe, when we switched from QList (which recursively
|
26
|
+
frees contents) to g_queue (which does not).
|
27
|
+
|
28
|
+
We don't yet require glib 2.32 with its g_queue_free_full(),
|
29
|
+
so open-code it instead.
|
30
|
+
|
31
|
+
CC: qemu-stable@nongnu.org
|
32
|
+
Signed-off-by: Eric Blake <eblake@redhat.com>
|
33
|
+
Message-Id: <1463608012-12760-1-git-send-email-eblake@redhat.com>
|
34
|
+
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
35
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
36
|
+
(cherry picked from commit ba4dba54347d5062436a8553f527dbbed6dcf069)
|
37
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
38
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
39
|
+
---
|
40
|
+
qobject/json-streamer.c | 6 ++++++
|
41
|
+
1 file changed, 6 insertions(+)
|
42
|
+
|
43
|
+
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
|
44
|
+
index a4db4b8..3c7d6be 100644
|
45
|
+
--- a/qobject/json-streamer.c
|
46
|
+
+++ b/qobject/json-streamer.c
|
47
|
+
|
48
|
+
#define MAX_TOKEN_COUNT (2ULL << 20)
|
49
|
+
#define MAX_NESTING (1ULL << 10)
|
50
|
+
|
51
|
+
+static void json_message_free_token(void *token, void *opaque)
|
52
|
+
+{
|
53
|
+
+ g_free(token);
|
54
|
+
+}
|
55
|
+
+
|
56
|
+
static void json_message_free_tokens(JSONMessageParser *parser)
|
57
|
+
{
|
58
|
+
if (parser->tokens) {
|
59
|
+
+ g_queue_foreach(parser->tokens, json_message_free_token, NULL);
|
60
|
+
g_queue_free(parser->tokens);
|
61
|
+
parser->tokens = NULL;
|
62
|
+
}
|
63
|
+
--
|
64
|
+
1.8.3.1
|
65
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
From a781053c1b5084ba32b86229b98b9601c990722c Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:13 +0200
|
4
|
+
Subject: [PATCH 15/16] json-streamer: fix double-free on exiting during a
|
5
|
+
parse
|
6
|
+
|
7
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
8
|
+
Message-id: <1469604913-12442-17-git-send-email-armbru@redhat.com>
|
9
|
+
Patchwork-id: 71484
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 15/15] json-streamer: fix double-free on exiting during a parse
|
11
|
+
Bugzilla: 1276036
|
12
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
13
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
14
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
15
|
+
|
16
|
+
From: Paolo Bonzini <pbonzini@redhat.com>
|
17
|
+
|
18
|
+
Now that json-streamer tries not to leak tokens on incomplete parse,
|
19
|
+
the tokens can be freed twice if QEMU destroys the json-streamer
|
20
|
+
object during the parser->emit call. To fix this, create the new
|
21
|
+
empty GQueue earlier, so that it is already in place when the old
|
22
|
+
one is passed to parser->emit.
|
23
|
+
|
24
|
+
Reported-by: Changlong Xie <xiecl.fnst@cn.fujitsu.com>
|
25
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
26
|
+
Message-Id: <1467636059-12557-1-git-send-email-pbonzini@redhat.com>
|
27
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
28
|
+
(cherry picked from commit a942d8fa01f65279cdc135f4294db611bbc088ef)
|
29
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
30
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
31
|
+
---
|
32
|
+
qobject/json-streamer.c | 8 ++++++--
|
33
|
+
1 file changed, 6 insertions(+), 2 deletions(-)
|
34
|
+
|
35
|
+
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
|
36
|
+
index 3c7d6be..7d041e1 100644
|
37
|
+
--- a/qobject/json-streamer.c
|
38
|
+
+++ b/qobject/json-streamer.c
|
39
|
+
@@ -38,6 +38,7 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
|
40
|
+
{
|
41
|
+
JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
|
42
|
+
JSONToken *token;
|
43
|
+
+ GQueue *tokens;
|
44
|
+
|
45
|
+
switch (type) {
|
46
|
+
case JSON_LCURLY:
|
47
|
+
@@ -95,9 +96,12 @@ out_emit:
|
48
|
+
/* send current list of tokens to parser and reset tokenizer */
|
49
|
+
parser->brace_count = 0;
|
50
|
+
parser->bracket_count = 0;
|
51
|
+
- /* parser->emit takes ownership of parser->tokens. */
|
52
|
+
- parser->emit(parser, parser->tokens);
|
53
|
+
+ /* parser->emit takes ownership of parser->tokens. Remove our own
|
54
|
+
+ * reference to parser->tokens before handing it out to parser->emit.
|
55
|
+
+ */
|
56
|
+
+ tokens = parser->tokens;
|
57
|
+
parser->tokens = g_queue_new();
|
58
|
+
+ parser->emit(parser, tokens);
|
59
|
+
parser->token_size = 0;
|
60
|
+
}
|
61
|
+
|
62
|
+
--
|
63
|
+
1.8.3.1
|
64
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
From 2efca7904a7a71d44bdf715208899e3bb29711df Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Thu, 10 Mar 2016 04:00:51 +0100
|
4
|
+
Subject: [PATCH 2/5] nbd: Always call "close_fn" in nbd_client_new
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1457582453-13835-2-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69757
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 1/3] nbd: Always call "close_fn" in nbd_client_new
|
10
|
+
Bugzilla: 1285453
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
13
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
14
|
+
|
15
|
+
Rename the parameter "close" to "close_fn" to disambiguous with
|
16
|
+
close(2).
|
17
|
+
|
18
|
+
This unifies error handling paths of NBDClient allocation:
|
19
|
+
nbd_client_new will shutdown the socket and call the "close_fn" callback
|
20
|
+
if negotiation failed, so the caller don't need a different path than
|
21
|
+
the normal close.
|
22
|
+
|
23
|
+
The returned pointer is never used, make it void in preparation for the
|
24
|
+
next patch.
|
25
|
+
|
26
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
27
|
+
Message-Id: <1452760863-25350-2-git-send-email-famz@redhat.com>
|
28
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
29
|
+
(cherry picked from commit ee7d7aabdaea4484e069cb99c9fc54e8cb24b56f)
|
30
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
31
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
32
|
+
|
33
|
+
Conflicts:
|
34
|
+
include/block/nbd.h
|
35
|
+
nbd.c
|
36
|
+
qemu-nbd.c
|
37
|
+
* nbd_update_server_fd_handler not in downstream;
|
38
|
+
* Context around the changed line is different.
|
39
|
+
---
|
40
|
+
include/block/nbd.h | 3 +--
|
41
|
+
nbd.c | 11 +++++------
|
42
|
+
qemu-nbd.c | 4 ++--
|
43
|
+
3 files changed, 8 insertions(+), 10 deletions(-)
|
44
|
+
|
45
|
+
diff --git a/include/block/nbd.h b/include/block/nbd.h
|
46
|
+
index c90f5e4..92e360e 100644
|
47
|
+
--- a/include/block/nbd.h
|
48
|
+
+++ b/include/block/nbd.h
|
49
|
+
@@ -92,8 +92,7 @@ NBDExport *nbd_export_find(const char *name);
|
50
|
+
void nbd_export_set_name(NBDExport *exp, const char *name);
|
51
|
+
void nbd_export_close_all(void);
|
52
|
+
|
53
|
+
-NBDClient *nbd_client_new(NBDExport *exp, int csock,
|
54
|
+
- void (*close)(NBDClient *));
|
55
|
+
+void nbd_client_new(NBDExport *exp, int csock, void (*close_fn)(NBDClient *));
|
56
|
+
void nbd_client_close(NBDClient *client);
|
57
|
+
void nbd_client_get(NBDClient *client);
|
58
|
+
void nbd_client_put(NBDClient *client);
|
59
|
+
diff --git a/nbd.c b/nbd.c
|
60
|
+
index f258cdd..ba97270 100644
|
61
|
+
--- a/nbd.c
|
62
|
+
+++ b/nbd.c
|
63
|
+
@@ -1232,8 +1232,7 @@ static void nbd_restart_write(void *opaque)
|
64
|
+
qemu_coroutine_enter(client->send_coroutine, NULL);
|
65
|
+
}
|
66
|
+
|
67
|
+
-NBDClient *nbd_client_new(NBDExport *exp, int csock,
|
68
|
+
- void (*close)(NBDClient *))
|
69
|
+
+void nbd_client_new(NBDExport *exp, int csock, void (*close_fn)(NBDClient *))
|
70
|
+
{
|
71
|
+
NBDClient *client;
|
72
|
+
client = g_malloc0(sizeof(NBDClient));
|
73
|
+
@@ -1241,10 +1240,11 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
|
74
|
+
client->exp = exp;
|
75
|
+
client->sock = csock;
|
76
|
+
if (nbd_send_negotiate(client) < 0) {
|
77
|
+
- g_free(client);
|
78
|
+
- return NULL;
|
79
|
+
+ shutdown(client->sock, 2);
|
80
|
+
+ close_fn(client);
|
81
|
+
+ return;
|
82
|
+
}
|
83
|
+
- client->close = close;
|
84
|
+
+ client->close = close_fn;
|
85
|
+
qemu_co_mutex_init(&client->send_lock);
|
86
|
+
qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
|
87
|
+
|
88
|
+
@@ -1252,5 +1252,4 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
|
89
|
+
QTAILQ_INSERT_TAIL(&exp->clients, client, next);
|
90
|
+
nbd_export_get(exp);
|
91
|
+
}
|
92
|
+
- return client;
|
93
|
+
}
|
94
|
+
diff --git a/qemu-nbd.c b/qemu-nbd.c
|
95
|
+
index ff792ef..047dd49 100644
|
96
|
+
--- a/qemu-nbd.c
|
97
|
+
+++ b/qemu-nbd.c
|
98
|
+
@@ -297,9 +297,9 @@ static void nbd_accept(void *opaque)
|
99
|
+
close(fd);
|
100
|
+
return;
|
101
|
+
}
|
102
|
+
-
|
103
|
+
- if (fd >= 0 && nbd_client_new(exp, fd, nbd_client_closed)) {
|
104
|
+
+ if (fd >= 0) {
|
105
|
+
nb_fds++;
|
106
|
+
+ nbd_client_new(exp, fd, nbd_client_closed);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
--
|
111
|
+
1.8.3.1
|
112
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
From c62e0877b191e5fba9b678bbd518a57c8fdf7099 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Thu, 10 Mar 2016 04:00:53 +0100
|
4
|
+
Subject: [PATCH 4/5] nbd: client_close on error in nbd_co_client_start
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1457582453-13835-4-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69759
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 3/3] nbd: client_close on error in nbd_co_client_start
|
10
|
+
Bugzilla: 1285453
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
13
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
14
|
+
|
15
|
+
From: Max Reitz <mreitz@redhat.com>
|
16
|
+
|
17
|
+
Use client_close() if an error in nbd_co_client_start() occurs instead
|
18
|
+
of manually inlining parts of it. This fixes an assertion error on the
|
19
|
+
server side if nbd_negotiate() fails.
|
20
|
+
|
21
|
+
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
22
|
+
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
23
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
24
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
25
|
+
(cherry picked from commit d3780c2dce2c452759ee9d94f9d824cf14cc3ab8)
|
26
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
27
|
+
|
28
|
+
Downstream: client_close -> nbd_client_close.
|
29
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
30
|
+
---
|
31
|
+
nbd.c | 3 +--
|
32
|
+
1 file changed, 1 insertion(+), 2 deletions(-)
|
33
|
+
|
34
|
+
diff --git a/nbd.c b/nbd.c
|
35
|
+
index 97aeecb..c20e57e 100644
|
36
|
+
--- a/nbd.c
|
37
|
+
+++ b/nbd.c
|
38
|
+
@@ -1282,8 +1282,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
|
39
|
+
nbd_export_get(exp);
|
40
|
+
}
|
41
|
+
if (nbd_negotiate(data)) {
|
42
|
+
- shutdown(client->sock, 2);
|
43
|
+
- client->close(client);
|
44
|
+
+ nbd_client_close(client);
|
45
|
+
goto out;
|
46
|
+
}
|
47
|
+
qemu_co_mutex_init(&client->send_lock);
|
48
|
+
--
|
49
|
+
1.8.3.1
|
50
|
+
|
@@ -0,0 +1,262 @@
|
|
1
|
+
From 2a68d801c63137c3d1fe9fa96f0193eb2d1576f5 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Thu, 10 Mar 2016 04:00:52 +0100
|
4
|
+
Subject: [PATCH 3/5] nbd-server: Coroutine based negotiation
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1457582453-13835-3-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69758
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 2/3] nbd-server: Coroutine based negotiation
|
10
|
+
Bugzilla: 1285453
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
13
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
14
|
+
|
15
|
+
Create a coroutine in nbd_client_new, so that nbd_send_negotiate doesn't
|
16
|
+
need qemu_set_block().
|
17
|
+
|
18
|
+
Handlers need to be set temporarily for csock fd in case the coroutine
|
19
|
+
yields during I/O.
|
20
|
+
|
21
|
+
With this, if the other end disappears in the middle of the negotiation,
|
22
|
+
we don't block the whole event loop.
|
23
|
+
|
24
|
+
To make the code clearer, unify all function names that belong to
|
25
|
+
negotiate, so they are less likely to be misused. This is important
|
26
|
+
because we rely on negotiation staying in main loop, as commented in
|
27
|
+
nbd_negotiate_read/write().
|
28
|
+
|
29
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
30
|
+
Message-Id: <1452760863-25350-4-git-send-email-famz@redhat.com>
|
31
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
32
|
+
(cherry picked from commit 1a6245a5b0b4e8d822c739b403fc67c8a7bc8d12)
|
33
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
34
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
35
|
+
|
36
|
+
Conflicts:
|
37
|
+
nbd.c
|
38
|
+
Downstream doesn't have new style protocol, and the code is not split.
|
39
|
+
The patch is redone.
|
40
|
+
---
|
41
|
+
nbd.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++---------------
|
42
|
+
1 file changed, 82 insertions(+), 24 deletions(-)
|
43
|
+
|
44
|
+
diff --git a/nbd.c b/nbd.c
|
45
|
+
index ba97270..97aeecb 100644
|
46
|
+
--- a/nbd.c
|
47
|
+
+++ b/nbd.c
|
48
|
+
@@ -167,6 +167,41 @@ ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
|
49
|
+
return offset;
|
50
|
+
}
|
51
|
+
|
52
|
+
+static void nbd_negotiate_continue(void *opaque)
|
53
|
+
+{
|
54
|
+
+ qemu_coroutine_enter(opaque, NULL);
|
55
|
+
+}
|
56
|
+
+
|
57
|
+
+static ssize_t read_sync(int fd, void *buffer, size_t size);
|
58
|
+
+static ssize_t write_sync(int fd, void *buffer, size_t size);
|
59
|
+
+
|
60
|
+
+static ssize_t nbd_negotiate_read(int fd, void *buffer, size_t size)
|
61
|
+
+{
|
62
|
+
+ ssize_t ret;
|
63
|
+
+
|
64
|
+
+ assert(qemu_in_coroutine());
|
65
|
+
+ /* Negotiation are always in main loop. */
|
66
|
+
+ qemu_set_fd_handler(fd, nbd_negotiate_continue, NULL,
|
67
|
+
+ qemu_coroutine_self());
|
68
|
+
+ ret = read_sync(fd, buffer, size);
|
69
|
+
+ qemu_set_fd_handler(fd, NULL, NULL, NULL);
|
70
|
+
+ return ret;
|
71
|
+
+
|
72
|
+
+}
|
73
|
+
+
|
74
|
+
+static ssize_t nbd_negotiate_write(int fd, void *buffer, size_t size)
|
75
|
+
+{
|
76
|
+
+ ssize_t ret;
|
77
|
+
+
|
78
|
+
+ assert(qemu_in_coroutine());
|
79
|
+
+ /* Negotiation are always in main loop. */
|
80
|
+
+ qemu_set_fd_handler(fd, NULL, nbd_negotiate_continue,
|
81
|
+
+ qemu_coroutine_self());
|
82
|
+
+ ret = write_sync(fd, buffer, size);
|
83
|
+
+ qemu_set_fd_handler(fd, NULL, NULL, NULL);
|
84
|
+
+ return ret;
|
85
|
+
+}
|
86
|
+
+
|
87
|
+
static ssize_t read_sync(int fd, void *buffer, size_t size)
|
88
|
+
{
|
89
|
+
/* Sockets are kept in blocking mode in the negotiation phase. After
|
90
|
+
@@ -280,7 +315,7 @@ int unix_socket_outgoing(const char *path)
|
91
|
+
|
92
|
+
*/
|
93
|
+
|
94
|
+
-static int nbd_receive_options(NBDClient *client)
|
95
|
+
+static coroutine_fn int nbd_negotiate_receive_options(NBDClient *client)
|
96
|
+
{
|
97
|
+
int csock = client->sock;
|
98
|
+
char name[256];
|
99
|
+
@@ -297,7 +332,7 @@ static int nbd_receive_options(NBDClient *client)
|
100
|
+
*/
|
101
|
+
|
102
|
+
rc = -EINVAL;
|
103
|
+
- if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
|
104
|
+
+ if (nbd_negotiate_read(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
|
105
|
+
LOG("read failed");
|
106
|
+
goto fail;
|
107
|
+
}
|
108
|
+
@@ -307,7 +342,7 @@ static int nbd_receive_options(NBDClient *client)
|
109
|
+
goto fail;
|
110
|
+
}
|
111
|
+
|
112
|
+
- if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
|
113
|
+
+ if (nbd_negotiate_read(csock, &magic, sizeof(magic)) != sizeof(magic)) {
|
114
|
+
LOG("read failed");
|
115
|
+
goto fail;
|
116
|
+
}
|
117
|
+
@@ -317,7 +352,7 @@ static int nbd_receive_options(NBDClient *client)
|
118
|
+
goto fail;
|
119
|
+
}
|
120
|
+
|
121
|
+
- if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
|
122
|
+
+ if (nbd_negotiate_read(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
|
123
|
+
LOG("read failed");
|
124
|
+
goto fail;
|
125
|
+
}
|
126
|
+
@@ -327,7 +362,7 @@ static int nbd_receive_options(NBDClient *client)
|
127
|
+
goto fail;
|
128
|
+
}
|
129
|
+
|
130
|
+
- if (read_sync(csock, &length, sizeof(length)) != sizeof(length)) {
|
131
|
+
+ if (nbd_negotiate_read(csock, &length, sizeof(length)) != sizeof(length)) {
|
132
|
+
LOG("read failed");
|
133
|
+
goto fail;
|
134
|
+
}
|
135
|
+
@@ -337,7 +372,7 @@ static int nbd_receive_options(NBDClient *client)
|
136
|
+
LOG("Bad length received");
|
137
|
+
goto fail;
|
138
|
+
}
|
139
|
+
- if (read_sync(csock, name, length) != length) {
|
140
|
+
+ if (nbd_negotiate_read(csock, name, length) != length) {
|
141
|
+
LOG("read failed");
|
142
|
+
goto fail;
|
143
|
+
}
|
144
|
+
@@ -358,8 +393,14 @@ fail:
|
145
|
+
return rc;
|
146
|
+
}
|
147
|
+
|
148
|
+
-static int nbd_send_negotiate(NBDClient *client)
|
149
|
+
+typedef struct {
|
150
|
+
+ NBDClient *client;
|
151
|
+
+ Coroutine *co;
|
152
|
+
+} NBDClientNewData;
|
153
|
+
+
|
154
|
+
+static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
|
155
|
+
{
|
156
|
+
+ NBDClient *client = data->client;
|
157
|
+
int csock = client->sock;
|
158
|
+
char buf[8 + 8 + 8 + 128];
|
159
|
+
int rc;
|
160
|
+
@@ -385,7 +426,6 @@ static int nbd_send_negotiate(NBDClient *client)
|
161
|
+
[28 .. 151] reserved (0)
|
162
|
+
*/
|
163
|
+
|
164
|
+
- qemu_set_block(csock);
|
165
|
+
rc = -EINVAL;
|
166
|
+
|
167
|
+
TRACE("Beginning negotiation.");
|
168
|
+
@@ -401,16 +441,16 @@ static int nbd_send_negotiate(NBDClient *client)
|
169
|
+
}
|
170
|
+
|
171
|
+
if (client->exp) {
|
172
|
+
- if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
|
173
|
+
+ if (nbd_negotiate_write(csock, buf, sizeof(buf)) != sizeof(buf)) {
|
174
|
+
LOG("write failed");
|
175
|
+
goto fail;
|
176
|
+
}
|
177
|
+
} else {
|
178
|
+
- if (write_sync(csock, buf, 18) != 18) {
|
179
|
+
+ if (nbd_negotiate_write(csock, buf, 18) != 18) {
|
180
|
+
LOG("write failed");
|
181
|
+
goto fail;
|
182
|
+
}
|
183
|
+
- rc = nbd_receive_options(client);
|
184
|
+
+ rc = nbd_negotiate_receive_options(client);
|
185
|
+
if (rc < 0) {
|
186
|
+
LOG("option negotiation failed");
|
187
|
+
goto fail;
|
188
|
+
@@ -419,7 +459,8 @@ static int nbd_send_negotiate(NBDClient *client)
|
189
|
+
assert ((client->exp->nbdflags & ~65535) == 0);
|
190
|
+
cpu_to_be64w((uint64_t*)(buf + 18), client->exp->size);
|
191
|
+
cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);
|
192
|
+
- if (write_sync(csock, buf + 18, sizeof(buf) - 18) != sizeof(buf) - 18) {
|
193
|
+
+ if (nbd_negotiate_write(csock, buf + 18,
|
194
|
+
+ sizeof(buf) - 18) != sizeof(buf) - 18) {
|
195
|
+
LOG("write failed");
|
196
|
+
goto fail;
|
197
|
+
}
|
198
|
+
@@ -428,7 +469,6 @@ static int nbd_send_negotiate(NBDClient *client)
|
199
|
+
TRACE("Negotiation succeeded.");
|
200
|
+
rc = 0;
|
201
|
+
fail:
|
202
|
+
- qemu_set_nonblock(csock);
|
203
|
+
return rc;
|
204
|
+
}
|
205
|
+
|
206
|
+
@@ -1232,24 +1272,42 @@ static void nbd_restart_write(void *opaque)
|
207
|
+
qemu_coroutine_enter(client->send_coroutine, NULL);
|
208
|
+
}
|
209
|
+
|
210
|
+
+static coroutine_fn void nbd_co_client_start(void *opaque)
|
211
|
+
+{
|
212
|
+
+ NBDClientNewData *data = opaque;
|
213
|
+
+ NBDClient *client = data->client;
|
214
|
+
+ NBDExport *exp = client->exp;
|
215
|
+
+
|
216
|
+
+ if (exp) {
|
217
|
+
+ nbd_export_get(exp);
|
218
|
+
+ }
|
219
|
+
+ if (nbd_negotiate(data)) {
|
220
|
+
+ shutdown(client->sock, 2);
|
221
|
+
+ client->close(client);
|
222
|
+
+ goto out;
|
223
|
+
+ }
|
224
|
+
+ qemu_co_mutex_init(&client->send_lock);
|
225
|
+
+ qemu_set_fd_handler2(client->sock, nbd_can_read, nbd_read, NULL, client);
|
226
|
+
+
|
227
|
+
+ if (exp) {
|
228
|
+
+ QTAILQ_INSERT_TAIL(&exp->clients, client, next);
|
229
|
+
+ }
|
230
|
+
+out:
|
231
|
+
+ g_free(data);
|
232
|
+
+}
|
233
|
+
+
|
234
|
+
void nbd_client_new(NBDExport *exp, int csock, void (*close_fn)(NBDClient *))
|
235
|
+
{
|
236
|
+
NBDClient *client;
|
237
|
+
+ NBDClientNewData *data = g_new(NBDClientNewData, 1);
|
238
|
+
+
|
239
|
+
client = g_malloc0(sizeof(NBDClient));
|
240
|
+
client->refcount = 1;
|
241
|
+
client->exp = exp;
|
242
|
+
client->sock = csock;
|
243
|
+
- if (nbd_send_negotiate(client) < 0) {
|
244
|
+
- shutdown(client->sock, 2);
|
245
|
+
- close_fn(client);
|
246
|
+
- return;
|
247
|
+
- }
|
248
|
+
client->close = close_fn;
|
249
|
+
- qemu_co_mutex_init(&client->send_lock);
|
250
|
+
- qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
|
251
|
+
|
252
|
+
- if (exp) {
|
253
|
+
- QTAILQ_INSERT_TAIL(&exp->clients, client, next);
|
254
|
+
- nbd_export_get(exp);
|
255
|
+
- }
|
256
|
+
+ data->client = client;
|
257
|
+
+ data->co = qemu_coroutine_create(nbd_co_client_start);
|
258
|
+
+ qemu_coroutine_enter(data->co, data);
|
259
|
+
}
|
260
|
+
--
|
261
|
+
1.8.3.1
|
262
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
From e36a5a8613df42339773ebf48e07d063ad7484e8 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 5 Sep 2016 01:18:15 +0200
|
4
|
+
Subject: [PATCH] nbd-server: Set O_NONBLOCK on client fd
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1473038295-7193-1-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 72141
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH] nbd-server: Set O_NONBLOCK on client fd
|
10
|
+
Bugzilla: 1285453
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
Upstream: upstream uses IO channels that is not present in downstream.
|
16
|
+
Backporting that deserves a separate and deliberate justification BZ,
|
17
|
+
for 7.4.
|
18
|
+
|
19
|
+
Even with 2a68d80 (nbd-server: Coroutine based negotiation), QEMU still
|
20
|
+
hangs when client hangs, because recvmsg the socket fd is blocking. Set
|
21
|
+
the O_NONBLOCK to fix this.
|
22
|
+
|
23
|
+
Analyzed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
24
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
nbd.c | 1 +
|
28
|
+
1 file changed, 1 insertion(+)
|
29
|
+
|
30
|
+
diff --git a/nbd.c b/nbd.c
|
31
|
+
index c20e57e..8a32e18 100644
|
32
|
+
--- a/nbd.c
|
33
|
+
+++ b/nbd.c
|
34
|
+
@@ -1281,6 +1281,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
|
35
|
+
if (exp) {
|
36
|
+
nbd_export_get(exp);
|
37
|
+
}
|
38
|
+
+ qemu_set_nonblock(client->sock);
|
39
|
+
if (nbd_negotiate(data)) {
|
40
|
+
nbd_client_close(client);
|
41
|
+
goto out;
|
42
|
+
--
|
43
|
+
1.8.3.1
|
44
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
From 9c2a6798c053cec989e02935e810a0d239fb493c Mon Sep 17 00:00:00 2001
|
2
|
+
From: Vlad Yasevich <vyasevic@redhat.com>
|
3
|
+
Date: Wed, 16 Dec 2015 02:59:35 +0100
|
4
|
+
Subject: [PATCH 1/2] net: Make qmp_query_rx_filter() with name argument more
|
5
|
+
obvious
|
6
|
+
|
7
|
+
RH-Author: Vlad Yasevich <vyasevic@redhat.com>
|
8
|
+
Message-id: <1450234776-7779-2-git-send-email-vyasevic@redhat.com>
|
9
|
+
Patchwork-id: 68620
|
10
|
+
O-Subject: [RHEL7.3 qemu-kvm PATCH 1/2] net: Make qmp_query_rx_filter() with name argument more obvious
|
11
|
+
Bugzilla: 1269738
|
12
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
13
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
14
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
15
|
+
|
16
|
+
From: Markus Armbruster <armbru@redhat.com>
|
17
|
+
|
18
|
+
With a client name, the QMP command is specified to return a list of
|
19
|
+
one element. This isn't locally obvious in the code. Make it so.
|
20
|
+
|
21
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
22
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
23
|
+
(cherry picked from commit 638fb14169ad96cf9bc0dd5f61460daaecee5bb1)
|
24
|
+
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
net/net.c | 4 ++++
|
28
|
+
1 file changed, 4 insertions(+)
|
29
|
+
|
30
|
+
diff --git a/net/net.c b/net/net.c
|
31
|
+
index a8c49fc..0be50a0 100644
|
32
|
+
--- a/net/net.c
|
33
|
+
+++ b/net/net.c
|
34
|
+
@@ -1000,6 +1000,10 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name,
|
35
|
+
" rx-filter querying", name);
|
36
|
+
break;
|
37
|
+
}
|
38
|
+
+
|
39
|
+
+ if (has_name) {
|
40
|
+
+ break;
|
41
|
+
+ }
|
42
|
+
}
|
43
|
+
|
44
|
+
if (filter_list == NULL && !error_is_set(errp) && has_name) {
|
45
|
+
--
|
46
|
+
1.8.3.1
|
47
|
+
|
@@ -0,0 +1,133 @@
|
|
1
|
+
From 607904cf94b1dee91c74522aedebda308ffba93d Mon Sep 17 00:00:00 2001
|
2
|
+
From: Laszlo Ersek <lersek@redhat.com>
|
3
|
+
Date: Wed, 11 May 2016 12:33:48 +0200
|
4
|
+
Subject: [PATCH 09/10] pc: set the OEM fields in the RSDT and the FADT from
|
5
|
+
the SLIC
|
6
|
+
|
7
|
+
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
8
|
+
Message-id: <1462970028-10959-8-git-send-email-lersek@redhat.com>
|
9
|
+
Patchwork-id: 70384
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 7/7] pc: set the OEM fields in the RSDT and the FADT from the SLIC
|
11
|
+
Bugzilla: 1330969
|
12
|
+
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
13
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
14
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
15
|
+
|
16
|
+
The Microsoft spec about the SLIC and MSDM ACPI tables at
|
17
|
+
<http://go.microsoft.com/fwlink/p/?LinkId=234834> requires the OEM ID and
|
18
|
+
OEM Table ID fields to be consistent between the SLIC and the RSDT/XSDT.
|
19
|
+
That further affects the FADT, because a similar match between the FADT
|
20
|
+
and the RSDT/XSDT is required by the ACPI spec in general.
|
21
|
+
|
22
|
+
This patch wires up the previous three patches.
|
23
|
+
|
24
|
+
Cc: "Michael S. Tsirkin" <mst@redhat.com> (supporter:ACPI/SMBIOS)
|
25
|
+
Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
|
26
|
+
Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
|
27
|
+
Cc: Richard W.M. Jones <rjones@redhat.com>
|
28
|
+
Cc: Aleksei Kovura <alex3kov@zoho.com>
|
29
|
+
Cc: Michael Tokarev <mjt@tls.msk.ru>
|
30
|
+
Cc: Steven Newbury <steve@snewbury.org.uk>
|
31
|
+
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
|
32
|
+
LP: https://bugs.launchpad.net/qemu/+bug/1533848
|
33
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
34
|
+
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
35
|
+
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
36
|
+
Reviewed-by: Steven Newbury <steve@snewbury.org.uk>
|
37
|
+
(cherry picked from commit ae12374951f07157f7a52c8d848b90f8eec722fb)
|
38
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
39
|
+
|
40
|
+
Conflicts:
|
41
|
+
hw/i386/acpi-build.c
|
42
|
+
|
43
|
+
RHEL-7 backport note: conflict due to downstream lacking 7c2c1fa5f428
|
44
|
+
("pc: acpi: use local var for accessing ACPI tables blob in
|
45
|
+
acpi_build()").
|
46
|
+
|
47
|
+
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
48
|
+
---
|
49
|
+
hw/i386/acpi-build.c | 13 +++++++++----
|
50
|
+
qemu-options.hx | 4 ++++
|
51
|
+
2 files changed, 13 insertions(+), 4 deletions(-)
|
52
|
+
---
|
53
|
+
hw/i386/acpi-build.c | 13 +++++++++----
|
54
|
+
qemu-options.hx | 4 ++++
|
55
|
+
2 files changed, 13 insertions(+), 4 deletions(-)
|
56
|
+
|
57
|
+
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
58
|
+
index d9433e6..85291f5 100644
|
59
|
+
--- a/hw/i386/acpi-build.c
|
60
|
+
+++ b/hw/i386/acpi-build.c
|
61
|
+
@@ -511,7 +511,8 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
|
62
|
+
/* FADT */
|
63
|
+
static void
|
64
|
+
build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
|
65
|
+
- unsigned facs, unsigned dsdt)
|
66
|
+
+ unsigned facs, unsigned dsdt,
|
67
|
+
+ const char *oem_id, const char *oem_table_id)
|
68
|
+
{
|
69
|
+
AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
|
70
|
+
|
71
|
+
@@ -532,7 +533,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
|
72
|
+
fadt_setup(fadt, pm);
|
73
|
+
|
74
|
+
build_header(linker, table_data,
|
75
|
+
- (void *)fadt, "FACP", sizeof(*fadt), 1, NULL, NULL);
|
76
|
+
+ (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
|
77
|
+
}
|
78
|
+
|
79
|
+
static void
|
80
|
+
@@ -1065,6 +1066,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
81
|
+
AcpiMcfgInfo mcfg;
|
82
|
+
PcPciInfo pci;
|
83
|
+
uint8_t *u;
|
84
|
+
+ AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL };
|
85
|
+
|
86
|
+
acpi_get_cpu_info(&cpu);
|
87
|
+
acpi_get_pm_info(&pm);
|
88
|
+
@@ -1072,6 +1074,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
89
|
+
acpi_get_hotplug_info(&misc);
|
90
|
+
acpi_get_misc_info(&misc);
|
91
|
+
acpi_get_pci_info(&pci);
|
92
|
+
+ acpi_get_slic_oem(&slic_oem);
|
93
|
+
|
94
|
+
table_offsets = g_array_new(false, true /* clear */,
|
95
|
+
sizeof(uint32_t));
|
96
|
+
@@ -1095,7 +1098,8 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
97
|
+
|
98
|
+
/* ACPI tables pointed to by RSDT */
|
99
|
+
acpi_add_table(table_offsets, tables->table_data);
|
100
|
+
- build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt);
|
101
|
+
+ build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt,
|
102
|
+
+ slic_oem.id, slic_oem.table_id);
|
103
|
+
|
104
|
+
acpi_add_table(table_offsets, tables->table_data);
|
105
|
+
build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
|
106
|
+
@@ -1127,7 +1131,8 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
107
|
+
|
108
|
+
/* RSDT is pointed to by RSDP */
|
109
|
+
rsdt = tables->table_data->len;
|
110
|
+
- build_rsdt(tables->table_data, tables->linker, table_offsets, NULL, NULL);
|
111
|
+
+ build_rsdt(tables->table_data, tables->linker, table_offsets,
|
112
|
+
+ slic_oem.id, slic_oem.table_id);
|
113
|
+
|
114
|
+
/* RSDP is in FSEG memory, so allocate it separately */
|
115
|
+
build_rsdp(tables->rsdp, tables->linker, rsdt);
|
116
|
+
diff --git a/qemu-options.hx b/qemu-options.hx
|
117
|
+
index 62c3e06..24ffab6 100644
|
118
|
+
--- a/qemu-options.hx
|
119
|
+
+++ b/qemu-options.hx
|
120
|
+
@@ -1295,6 +1295,10 @@ ACPI headers (possible overridden by other options).
|
121
|
+
For data=, only data
|
122
|
+
portion of the table is used, all header information is specified in the
|
123
|
+
command line.
|
124
|
+
+If a SLIC table is supplied to QEMU, then the SLIC's oem_id and oem_table_id
|
125
|
+
+fields will override the same in the RSDT and the FADT (a.k.a. FACP), in order
|
126
|
+
+to ensure the field matches required by the Microsoft SLIC spec and the ACPI
|
127
|
+
+spec.
|
128
|
+
ETEXI
|
129
|
+
|
130
|
+
DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
|
131
|
+
--
|
132
|
+
1.8.3.1
|
133
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
From 362faad8e8f4c2c2c875df12f6bbae7964c0146d Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:38 +0100
|
4
|
+
Subject: [PATCH 19/27] qemu-io: Check for trailing chars
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-20-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68449
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 19/21] qemu-io: Check for trailing chars
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
Make sure there's not trailing garbage, e.g.
|
16
|
+
"64k-whatever-i-want-here"
|
17
|
+
|
18
|
+
Reported-by: Max Reitz <mreitz@redhat.com>
|
19
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
20
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
21
|
+
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
22
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
23
|
+
(cherry picked from commit ef5a788527b2038d742b057a415ab4d0e735e98f)
|
24
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
|
27
|
+
Conflicts:
|
28
|
+
qemu-io-cmds.c:
|
29
|
+
- Downstream still uses strtosz_suffix, not
|
30
|
+
qemu_strtosz_suffix.
|
31
|
+
|
32
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
33
|
+
---
|
34
|
+
qemu-io-cmds.c | 9 ++++++++-
|
35
|
+
1 file changed, 8 insertions(+), 1 deletion(-)
|
36
|
+
|
37
|
+
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
38
|
+
index 95345fe..6ea027d 100644
|
39
|
+
--- a/qemu-io-cmds.c
|
40
|
+
+++ b/qemu-io-cmds.c
|
41
|
+
@@ -124,7 +124,14 @@ static char **breakline(char *input, int *count)
|
42
|
+
static int64_t cvtnum(const char *s)
|
43
|
+
{
|
44
|
+
char *end;
|
45
|
+
- return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
|
46
|
+
+ int64_t ret;
|
47
|
+
+
|
48
|
+
+ ret = strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
|
49
|
+
+ if (*end != '\0') {
|
50
|
+
+ /* Detritus at the end of the string */
|
51
|
+
+ return -EINVAL;
|
52
|
+
+ }
|
53
|
+
+ return ret;
|
54
|
+
}
|
55
|
+
|
56
|
+
#define EXABYTES(x) ((long long)(x) << 60)
|
57
|
+
--
|
58
|
+
1.8.3.1
|
59
|
+
|
@@ -0,0 +1,218 @@
|
|
1
|
+
From 8adbd2914ccd44e0b1766690b514bda213b88740 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:39 +0100
|
4
|
+
Subject: [PATCH 20/27] qemu-io: Correct error messages
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-21-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68446
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 20/21] qemu-io: Correct error messages
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
Reported-by: Max Reitz <mreitz@redhat.com>
|
16
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
17
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
18
|
+
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
19
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
20
|
+
(cherry picked from commit a9ecfa004f2dd83df612daac4a87dfc3a0feba28)
|
21
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
22
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
23
|
+
|
24
|
+
Conflicts:
|
25
|
+
qemu-io-cmds.c:
|
26
|
+
- Fixes to sigraise are not backported.
|
27
|
+
|
28
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
29
|
+
---
|
30
|
+
qemu-io-cmds.c | 51 +++++++++++++++++++++++++++++++++------------------
|
31
|
+
1 file changed, 33 insertions(+), 18 deletions(-)
|
32
|
+
|
33
|
+
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
34
|
+
index 6ea027d..b41d6ee 100644
|
35
|
+
--- a/qemu-io-cmds.c
|
36
|
+
+++ b/qemu-io-cmds.c
|
37
|
+
@@ -134,6 +134,21 @@ static int64_t cvtnum(const char *s)
|
38
|
+
return ret;
|
39
|
+
}
|
40
|
+
|
41
|
+
+static void print_cvtnum_err(int64_t rc, const char *arg)
|
42
|
+
+{
|
43
|
+
+ switch (rc) {
|
44
|
+
+ case -EINVAL:
|
45
|
+
+ printf("Parsing error: non-numeric argument,"
|
46
|
+
+ " or extraneous/unrecognized suffix -- %s\n", arg);
|
47
|
+
+ break;
|
48
|
+
+ case -ERANGE:
|
49
|
+
+ printf("Parsing error: argument too large -- %s\n", arg);
|
50
|
+
+ break;
|
51
|
+
+ default:
|
52
|
+
+ printf("Parsing error: %s\n", arg);
|
53
|
+
+ }
|
54
|
+
+}
|
55
|
+
+
|
56
|
+
#define EXABYTES(x) ((long long)(x) << 60)
|
57
|
+
#define PETABYTES(x) ((long long)(x) << 50)
|
58
|
+
#define TERABYTES(x) ((long long)(x) << 40)
|
59
|
+
@@ -355,13 +370,13 @@ create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
|
60
|
+
|
61
|
+
len = cvtnum(arg);
|
62
|
+
if (len < 0) {
|
63
|
+
- printf("non-numeric length argument -- %s\n", arg);
|
64
|
+
+ print_cvtnum_err(len, arg);
|
65
|
+
goto fail;
|
66
|
+
}
|
67
|
+
|
68
|
+
/* should be SIZE_T_MAX, but that doesn't exist */
|
69
|
+
if (len > INT_MAX) {
|
70
|
+
- printf("too large length argument -- %s\n", arg);
|
71
|
+
+ printf("Argument '%s' exceeds maximum size %d\n", arg, INT_MAX);
|
72
|
+
goto fail;
|
73
|
+
}
|
74
|
+
|
75
|
+
@@ -688,7 +703,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
|
76
|
+
lflag = 1;
|
77
|
+
pattern_count = cvtnum(optarg);
|
78
|
+
if (pattern_count < 0) {
|
79
|
+
- printf("non-numeric length argument -- %s\n", optarg);
|
80
|
+
+ print_cvtnum_err(pattern_count, optarg);
|
81
|
+
return 0;
|
82
|
+
}
|
83
|
+
break;
|
84
|
+
@@ -709,7 +724,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
|
85
|
+
sflag = 1;
|
86
|
+
pattern_offset = cvtnum(optarg);
|
87
|
+
if (pattern_offset < 0) {
|
88
|
+
- printf("non-numeric length argument -- %s\n", optarg);
|
89
|
+
+ print_cvtnum_err(pattern_offset, optarg);
|
90
|
+
return 0;
|
91
|
+
}
|
92
|
+
break;
|
93
|
+
@@ -732,14 +747,14 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
|
94
|
+
|
95
|
+
offset = cvtnum(argv[optind]);
|
96
|
+
if (offset < 0) {
|
97
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
98
|
+
+ print_cvtnum_err(offset, argv[optind]);
|
99
|
+
return 0;
|
100
|
+
}
|
101
|
+
|
102
|
+
optind++;
|
103
|
+
count = cvtnum(argv[optind]);
|
104
|
+
if (count < 0) {
|
105
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
106
|
+
+ print_cvtnum_err(count, argv[optind]);
|
107
|
+
return 0;
|
108
|
+
} else if (count > SIZE_MAX) {
|
109
|
+
printf("length cannot exceed %" PRIu64 ", given %s\n",
|
110
|
+
@@ -894,7 +909,7 @@ static int readv_f(BlockDriverState *bs, int argc, char **argv)
|
111
|
+
|
112
|
+
offset = cvtnum(argv[optind]);
|
113
|
+
if (offset < 0) {
|
114
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
115
|
+
+ print_cvtnum_err(offset, argv[optind]);
|
116
|
+
return 0;
|
117
|
+
}
|
118
|
+
optind++;
|
119
|
+
@@ -1043,14 +1058,14 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
|
120
|
+
|
121
|
+
offset = cvtnum(argv[optind]);
|
122
|
+
if (offset < 0) {
|
123
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
124
|
+
+ print_cvtnum_err(offset, argv[optind]);
|
125
|
+
return 0;
|
126
|
+
}
|
127
|
+
|
128
|
+
optind++;
|
129
|
+
count = cvtnum(argv[optind]);
|
130
|
+
if (count < 0) {
|
131
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
132
|
+
+ print_cvtnum_err(count, argv[optind]);
|
133
|
+
return 0;
|
134
|
+
} else if (count > SIZE_MAX) {
|
135
|
+
printf("length cannot exceed %" PRIu64 ", given %s\n",
|
136
|
+
@@ -1179,7 +1194,7 @@ static int writev_f(BlockDriverState *bs, int argc, char **argv)
|
137
|
+
|
138
|
+
offset = cvtnum(argv[optind]);
|
139
|
+
if (offset < 0) {
|
140
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
141
|
+
+ print_cvtnum_err(offset, argv[optind]);
|
142
|
+
return 0;
|
143
|
+
}
|
144
|
+
optind++;
|
145
|
+
@@ -1306,7 +1321,7 @@ static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
|
146
|
+
/* Read the offset of the request */
|
147
|
+
offset = cvtnum(argv[optind]);
|
148
|
+
if (offset < 0) {
|
149
|
+
- printf("non-numeric offset argument -- %s\n", argv[optind]);
|
150
|
+
+ print_cvtnum_err(offset, argv[optind]);
|
151
|
+
goto out;
|
152
|
+
}
|
153
|
+
optind++;
|
154
|
+
@@ -1526,7 +1541,7 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
|
155
|
+
|
156
|
+
ctx->offset = cvtnum(argv[optind]);
|
157
|
+
if (ctx->offset < 0) {
|
158
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
159
|
+
+ print_cvtnum_err(ctx->offset, argv[optind]);
|
160
|
+
g_free(ctx);
|
161
|
+
return 0;
|
162
|
+
}
|
163
|
+
@@ -1618,7 +1633,7 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
|
164
|
+
|
165
|
+
ctx->offset = cvtnum(argv[optind]);
|
166
|
+
if (ctx->offset < 0) {
|
167
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
168
|
+
+ print_cvtnum_err(ctx->offset, argv[optind]);
|
169
|
+
g_free(ctx);
|
170
|
+
return 0;
|
171
|
+
}
|
172
|
+
@@ -1676,7 +1691,7 @@ static int truncate_f(BlockDriverState *bs, int argc, char **argv)
|
173
|
+
|
174
|
+
offset = cvtnum(argv[1]);
|
175
|
+
if (offset < 0) {
|
176
|
+
- printf("non-numeric truncate argument -- %s\n", argv[1]);
|
177
|
+
+ print_cvtnum_err(offset, argv[1]);
|
178
|
+
return 0;
|
179
|
+
}
|
180
|
+
|
181
|
+
@@ -1822,14 +1837,14 @@ static int discard_f(BlockDriverState *bs, int argc, char **argv)
|
182
|
+
|
183
|
+
offset = cvtnum(argv[optind]);
|
184
|
+
if (offset < 0) {
|
185
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
186
|
+
+ print_cvtnum_err(offset, argv[optind]);
|
187
|
+
return 0;
|
188
|
+
}
|
189
|
+
|
190
|
+
optind++;
|
191
|
+
count = cvtnum(argv[optind]);
|
192
|
+
if (count < 0) {
|
193
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
194
|
+
+ print_cvtnum_err(count, argv[optind]);
|
195
|
+
return 0;
|
196
|
+
} else if (count >> BDRV_SECTOR_BITS > INT_MAX) {
|
197
|
+
printf("length cannot exceed %"PRIu64", given %s\n",
|
198
|
+
@@ -1867,7 +1882,7 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
|
199
|
+
|
200
|
+
offset = cvtnum(argv[1]);
|
201
|
+
if (offset < 0) {
|
202
|
+
- printf("non-numeric offset argument -- %s\n", argv[1]);
|
203
|
+
+ print_cvtnum_err(offset, argv[1]);
|
204
|
+
return 0;
|
205
|
+
} else if (offset & 0x1ff) {
|
206
|
+
printf("offset %" PRId64 " is not sector aligned\n",
|
207
|
+
@@ -1878,7 +1893,7 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
|
208
|
+
if (argc == 3) {
|
209
|
+
nb_sectors = cvtnum(argv[2]);
|
210
|
+
if (nb_sectors < 0) {
|
211
|
+
- printf("non-numeric length argument -- %s\n", argv[2]);
|
212
|
+
+ print_cvtnum_err(nb_sectors, argv[2]);
|
213
|
+
return 0;
|
214
|
+
} else if (nb_sectors > INT_MAX) {
|
215
|
+
printf("length argument cannot exceed %d, given %s\n",
|
216
|
+
--
|
217
|
+
1.8.3.1
|
218
|
+
|
@@ -0,0 +1,737 @@
|
|
1
|
+
From 2653e21a25d8fb99479337c785e81b07f755acda Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:24 +0100
|
4
|
+
Subject: [PATCH 05/27] qemu-io: Don't use global bs in command implementations
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-6-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68433
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 05/21] qemu-io: Don't use global bs in command implementations
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
Pass in the BlockDriverState to the command handlers instead of using
|
18
|
+
the global variable. This is an important step to make the commands
|
19
|
+
usable outside of qemu-io.
|
20
|
+
|
21
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
22
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
23
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
24
|
+
(cherry picked from commit 734c3b85cb72d264ad2b38a87f30304e05de2cb1)
|
25
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
26
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
27
|
+
|
28
|
+
Conflicts:
|
29
|
+
qemu-io.c
|
30
|
+
Number of arguments to bdrv_co_write_zeroes
|
31
|
+
bdrv_unref used downstream instead of bdrv_delete
|
32
|
+
downstream, local_err used for bdrv_open
|
33
|
+
downstream, error_abort used for bdrv_new
|
34
|
+
map_is_allocated was never backported from a00e81e98f71
|
35
|
+
sleep_f was backported, adjust its signature
|
36
|
+
|
37
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
38
|
+
---
|
39
|
+
cmd.c | 6 ++-
|
40
|
+
cmd.h | 8 ++-
|
41
|
+
qemu-io.c | 164 ++++++++++++++++++++++++++++++++++----------------------------
|
42
|
+
3 files changed, 99 insertions(+), 79 deletions(-)
|
43
|
+
|
44
|
+
diff --git a/cmd.c b/cmd.c
|
45
|
+
index 214c6f7..d501aab 100644
|
46
|
+
--- a/cmd.c
|
47
|
+
+++ b/cmd.c
|
48
|
+
@@ -57,7 +57,7 @@ check_command(
|
49
|
+
const cmdinfo_t *ci)
|
50
|
+
{
|
51
|
+
if (check_func)
|
52
|
+
- return check_func(ci);
|
53
|
+
+ return check_func(qemuio_bs, ci);
|
54
|
+
return 1;
|
55
|
+
}
|
56
|
+
|
57
|
+
@@ -103,7 +103,7 @@ command(
|
58
|
+
return 0;
|
59
|
+
}
|
60
|
+
optind = 0;
|
61
|
+
- return ct->cfunc(argc, argv);
|
62
|
+
+ return ct->cfunc(qemuio_bs, argc, argv);
|
63
|
+
}
|
64
|
+
|
65
|
+
const cmdinfo_t *
|
66
|
+
@@ -452,6 +452,7 @@ static cmdinfo_t quit_cmd;
|
67
|
+
/* ARGSUSED */
|
68
|
+
static int
|
69
|
+
quit_f(
|
70
|
+
+ BlockDriverState *bs,
|
71
|
+
int argc,
|
72
|
+
char **argv)
|
73
|
+
{
|
74
|
+
@@ -490,6 +491,7 @@ help_all(void)
|
75
|
+
|
76
|
+
static int
|
77
|
+
help_f(
|
78
|
+
+ BlockDriverState *bs,
|
79
|
+
int argc,
|
80
|
+
char **argv)
|
81
|
+
{
|
82
|
+
diff --git a/cmd.h b/cmd.h
|
83
|
+
index 4dcfe88..ccf6336 100644
|
84
|
+
--- a/cmd.h
|
85
|
+
+++ b/cmd.h
|
86
|
+
|
87
|
+
#ifndef __COMMAND_H__
|
88
|
+
#define __COMMAND_H__
|
89
|
+
|
90
|
+
+#include "qemu-common.h"
|
91
|
+
+
|
92
|
+
#define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */
|
93
|
+
|
94
|
+
-typedef int (*cfunc_t)(int argc, char **argv);
|
95
|
+
+extern BlockDriverState *qemuio_bs;
|
96
|
+
+
|
97
|
+
+typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
|
98
|
+
typedef void (*helpfunc_t)(void);
|
99
|
+
|
100
|
+
typedef struct cmdinfo {
|
101
|
+
@@ -41,7 +45,7 @@ extern int ncmds;
|
102
|
+
void help_init(void);
|
103
|
+
void quit_init(void);
|
104
|
+
|
105
|
+
-typedef int (*checkfunc_t)(const cmdinfo_t *ci);
|
106
|
+
+typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
|
107
|
+
|
108
|
+
void add_command(const cmdinfo_t *ci);
|
109
|
+
void add_user_command(char *optarg);
|
110
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
111
|
+
index e4fa2fc..c3cc4f3 100644
|
112
|
+
--- a/qemu-io.c
|
113
|
+
+++ b/qemu-io.c
|
114
|
+
|
115
|
+
#define CMD_NOFILE_OK 0x01
|
116
|
+
|
117
|
+
char *progname;
|
118
|
+
-static BlockDriverState *bs;
|
119
|
+
|
120
|
+
+BlockDriverState *qemuio_bs;
|
121
|
+
static int misalign;
|
122
|
+
|
123
|
+
static int64_t cvtnum(const char *s)
|
124
|
+
@@ -67,7 +67,7 @@ static int parse_pattern(const char *arg)
|
125
|
+
*/
|
126
|
+
|
127
|
+
#define MISALIGN_OFFSET 16
|
128
|
+
-static void *qemu_io_alloc(size_t len, int pattern)
|
129
|
+
+static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
|
130
|
+
{
|
131
|
+
void *buf;
|
132
|
+
|
133
|
+
@@ -140,7 +140,8 @@ static void print_report(const char *op, struct timeval *t, int64_t offset,
|
134
|
+
* vector matching it.
|
135
|
+
*/
|
136
|
+
static void *
|
137
|
+
-create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
|
138
|
+
+create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
|
139
|
+
+ int pattern)
|
140
|
+
{
|
141
|
+
size_t *sizes = g_new0(size_t, nr_iov);
|
142
|
+
size_t count = 0;
|
143
|
+
@@ -176,7 +177,7 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
|
144
|
+
|
145
|
+
qemu_iovec_init(qiov, nr_iov);
|
146
|
+
|
147
|
+
- buf = p = qemu_io_alloc(count, pattern);
|
148
|
+
+ buf = p = qemu_io_alloc(bs, count, pattern);
|
149
|
+
|
150
|
+
for (i = 0; i < nr_iov; i++) {
|
151
|
+
qemu_iovec_add(qiov, p, sizes[i]);
|
152
|
+
@@ -188,7 +189,8 @@ fail:
|
153
|
+
return buf;
|
154
|
+
}
|
155
|
+
|
156
|
+
-static int do_read(char *buf, int64_t offset, int count, int *total)
|
157
|
+
+static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
158
|
+
+ int *total)
|
159
|
+
{
|
160
|
+
int ret;
|
161
|
+
|
162
|
+
@@ -200,7 +202,8 @@ static int do_read(char *buf, int64_t offset, int count, int *total)
|
163
|
+
return 1;
|
164
|
+
}
|
165
|
+
|
166
|
+
-static int do_write(char *buf, int64_t offset, int count, int *total)
|
167
|
+
+static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
168
|
+
+ int *total)
|
169
|
+
{
|
170
|
+
int ret;
|
171
|
+
|
172
|
+
@@ -212,7 +215,8 @@ static int do_write(char *buf, int64_t offset, int count, int *total)
|
173
|
+
return 1;
|
174
|
+
}
|
175
|
+
|
176
|
+
-static int do_pread(char *buf, int64_t offset, int count, int *total)
|
177
|
+
+static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
178
|
+
+ int *total)
|
179
|
+
{
|
180
|
+
*total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
|
181
|
+
if (*total < 0) {
|
182
|
+
@@ -221,7 +225,8 @@ static int do_pread(char *buf, int64_t offset, int count, int *total)
|
183
|
+
return 1;
|
184
|
+
}
|
185
|
+
|
186
|
+
-static int do_pwrite(char *buf, int64_t offset, int count, int *total)
|
187
|
+
+static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
188
|
+
+ int *total)
|
189
|
+
{
|
190
|
+
*total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
|
191
|
+
if (*total < 0) {
|
192
|
+
@@ -231,6 +236,7 @@ static int do_pwrite(char *buf, int64_t offset, int count, int *total)
|
193
|
+
}
|
194
|
+
|
195
|
+
typedef struct {
|
196
|
+
+ BlockDriverState *bs;
|
197
|
+
int64_t offset;
|
198
|
+
int count;
|
199
|
+
int *total;
|
200
|
+
@@ -242,7 +248,7 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque)
|
201
|
+
{
|
202
|
+
CoWriteZeroes *data = opaque;
|
203
|
+
|
204
|
+
- data->ret = bdrv_co_write_zeroes(bs, data->offset / BDRV_SECTOR_SIZE,
|
205
|
+
+ data->ret = bdrv_co_write_zeroes(data->bs, data->offset / BDRV_SECTOR_SIZE,
|
206
|
+
data->count / BDRV_SECTOR_SIZE, 0);
|
207
|
+
data->done = true;
|
208
|
+
if (data->ret < 0) {
|
209
|
+
@@ -253,10 +259,12 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque)
|
210
|
+
*data->total = data->count;
|
211
|
+
}
|
212
|
+
|
213
|
+
-static int do_co_write_zeroes(int64_t offset, int count, int *total)
|
214
|
+
+static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
|
215
|
+
+ int *total)
|
216
|
+
{
|
217
|
+
Coroutine *co;
|
218
|
+
CoWriteZeroes data = {
|
219
|
+
+ .bs = bs,
|
220
|
+
.offset = offset,
|
221
|
+
.count = count,
|
222
|
+
.total = total,
|
223
|
+
@@ -275,7 +283,8 @@ static int do_co_write_zeroes(int64_t offset, int count, int *total)
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
-static int do_write_compressed(char *buf, int64_t offset, int count, int *total)
|
228
|
+
+static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
|
229
|
+
+ int count, int *total)
|
230
|
+
{
|
231
|
+
int ret;
|
232
|
+
|
233
|
+
@@ -287,7 +296,8 @@ static int do_write_compressed(char *buf, int64_t offset, int count, int *total)
|
234
|
+
return 1;
|
235
|
+
}
|
236
|
+
|
237
|
+
-static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
|
238
|
+
+static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
|
239
|
+
+ int count, int *total)
|
240
|
+
{
|
241
|
+
*total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
|
242
|
+
if (*total < 0) {
|
243
|
+
@@ -296,7 +306,8 @@ static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
|
244
|
+
return 1;
|
245
|
+
}
|
246
|
+
|
247
|
+
-static int do_save_vmstate(char *buf, int64_t offset, int count, int *total)
|
248
|
+
+static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
|
249
|
+
+ int count, int *total)
|
250
|
+
{
|
251
|
+
*total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
|
252
|
+
if (*total < 0) {
|
253
|
+
@@ -311,7 +322,8 @@ static void aio_rw_done(void *opaque, int ret)
|
254
|
+
*(int *)opaque = ret;
|
255
|
+
}
|
256
|
+
|
257
|
+
-static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
|
258
|
+
+static int do_aio_readv(BlockDriverState *bs, QEMUIOVector *qiov,
|
259
|
+
+ int64_t offset, int *total)
|
260
|
+
{
|
261
|
+
int async_ret = NOT_DONE;
|
262
|
+
|
263
|
+
@@ -325,7 +337,8 @@ static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
|
264
|
+
return async_ret < 0 ? async_ret : 1;
|
265
|
+
}
|
266
|
+
|
267
|
+
-static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)
|
268
|
+
+static int do_aio_writev(BlockDriverState *bs, QEMUIOVector *qiov,
|
269
|
+
+ int64_t offset, int *total)
|
270
|
+
{
|
271
|
+
int async_ret = NOT_DONE;
|
272
|
+
|
273
|
+
@@ -354,7 +367,8 @@ static void multiwrite_cb(void *opaque, int ret)
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
-static int do_aio_multiwrite(BlockRequest* reqs, int num_reqs, int *total)
|
278
|
+
+static int do_aio_multiwrite(BlockDriverState *bs, BlockRequest* reqs,
|
279
|
+
+ int num_reqs, int *total)
|
280
|
+
{
|
281
|
+
int i, ret;
|
282
|
+
struct multiwrite_async_ret async_ret = {
|
283
|
+
@@ -403,7 +417,7 @@ static void read_help(void)
|
284
|
+
"\n");
|
285
|
+
}
|
286
|
+
|
287
|
+
-static int read_f(int argc, char **argv);
|
288
|
+
+static int read_f(BlockDriverState *bs, int argc, char **argv);
|
289
|
+
|
290
|
+
static const cmdinfo_t read_cmd = {
|
291
|
+
.name = "read",
|
292
|
+
@@ -416,7 +430,7 @@ static const cmdinfo_t read_cmd = {
|
293
|
+
.help = read_help,
|
294
|
+
};
|
295
|
+
|
296
|
+
-static int read_f(int argc, char **argv)
|
297
|
+
+static int read_f(BlockDriverState *bs, int argc, char **argv)
|
298
|
+
{
|
299
|
+
struct timeval t1, t2;
|
300
|
+
int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
|
301
|
+
@@ -522,15 +536,15 @@ static int read_f(int argc, char **argv)
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
- buf = qemu_io_alloc(count, 0xab);
|
306
|
+
+ buf = qemu_io_alloc(bs, count, 0xab);
|
307
|
+
|
308
|
+
gettimeofday(&t1, NULL);
|
309
|
+
if (pflag) {
|
310
|
+
- cnt = do_pread(buf, offset, count, &total);
|
311
|
+
+ cnt = do_pread(bs, buf, offset, count, &total);
|
312
|
+
} else if (bflag) {
|
313
|
+
- cnt = do_load_vmstate(buf, offset, count, &total);
|
314
|
+
+ cnt = do_load_vmstate(bs, buf, offset, count, &total);
|
315
|
+
} else {
|
316
|
+
- cnt = do_read(buf, offset, count, &total);
|
317
|
+
+ cnt = do_read(bs, buf, offset, count, &total);
|
318
|
+
}
|
319
|
+
gettimeofday(&t2, NULL);
|
320
|
+
|
321
|
+
@@ -587,7 +601,7 @@ static void readv_help(void)
|
322
|
+
"\n");
|
323
|
+
}
|
324
|
+
|
325
|
+
-static int readv_f(int argc, char **argv);
|
326
|
+
+static int readv_f(BlockDriverState *bs, int argc, char **argv);
|
327
|
+
|
328
|
+
static const cmdinfo_t readv_cmd = {
|
329
|
+
.name = "readv",
|
330
|
+
@@ -599,7 +613,7 @@ static const cmdinfo_t readv_cmd = {
|
331
|
+
.help = readv_help,
|
332
|
+
};
|
333
|
+
|
334
|
+
-static int readv_f(int argc, char **argv)
|
335
|
+
+static int readv_f(BlockDriverState *bs, int argc, char **argv)
|
336
|
+
{
|
337
|
+
struct timeval t1, t2;
|
338
|
+
int Cflag = 0, qflag = 0, vflag = 0;
|
339
|
+
@@ -655,13 +669,13 @@ static int readv_f(int argc, char **argv)
|
340
|
+
}
|
341
|
+
|
342
|
+
nr_iov = argc - optind;
|
343
|
+
- buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
|
344
|
+
+ buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, 0xab);
|
345
|
+
if (buf == NULL) {
|
346
|
+
return 0;
|
347
|
+
}
|
348
|
+
|
349
|
+
gettimeofday(&t1, NULL);
|
350
|
+
- cnt = do_aio_readv(&qiov, offset, &total);
|
351
|
+
+ cnt = do_aio_readv(bs, &qiov, offset, &total);
|
352
|
+
gettimeofday(&t2, NULL);
|
353
|
+
|
354
|
+
if (cnt < 0) {
|
355
|
+
@@ -718,7 +732,7 @@ static void write_help(void)
|
356
|
+
"\n");
|
357
|
+
}
|
358
|
+
|
359
|
+
-static int write_f(int argc, char **argv);
|
360
|
+
+static int write_f(BlockDriverState *bs, int argc, char **argv);
|
361
|
+
|
362
|
+
static const cmdinfo_t write_cmd = {
|
363
|
+
.name = "write",
|
364
|
+
@@ -731,7 +745,7 @@ static const cmdinfo_t write_cmd = {
|
365
|
+
.help = write_help,
|
366
|
+
};
|
367
|
+
|
368
|
+
-static int write_f(int argc, char **argv)
|
369
|
+
+static int write_f(BlockDriverState *bs, int argc, char **argv)
|
370
|
+
{
|
371
|
+
struct timeval t1, t2;
|
372
|
+
int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
|
373
|
+
@@ -818,20 +832,20 @@ static int write_f(int argc, char **argv)
|
374
|
+
}
|
375
|
+
|
376
|
+
if (!zflag) {
|
377
|
+
- buf = qemu_io_alloc(count, pattern);
|
378
|
+
+ buf = qemu_io_alloc(bs, count, pattern);
|
379
|
+
}
|
380
|
+
|
381
|
+
gettimeofday(&t1, NULL);
|
382
|
+
if (pflag) {
|
383
|
+
- cnt = do_pwrite(buf, offset, count, &total);
|
384
|
+
+ cnt = do_pwrite(bs, buf, offset, count, &total);
|
385
|
+
} else if (bflag) {
|
386
|
+
- cnt = do_save_vmstate(buf, offset, count, &total);
|
387
|
+
+ cnt = do_save_vmstate(bs, buf, offset, count, &total);
|
388
|
+
} else if (zflag) {
|
389
|
+
- cnt = do_co_write_zeroes(offset, count, &total);
|
390
|
+
+ cnt = do_co_write_zeroes(bs, offset, count, &total);
|
391
|
+
} else if (cflag) {
|
392
|
+
- cnt = do_write_compressed(buf, offset, count, &total);
|
393
|
+
+ cnt = do_write_compressed(bs, buf, offset, count, &total);
|
394
|
+
} else {
|
395
|
+
- cnt = do_write(buf, offset, count, &total);
|
396
|
+
+ cnt = do_write(bs, buf, offset, count, &total);
|
397
|
+
}
|
398
|
+
gettimeofday(&t2, NULL);
|
399
|
+
|
400
|
+
@@ -874,7 +888,7 @@ writev_help(void)
|
401
|
+
"\n");
|
402
|
+
}
|
403
|
+
|
404
|
+
-static int writev_f(int argc, char **argv);
|
405
|
+
+static int writev_f(BlockDriverState *bs, int argc, char **argv);
|
406
|
+
|
407
|
+
static const cmdinfo_t writev_cmd = {
|
408
|
+
.name = "writev",
|
409
|
+
@@ -886,7 +900,7 @@ static const cmdinfo_t writev_cmd = {
|
410
|
+
.help = writev_help,
|
411
|
+
};
|
412
|
+
|
413
|
+
-static int writev_f(int argc, char **argv)
|
414
|
+
+static int writev_f(BlockDriverState *bs, int argc, char **argv)
|
415
|
+
{
|
416
|
+
struct timeval t1, t2;
|
417
|
+
int Cflag = 0, qflag = 0;
|
418
|
+
@@ -936,13 +950,13 @@ static int writev_f(int argc, char **argv)
|
419
|
+
}
|
420
|
+
|
421
|
+
nr_iov = argc - optind;
|
422
|
+
- buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
|
423
|
+
+ buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, pattern);
|
424
|
+
if (buf == NULL) {
|
425
|
+
return 0;
|
426
|
+
}
|
427
|
+
|
428
|
+
gettimeofday(&t1, NULL);
|
429
|
+
- cnt = do_aio_writev(&qiov, offset, &total);
|
430
|
+
+ cnt = do_aio_writev(bs, &qiov, offset, &total);
|
431
|
+
gettimeofday(&t2, NULL);
|
432
|
+
|
433
|
+
if (cnt < 0) {
|
434
|
+
@@ -983,7 +997,7 @@ static void multiwrite_help(void)
|
435
|
+
"\n");
|
436
|
+
}
|
437
|
+
|
438
|
+
-static int multiwrite_f(int argc, char **argv);
|
439
|
+
+static int multiwrite_f(BlockDriverState *bs, int argc, char **argv);
|
440
|
+
|
441
|
+
static const cmdinfo_t multiwrite_cmd = {
|
442
|
+
.name = "multiwrite",
|
443
|
+
@@ -995,7 +1009,7 @@ static const cmdinfo_t multiwrite_cmd = {
|
444
|
+
.help = multiwrite_help,
|
445
|
+
};
|
446
|
+
|
447
|
+
-static int multiwrite_f(int argc, char **argv)
|
448
|
+
+static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
|
449
|
+
{
|
450
|
+
struct timeval t1, t2;
|
451
|
+
int Cflag = 0, qflag = 0;
|
452
|
+
@@ -1076,7 +1090,7 @@ static int multiwrite_f(int argc, char **argv)
|
453
|
+
nr_iov = j - optind;
|
454
|
+
|
455
|
+
/* Build request */
|
456
|
+
- buf[i] = create_iovec(&qiovs[i], &argv[optind], nr_iov, pattern);
|
457
|
+
+ buf[i] = create_iovec(bs, &qiovs[i], &argv[optind], nr_iov, pattern);
|
458
|
+
if (buf[i] == NULL) {
|
459
|
+
goto out;
|
460
|
+
}
|
461
|
+
@@ -1094,7 +1108,7 @@ static int multiwrite_f(int argc, char **argv)
|
462
|
+
nr_reqs = i;
|
463
|
+
|
464
|
+
gettimeofday(&t1, NULL);
|
465
|
+
- cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
|
466
|
+
+ cnt = do_aio_multiwrite(bs, reqs, nr_reqs, &total);
|
467
|
+
gettimeofday(&t2, NULL);
|
468
|
+
|
469
|
+
if (cnt < 0) {
|
470
|
+
@@ -1222,7 +1236,7 @@ static void aio_read_help(void)
|
471
|
+
"\n");
|
472
|
+
}
|
473
|
+
|
474
|
+
-static int aio_read_f(int argc, char **argv);
|
475
|
+
+static int aio_read_f(BlockDriverState *bs, int argc, char **argv);
|
476
|
+
|
477
|
+
static const cmdinfo_t aio_read_cmd = {
|
478
|
+
.name = "aio_read",
|
479
|
+
@@ -1234,7 +1248,7 @@ static const cmdinfo_t aio_read_cmd = {
|
480
|
+
.help = aio_read_help,
|
481
|
+
};
|
482
|
+
|
483
|
+
-static int aio_read_f(int argc, char **argv)
|
484
|
+
+static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
|
485
|
+
{
|
486
|
+
int nr_iov, c;
|
487
|
+
struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
|
488
|
+
@@ -1285,7 +1299,7 @@ static int aio_read_f(int argc, char **argv)
|
489
|
+
}
|
490
|
+
|
491
|
+
nr_iov = argc - optind;
|
492
|
+
- ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
|
493
|
+
+ ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, 0xab);
|
494
|
+
if (ctx->buf == NULL) {
|
495
|
+
g_free(ctx);
|
496
|
+
return 0;
|
497
|
+
@@ -1317,7 +1331,7 @@ static void aio_write_help(void)
|
498
|
+
"\n");
|
499
|
+
}
|
500
|
+
|
501
|
+
-static int aio_write_f(int argc, char **argv);
|
502
|
+
+static int aio_write_f(BlockDriverState *bs, int argc, char **argv);
|
503
|
+
|
504
|
+
static const cmdinfo_t aio_write_cmd = {
|
505
|
+
.name = "aio_write",
|
506
|
+
@@ -1329,7 +1343,7 @@ static const cmdinfo_t aio_write_cmd = {
|
507
|
+
.help = aio_write_help,
|
508
|
+
};
|
509
|
+
|
510
|
+
-static int aio_write_f(int argc, char **argv)
|
511
|
+
+static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
|
512
|
+
{
|
513
|
+
int nr_iov, c;
|
514
|
+
int pattern = 0xcd;
|
515
|
+
@@ -1377,7 +1391,7 @@ static int aio_write_f(int argc, char **argv)
|
516
|
+
}
|
517
|
+
|
518
|
+
nr_iov = argc - optind;
|
519
|
+
- ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
|
520
|
+
+ ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, pattern);
|
521
|
+
if (ctx->buf == NULL) {
|
522
|
+
g_free(ctx);
|
523
|
+
return 0;
|
524
|
+
@@ -1389,7 +1403,7 @@ static int aio_write_f(int argc, char **argv)
|
525
|
+
return 0;
|
526
|
+
}
|
527
|
+
|
528
|
+
-static int aio_flush_f(int argc, char **argv)
|
529
|
+
+static int aio_flush_f(BlockDriverState *bs, int argc, char **argv)
|
530
|
+
{
|
531
|
+
bdrv_drain_all();
|
532
|
+
return 0;
|
533
|
+
@@ -1401,7 +1415,7 @@ static const cmdinfo_t aio_flush_cmd = {
|
534
|
+
.oneline = "completes all outstanding aio requests"
|
535
|
+
};
|
536
|
+
|
537
|
+
-static int flush_f(int argc, char **argv)
|
538
|
+
+static int flush_f(BlockDriverState *bs, int argc, char **argv)
|
539
|
+
{
|
540
|
+
bdrv_flush(bs);
|
541
|
+
return 0;
|
542
|
+
@@ -1414,7 +1428,7 @@ static const cmdinfo_t flush_cmd = {
|
543
|
+
.oneline = "flush all in-core file state to disk",
|
544
|
+
};
|
545
|
+
|
546
|
+
-static int truncate_f(int argc, char **argv)
|
547
|
+
+static int truncate_f(BlockDriverState *bs, int argc, char **argv)
|
548
|
+
{
|
549
|
+
int64_t offset;
|
550
|
+
int ret;
|
551
|
+
@@ -1444,7 +1458,7 @@ static const cmdinfo_t truncate_cmd = {
|
552
|
+
.oneline = "truncates the current file at the given offset",
|
553
|
+
};
|
554
|
+
|
555
|
+
-static int length_f(int argc, char **argv)
|
556
|
+
+static int length_f(BlockDriverState *bs, int argc, char **argv)
|
557
|
+
{
|
558
|
+
int64_t size;
|
559
|
+
char s1[64];
|
560
|
+
@@ -1469,7 +1483,7 @@ static const cmdinfo_t length_cmd = {
|
561
|
+
};
|
562
|
+
|
563
|
+
|
564
|
+
-static int info_f(int argc, char **argv)
|
565
|
+
+static int info_f(BlockDriverState *bs, int argc, char **argv)
|
566
|
+
{
|
567
|
+
BlockDriverInfo bdi;
|
568
|
+
ImageInfoSpecific *spec_info;
|
569
|
+
@@ -1528,7 +1542,7 @@ static void discard_help(void)
|
570
|
+
"\n");
|
571
|
+
}
|
572
|
+
|
573
|
+
-static int discard_f(int argc, char **argv);
|
574
|
+
+static int discard_f(BlockDriverState *bs, int argc, char **argv);
|
575
|
+
|
576
|
+
static const cmdinfo_t discard_cmd = {
|
577
|
+
.name = "discard",
|
578
|
+
@@ -1541,7 +1555,7 @@ static const cmdinfo_t discard_cmd = {
|
579
|
+
.help = discard_help,
|
580
|
+
};
|
581
|
+
|
582
|
+
-static int discard_f(int argc, char **argv)
|
583
|
+
+static int discard_f(BlockDriverState *bs, int argc, char **argv)
|
584
|
+
{
|
585
|
+
struct timeval t1, t2;
|
586
|
+
int Cflag = 0, qflag = 0;
|
587
|
+
@@ -1599,7 +1613,7 @@ out:
|
588
|
+
return 0;
|
589
|
+
}
|
590
|
+
|
591
|
+
-static int alloc_f(int argc, char **argv)
|
592
|
+
+static int alloc_f(BlockDriverState *bs, int argc, char **argv)
|
593
|
+
{
|
594
|
+
int64_t offset, sector_num;
|
595
|
+
int nb_sectors, remaining;
|
596
|
+
@@ -1664,7 +1678,7 @@ static const cmdinfo_t alloc_cmd = {
|
597
|
+
.oneline = "checks if a sector is present in the file",
|
598
|
+
};
|
599
|
+
|
600
|
+
-static int map_f(int argc, char **argv)
|
601
|
+
+static int map_f(BlockDriverState *bs, int argc, char **argv)
|
602
|
+
{
|
603
|
+
int64_t offset;
|
604
|
+
int64_t nb_sectors;
|
605
|
+
@@ -1700,7 +1714,7 @@ static const cmdinfo_t map_cmd = {
|
606
|
+
.oneline = "prints the allocated areas of a file",
|
607
|
+
};
|
608
|
+
|
609
|
+
-static int break_f(int argc, char **argv)
|
610
|
+
+static int break_f(BlockDriverState *bs, int argc, char **argv)
|
611
|
+
{
|
612
|
+
int ret;
|
613
|
+
|
614
|
+
@@ -1722,7 +1736,7 @@ static const cmdinfo_t break_cmd = {
|
615
|
+
"request as tag",
|
616
|
+
};
|
617
|
+
|
618
|
+
-static int resume_f(int argc, char **argv)
|
619
|
+
+static int resume_f(BlockDriverState *bs, int argc, char **argv)
|
620
|
+
{
|
621
|
+
int ret;
|
622
|
+
|
623
|
+
@@ -1743,7 +1757,7 @@ static const cmdinfo_t resume_cmd = {
|
624
|
+
.oneline = "resumes the request tagged as tag",
|
625
|
+
};
|
626
|
+
|
627
|
+
-static int wait_break_f(int argc, char **argv)
|
628
|
+
+static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
|
629
|
+
{
|
630
|
+
while (!bdrv_debug_is_suspended(bs, argv[1])) {
|
631
|
+
qemu_aio_wait();
|
632
|
+
@@ -1761,7 +1775,7 @@ static const cmdinfo_t wait_break_cmd = {
|
633
|
+
.oneline = "waits for the suspension of a request",
|
634
|
+
};
|
635
|
+
|
636
|
+
-static int abort_f(int argc, char **argv)
|
637
|
+
+static int abort_f(BlockDriverState *bs, int argc, char **argv)
|
638
|
+
{
|
639
|
+
abort();
|
640
|
+
}
|
641
|
+
@@ -1773,10 +1787,10 @@ static const cmdinfo_t abort_cmd = {
|
642
|
+
.oneline = "simulate a program crash using abort(3)",
|
643
|
+
};
|
644
|
+
|
645
|
+
-static int close_f(int argc, char **argv)
|
646
|
+
+static int close_f(BlockDriverState *bs, int argc, char **argv)
|
647
|
+
{
|
648
|
+
bdrv_unref(bs);
|
649
|
+
- bs = NULL;
|
650
|
+
+ qemuio_bs = NULL;
|
651
|
+
return 0;
|
652
|
+
}
|
653
|
+
|
654
|
+
@@ -1793,7 +1807,7 @@ static void sleep_cb(void *opaque)
|
655
|
+
*expired = true;
|
656
|
+
}
|
657
|
+
|
658
|
+
-static int sleep_f(int argc, char **argv)
|
659
|
+
+static int sleep_f(BlockDriverState *bs, int argc, char **argv)
|
660
|
+
{
|
661
|
+
char *endptr;
|
662
|
+
long ms;
|
663
|
+
@@ -1831,27 +1845,27 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
|
664
|
+
{
|
665
|
+
Error *local_err = NULL;
|
666
|
+
|
667
|
+
- if (bs) {
|
668
|
+
+ if (qemuio_bs) {
|
669
|
+
fprintf(stderr, "file open already, try 'help close'\n");
|
670
|
+
return 1;
|
671
|
+
}
|
672
|
+
|
673
|
+
if (growable) {
|
674
|
+
- if (bdrv_file_open(&bs, name, opts, flags, &local_err)) {
|
675
|
+
+ if (bdrv_file_open(&qemuio_bs, name, opts, flags, &local_err)) {
|
676
|
+
fprintf(stderr, "%s: can't open device %s: %s\n", progname, name,
|
677
|
+
error_get_pretty(local_err));
|
678
|
+
error_free(local_err);
|
679
|
+
return 1;
|
680
|
+
}
|
681
|
+
} else {
|
682
|
+
- bs = bdrv_new("hda", &error_abort);
|
683
|
+
+ qemuio_bs = bdrv_new("hda", &error_abort);
|
684
|
+
|
685
|
+
- if (bdrv_open(bs, name, opts, flags, NULL, &local_err) < 0) {
|
686
|
+
+ if (bdrv_open(qemuio_bs, name, opts, flags, NULL, &local_err) < 0) {
|
687
|
+
fprintf(stderr, "%s: can't open device %s: %s\n", progname, name,
|
688
|
+
error_get_pretty(local_err));
|
689
|
+
error_free(local_err);
|
690
|
+
- bdrv_unref(bs);
|
691
|
+
- bs = NULL;
|
692
|
+
+ bdrv_unref(qemuio_bs);
|
693
|
+
+ qemuio_bs = NULL;
|
694
|
+
return 1;
|
695
|
+
}
|
696
|
+
}
|
697
|
+
@@ -1877,7 +1891,7 @@ static void open_help(void)
|
698
|
+
"\n");
|
699
|
+
}
|
700
|
+
|
701
|
+
-static int open_f(int argc, char **argv);
|
702
|
+
+static int open_f(BlockDriverState *bs, int argc, char **argv);
|
703
|
+
|
704
|
+
static const cmdinfo_t open_cmd = {
|
705
|
+
.name = "open",
|
706
|
+
@@ -1900,7 +1914,7 @@ static QemuOptsList empty_opts = {
|
707
|
+
},
|
708
|
+
};
|
709
|
+
|
710
|
+
-static int open_f(int argc, char **argv)
|
711
|
+
+static int open_f(BlockDriverState *bs, int argc, char **argv)
|
712
|
+
{
|
713
|
+
int flags = 0;
|
714
|
+
int readonly = 0;
|
715
|
+
@@ -1948,7 +1962,7 @@ static int open_f(int argc, char **argv)
|
716
|
+
return openfile(argv[optind], flags, growable, opts);
|
717
|
+
}
|
718
|
+
|
719
|
+
-static int init_check_command(const cmdinfo_t *ct)
|
720
|
+
+static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
|
721
|
+
{
|
722
|
+
if (ct->flags & CMD_FLAG_GLOBAL) {
|
723
|
+
return 1;
|
724
|
+
@@ -2117,8 +2131,8 @@ int main(int argc, char **argv)
|
725
|
+
*/
|
726
|
+
bdrv_drain_all();
|
727
|
+
|
728
|
+
- if (bs) {
|
729
|
+
- bdrv_unref(bs);
|
730
|
+
+ if (qemuio_bs) {
|
731
|
+
+ bdrv_unref(qemuio_bs);
|
732
|
+
}
|
733
|
+
return 0;
|
734
|
+
}
|
735
|
+
--
|
736
|
+
1.8.3.1
|
737
|
+
|
@@ -0,0 +1,163 @@
|
|
1
|
+
From c73b87743086200c3f9ad485dcd4e71bdee27881 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:26 +0100
|
4
|
+
Subject: [PATCH 07/27] qemu-io: Factor out qemuio_command
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-8-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68438
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 07/21] qemu-io: Factor out qemuio_command
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
It's duplicated code. Move it to qemu-io-cmds.c because it's not
|
18
|
+
dependent on any static data of the qemu-io tool.
|
19
|
+
|
20
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
21
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
22
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
23
|
+
(cherry picked from commit dd5832967ac3fe96bd5bf9f199639176998ead69)
|
24
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
cmd.c | 43 +++++--------------------------------------
|
28
|
+
cmd.h | 3 ++-
|
29
|
+
qemu-io-cmds.c | 24 ++++++++++++++++++++++++
|
30
|
+
3 files changed, 31 insertions(+), 39 deletions(-)
|
31
|
+
|
32
|
+
diff --git a/cmd.c b/cmd.c
|
33
|
+
index d501aab..7ae978f 100644
|
34
|
+
--- a/cmd.c
|
35
|
+
+++ b/cmd.c
|
36
|
+
@@ -138,28 +138,11 @@ static char *get_prompt(void);
|
37
|
+
|
38
|
+
void command_loop(void)
|
39
|
+
{
|
40
|
+
- int c, i, done = 0, fetchable = 0, prompted = 0;
|
41
|
+
+ int i, done = 0, fetchable = 0, prompted = 0;
|
42
|
+
char *input;
|
43
|
+
- char **v;
|
44
|
+
- const cmdinfo_t *ct;
|
45
|
+
|
46
|
+
for (i = 0; !done && i < ncmdline; i++) {
|
47
|
+
- input = strdup(cmdline[i]);
|
48
|
+
- if (!input) {
|
49
|
+
- fprintf(stderr, _("cannot strdup command '%s': %s\n"),
|
50
|
+
- cmdline[i], strerror(errno));
|
51
|
+
- exit(1);
|
52
|
+
- }
|
53
|
+
- v = breakline(input, &c);
|
54
|
+
- if (c) {
|
55
|
+
- ct = find_command(v[0]);
|
56
|
+
- if (ct) {
|
57
|
+
- done = command(ct, c, v);
|
58
|
+
- } else {
|
59
|
+
- fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
|
60
|
+
- }
|
61
|
+
- }
|
62
|
+
- doneline(input, v);
|
63
|
+
+ done = qemuio_command(cmdline[i]);
|
64
|
+
}
|
65
|
+
if (cmdline) {
|
66
|
+
g_free(cmdline);
|
67
|
+
@@ -179,20 +162,13 @@ void command_loop(void)
|
68
|
+
if (!fetchable) {
|
69
|
+
continue;
|
70
|
+
}
|
71
|
+
+
|
72
|
+
input = fetchline();
|
73
|
+
if (input == NULL) {
|
74
|
+
break;
|
75
|
+
}
|
76
|
+
- v = breakline(input, &c);
|
77
|
+
- if (c) {
|
78
|
+
- ct = find_command(v[0]);
|
79
|
+
- if (ct) {
|
80
|
+
- done = command(ct, c, v);
|
81
|
+
- } else {
|
82
|
+
- fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
|
83
|
+
- }
|
84
|
+
- }
|
85
|
+
- doneline(input, v);
|
86
|
+
+ done = qemuio_command(input);
|
87
|
+
+ free(input);
|
88
|
+
|
89
|
+
prompted = 0;
|
90
|
+
fetchable = 0;
|
91
|
+
@@ -328,15 +304,6 @@ char **breakline(char *input, int *count)
|
92
|
+
return rval;
|
93
|
+
}
|
94
|
+
|
95
|
+
-void
|
96
|
+
-doneline(
|
97
|
+
- char *input,
|
98
|
+
- char **vec)
|
99
|
+
-{
|
100
|
+
- free(input);
|
101
|
+
- free(vec);
|
102
|
+
-}
|
103
|
+
-
|
104
|
+
#define EXABYTES(x) ((long long)(x) << 60)
|
105
|
+
#define PETABYTES(x) ((long long)(x) << 50)
|
106
|
+
#define TERABYTES(x) ((long long)(x) << 40)
|
107
|
+
diff --git a/cmd.h b/cmd.h
|
108
|
+
index ccf6336..d676408 100644
|
109
|
+
--- a/cmd.h
|
110
|
+
+++ b/cmd.h
|
111
|
+
@@ -59,7 +59,6 @@ int command(const cmdinfo_t *ci, int argc, char **argv);
|
112
|
+
|
113
|
+
/* from input.h */
|
114
|
+
char **breakline(char *input, int *count);
|
115
|
+
-void doneline(char *input, char **vec);
|
116
|
+
char *fetchline(void);
|
117
|
+
|
118
|
+
void cvtstr(double value, char *str, size_t sz);
|
119
|
+
@@ -77,4 +76,6 @@ void timestr(struct timeval *tv, char *str, size_t sz, int flags);
|
120
|
+
|
121
|
+
extern char *progname;
|
122
|
+
|
123
|
+
+bool qemuio_command(const char *cmd);
|
124
|
+
+
|
125
|
+
#endif /* __COMMAND_H__ */
|
126
|
+
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
127
|
+
index efa6070..09e4099 100644
|
128
|
+
--- a/qemu-io-cmds.c
|
129
|
+
+++ b/qemu-io-cmds.c
|
130
|
+
@@ -1824,6 +1824,30 @@ static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
|
131
|
+
return 1;
|
132
|
+
}
|
133
|
+
|
134
|
+
+bool qemuio_command(const char *cmd)
|
135
|
+
+{
|
136
|
+
+ char *input;
|
137
|
+
+ const cmdinfo_t *ct;
|
138
|
+
+ char **v;
|
139
|
+
+ int c;
|
140
|
+
+ bool done = false;
|
141
|
+
+
|
142
|
+
+ input = g_strdup(cmd);
|
143
|
+
+ v = breakline(input, &c);
|
144
|
+
+ if (c) {
|
145
|
+
+ ct = find_command(v[0]);
|
146
|
+
+ if (ct) {
|
147
|
+
+ done = command(ct, c, v);
|
148
|
+
+ } else {
|
149
|
+
+ fprintf(stderr, "command \"%s\" not found\n", v[0]);
|
150
|
+
+ }
|
151
|
+
+ }
|
152
|
+
+ g_free(input);
|
153
|
+
+ g_free(v);
|
154
|
+
+
|
155
|
+
+ return done;
|
156
|
+
+}
|
157
|
+
+
|
158
|
+
static void __attribute((constructor)) init_qemuio_commands(void)
|
159
|
+
{
|
160
|
+
/* initialize commands */
|
161
|
+
--
|
162
|
+
1.8.3.1
|
163
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
From 862f45e0ad5a70d10bffa435d5331c444874e4d2 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:23 +0100
|
4
|
+
Subject: [PATCH 04/27] qemu-io: Handle cvtnum() errors in 'alloc'
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-5-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68431
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 04/21] qemu-io: Handle cvtnum() errors in 'alloc'
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
18
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
19
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
20
|
+
(cherry picked from commit cf49a6a00c19cabf4006d4f82bef26345043e7b5)
|
21
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
22
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
23
|
+
---
|
24
|
+
qemu-io.c | 9 ++++++++-
|
25
|
+
1 file changed, 8 insertions(+), 1 deletion(-)
|
26
|
+
|
27
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
28
|
+
index 3b5890e..e4fa2fc 100644
|
29
|
+
--- a/qemu-io.c
|
30
|
+
+++ b/qemu-io.c
|
31
|
+
@@ -1608,7 +1608,10 @@ static int alloc_f(int argc, char **argv)
|
32
|
+
int ret;
|
33
|
+
|
34
|
+
offset = cvtnum(argv[1]);
|
35
|
+
- if (offset & 0x1ff) {
|
36
|
+
+ if (offset < 0) {
|
37
|
+
+ printf("non-numeric offset argument -- %s\n", argv[1]);
|
38
|
+
+ return 0;
|
39
|
+
+ } else if (offset & 0x1ff) {
|
40
|
+
printf("offset %" PRId64 " is not sector aligned\n",
|
41
|
+
offset);
|
42
|
+
return 0;
|
43
|
+
@@ -1616,6 +1619,10 @@ static int alloc_f(int argc, char **argv)
|
44
|
+
|
45
|
+
if (argc == 3) {
|
46
|
+
nb_sectors = cvtnum(argv[2]);
|
47
|
+
+ if (nb_sectors < 0) {
|
48
|
+
+ printf("non-numeric length argument -- %s\n", argv[2]);
|
49
|
+
+ return 0;
|
50
|
+
+ }
|
51
|
+
} else {
|
52
|
+
nb_sectors = 1;
|
53
|
+
}
|
54
|
+
--
|
55
|
+
1.8.3.1
|
56
|
+
|
@@ -0,0 +1,240 @@
|
|
1
|
+
From 0dfb1b6f831f5b2a1fdf5e77330db3c95db2e464 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:33 +0100
|
4
|
+
Subject: [PATCH 14/27] qemu-io: Interface cleanup
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-15-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68444
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 14/21] qemu-io: Interface cleanup
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
18
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
19
|
+
(cherry picked from commit 3d21994f9c511cb63220fef5abea164b83fbb997)
|
20
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
21
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
22
|
+
|
23
|
+
Conflicts:
|
24
|
+
qemu-io-cmds.c: include block/qapi.h context
|
25
|
+
qemu-io.c include block/qapi.h context
|
26
|
+
|
27
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
28
|
+
---
|
29
|
+
cmd.h | 48 ------------------------------------------------
|
30
|
+
include/qemu-io.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
|
31
|
+
qemu-io-cmds.c | 14 +++++++-------
|
32
|
+
qemu-io.c | 7 +++----
|
33
|
+
4 files changed, 56 insertions(+), 59 deletions(-)
|
34
|
+
delete mode 100644 cmd.h
|
35
|
+
create mode 100644 include/qemu-io.h
|
36
|
+
|
37
|
+
diff --git a/cmd.h b/cmd.h
|
38
|
+
deleted file mode 100644
|
39
|
+
index 9907795..0000000
|
40
|
+
--- a/cmd.h
|
41
|
+
+++ /dev/null
|
42
|
+
|
43
|
+
-/*
|
44
|
+
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
45
|
+
- * All Rights Reserved.
|
46
|
+
- *
|
47
|
+
- * This program is free software; you can redistribute it and/or
|
48
|
+
- * modify it under the terms of the GNU General Public License as
|
49
|
+
- * published by the Free Software Foundation.
|
50
|
+
- *
|
51
|
+
- * This program is distributed in the hope that it would be useful,
|
52
|
+
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
53
|
+
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
54
|
+
- * GNU General Public License for more details.
|
55
|
+
- *
|
56
|
+
- * You should have received a copy of the GNU General Public License
|
57
|
+
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
58
|
+
- */
|
59
|
+
-#ifndef __COMMAND_H__
|
60
|
+
-#define __COMMAND_H__
|
61
|
+
-
|
62
|
+
-#include "qemu-common.h"
|
63
|
+
-
|
64
|
+
-#define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */
|
65
|
+
-
|
66
|
+
-extern BlockDriverState *qemuio_bs;
|
67
|
+
-
|
68
|
+
-typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
|
69
|
+
-typedef void (*helpfunc_t)(void);
|
70
|
+
-
|
71
|
+
-typedef struct cmdinfo {
|
72
|
+
- const char *name;
|
73
|
+
- const char *altname;
|
74
|
+
- cfunc_t cfunc;
|
75
|
+
- int argmin;
|
76
|
+
- int argmax;
|
77
|
+
- int canpush;
|
78
|
+
- int flags;
|
79
|
+
- const char *args;
|
80
|
+
- const char *oneline;
|
81
|
+
- helpfunc_t help;
|
82
|
+
-} cmdinfo_t;
|
83
|
+
-
|
84
|
+
-void qemuio_add_command(const cmdinfo_t *ci);
|
85
|
+
-
|
86
|
+
-int qemuio_command_usage(const cmdinfo_t *ci);
|
87
|
+
-
|
88
|
+
-bool qemuio_command(const char *cmd);
|
89
|
+
-
|
90
|
+
-#endif /* __COMMAND_H__ */
|
91
|
+
diff --git a/include/qemu-io.h b/include/qemu-io.h
|
92
|
+
new file mode 100644
|
93
|
+
index 0000000..a418b46
|
94
|
+
--- /dev/null
|
95
|
+
+++ b/include/qemu-io.h
|
96
|
+
|
97
|
+
+/*
|
98
|
+
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
99
|
+
+ * All Rights Reserved.
|
100
|
+
+ *
|
101
|
+
+ * This program is free software; you can redistribute it and/or
|
102
|
+
+ * modify it under the terms of the GNU General Public License as
|
103
|
+
+ * published by the Free Software Foundation.
|
104
|
+
+ *
|
105
|
+
+ * This program is distributed in the hope that it would be useful,
|
106
|
+
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
107
|
+
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
108
|
+
+ * GNU General Public License for more details.
|
109
|
+
+ *
|
110
|
+
+ * You should have received a copy of the GNU General Public License
|
111
|
+
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
112
|
+
+ */
|
113
|
+
+
|
114
|
+
+#ifndef QEMU_IO_H
|
115
|
+
+#define QEMU_IO_H
|
116
|
+
+
|
117
|
+
+#include "qemu-common.h"
|
118
|
+
+
|
119
|
+
+#define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */
|
120
|
+
+
|
121
|
+
+typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
|
122
|
+
+typedef void (*helpfunc_t)(void);
|
123
|
+
+
|
124
|
+
+typedef struct cmdinfo {
|
125
|
+
+ const char* name;
|
126
|
+
+ const char* altname;
|
127
|
+
+ cfunc_t cfunc;
|
128
|
+
+ int argmin;
|
129
|
+
+ int argmax;
|
130
|
+
+ int canpush;
|
131
|
+
+ int flags;
|
132
|
+
+ const char *args;
|
133
|
+
+ const char *oneline;
|
134
|
+
+ helpfunc_t help;
|
135
|
+
+} cmdinfo_t;
|
136
|
+
+
|
137
|
+
+bool qemuio_command(BlockDriverState *bs, const char *cmd);
|
138
|
+
+
|
139
|
+
+void qemuio_add_command(const cmdinfo_t *ci);
|
140
|
+
+int qemuio_command_usage(const cmdinfo_t *ci);
|
141
|
+
+
|
142
|
+
+#endif /* QEMU_IO_H */
|
143
|
+
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
144
|
+
index 1db7fb9..1f21ce9 100644
|
145
|
+
--- a/qemu-io-cmds.c
|
146
|
+
+++ b/qemu-io-cmds.c
|
147
|
+
|
148
|
+
* See the COPYING file in the top-level directory.
|
149
|
+
*/
|
150
|
+
|
151
|
+
-#include "qemu-common.h"
|
152
|
+
+#include "qemu-io.h"
|
153
|
+
#include "block/block_int.h"
|
154
|
+
#include "block/qapi.h"
|
155
|
+
-#include "cmd.h"
|
156
|
+
|
157
|
+
#define CMD_NOFILE_OK 0x01
|
158
|
+
|
159
|
+
@@ -51,11 +50,12 @@ static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
|
160
|
+
return 1;
|
161
|
+
}
|
162
|
+
|
163
|
+
-static int command(const cmdinfo_t *ct, int argc, char **argv)
|
164
|
+
+static int command(BlockDriverState *bs, const cmdinfo_t *ct, int argc,
|
165
|
+
+ char **argv)
|
166
|
+
{
|
167
|
+
char *cmd = argv[0];
|
168
|
+
|
169
|
+
- if (!init_check_command(qemuio_bs, ct)) {
|
170
|
+
+ if (!init_check_command(bs, ct)) {
|
171
|
+
return 0;
|
172
|
+
}
|
173
|
+
|
174
|
+
@@ -76,7 +76,7 @@ static int command(const cmdinfo_t *ct, int argc, char **argv)
|
175
|
+
return 0;
|
176
|
+
}
|
177
|
+
optind = 0;
|
178
|
+
- return ct->cfunc(qemuio_bs, argc, argv);
|
179
|
+
+ return ct->cfunc(bs, argc, argv);
|
180
|
+
}
|
181
|
+
|
182
|
+
static const cmdinfo_t *find_command(const char *cmd)
|
183
|
+
@@ -2084,7 +2084,7 @@ static const cmdinfo_t help_cmd = {
|
184
|
+
.oneline = "help for one or all commands",
|
185
|
+
};
|
186
|
+
|
187
|
+
-bool qemuio_command(const char *cmd)
|
188
|
+
+bool qemuio_command(BlockDriverState *bs, const char *cmd)
|
189
|
+
{
|
190
|
+
char *input;
|
191
|
+
const cmdinfo_t *ct;
|
192
|
+
@@ -2097,7 +2097,7 @@ bool qemuio_command(const char *cmd)
|
193
|
+
if (c) {
|
194
|
+
ct = find_command(v[0]);
|
195
|
+
if (ct) {
|
196
|
+
- done = command(ct, c, v);
|
197
|
+
+ done = command(bs, ct, c, v);
|
198
|
+
} else {
|
199
|
+
fprintf(stderr, "command \"%s\" not found\n", v[0]);
|
200
|
+
}
|
201
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
202
|
+
index da9944e..e685808 100644
|
203
|
+
--- a/qemu-io.c
|
204
|
+
+++ b/qemu-io.c
|
205
|
+
|
206
|
+
#include <getopt.h>
|
207
|
+
#include <libgen.h>
|
208
|
+
|
209
|
+
-#include "qemu-common.h"
|
210
|
+
+#include "qemu-io.h"
|
211
|
+
#include "qemu/main-loop.h"
|
212
|
+
#include "qemu/option.h"
|
213
|
+
#include "qemu/config-file.h"
|
214
|
+
#include "block/block_int.h"
|
215
|
+
#include "block/qapi.h"
|
216
|
+
-#include "cmd.h"
|
217
|
+
#include "trace/control.h"
|
218
|
+
#include "qemu/timer.h"
|
219
|
+
|
220
|
+
@@ -306,7 +305,7 @@ static void command_loop(void)
|
221
|
+
char *input;
|
222
|
+
|
223
|
+
for (i = 0; !done && i < ncmdline; i++) {
|
224
|
+
- done = qemuio_command(cmdline[i]);
|
225
|
+
+ done = qemuio_command(qemuio_bs, cmdline[i]);
|
226
|
+
}
|
227
|
+
if (cmdline) {
|
228
|
+
g_free(cmdline);
|
229
|
+
@@ -331,7 +330,7 @@ static void command_loop(void)
|
230
|
+
if (input == NULL) {
|
231
|
+
break;
|
232
|
+
}
|
233
|
+
- done = qemuio_command(input);
|
234
|
+
+ done = qemuio_command(qemuio_bs, input);
|
235
|
+
g_free(input);
|
236
|
+
|
237
|
+
prompted = 0;
|
238
|
+
--
|
239
|
+
1.8.3.1
|
240
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
From 94787daf53d6eb2936704f7d9089b26cc5803699 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:22 +0100
|
4
|
+
Subject: [PATCH 03/27] qemu-io: Make cvtnum() a wrapper around
|
5
|
+
strtosz_suffix()
|
6
|
+
|
7
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
8
|
+
Message-id: <1448300320-7772-4-git-send-email-jsnow@redhat.com>
|
9
|
+
Patchwork-id: 68432
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 03/21] qemu-io: Make cvtnum() a wrapper around strtosz_suffix()
|
11
|
+
Bugzilla: 1272523
|
12
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
13
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
14
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
15
|
+
|
16
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
17
|
+
|
18
|
+
No reason to implement the same thing multiple times. A nice side effect
|
19
|
+
is that fractional numbers like 0.5M can be used in qemu-io now.
|
20
|
+
|
21
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
22
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
23
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
24
|
+
(cherry picked from commit b6e356aa25c81d928e1c463292048d29cf25f04e)
|
25
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
26
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
27
|
+
---
|
28
|
+
cmd.c | 37 -------------------------------------
|
29
|
+
cmd.h | 1 -
|
30
|
+
qemu-io.c | 6 ++++++
|
31
|
+
3 files changed, 6 insertions(+), 38 deletions(-)
|
32
|
+
|
33
|
+
diff --git a/cmd.c b/cmd.c
|
34
|
+
index 4e7579b..214c6f7 100644
|
35
|
+
--- a/cmd.c
|
36
|
+
+++ b/cmd.c
|
37
|
+
@@ -344,43 +344,6 @@ doneline(
|
38
|
+
#define MEGABYTES(x) ((long long)(x) << 20)
|
39
|
+
#define KILOBYTES(x) ((long long)(x) << 10)
|
40
|
+
|
41
|
+
-long long
|
42
|
+
-cvtnum(
|
43
|
+
- char *s)
|
44
|
+
-{
|
45
|
+
- long long i;
|
46
|
+
- char *sp;
|
47
|
+
- int c;
|
48
|
+
-
|
49
|
+
- i = strtoll(s, &sp, 0);
|
50
|
+
- if (i == 0 && sp == s)
|
51
|
+
- return -1LL;
|
52
|
+
- if (*sp == '\0')
|
53
|
+
- return i;
|
54
|
+
-
|
55
|
+
- if (sp[1] != '\0')
|
56
|
+
- return -1LL;
|
57
|
+
-
|
58
|
+
- c = qemu_tolower(*sp);
|
59
|
+
- switch (c) {
|
60
|
+
- default:
|
61
|
+
- return i;
|
62
|
+
- case 'k':
|
63
|
+
- return KILOBYTES(i);
|
64
|
+
- case 'm':
|
65
|
+
- return MEGABYTES(i);
|
66
|
+
- case 'g':
|
67
|
+
- return GIGABYTES(i);
|
68
|
+
- case 't':
|
69
|
+
- return TERABYTES(i);
|
70
|
+
- case 'p':
|
71
|
+
- return PETABYTES(i);
|
72
|
+
- case 'e':
|
73
|
+
- return EXABYTES(i);
|
74
|
+
- }
|
75
|
+
- return -1LL;
|
76
|
+
-}
|
77
|
+
-
|
78
|
+
#define TO_EXABYTES(x) ((x) / EXABYTES(1))
|
79
|
+
#define TO_PETABYTES(x) ((x) / PETABYTES(1))
|
80
|
+
#define TO_TERABYTES(x) ((x) / TERABYTES(1))
|
81
|
+
diff --git a/cmd.h b/cmd.h
|
82
|
+
index 8e6f753..4dcfe88 100644
|
83
|
+
--- a/cmd.h
|
84
|
+
+++ b/cmd.h
|
85
|
+
@@ -58,7 +58,6 @@ char **breakline(char *input, int *count);
|
86
|
+
void doneline(char *input, char **vec);
|
87
|
+
char *fetchline(void);
|
88
|
+
|
89
|
+
-long long cvtnum(char *s);
|
90
|
+
void cvtstr(double value, char *str, size_t sz);
|
91
|
+
|
92
|
+
struct timeval tsub(struct timeval t1, struct timeval t2);
|
93
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
94
|
+
index 9f66a78..3b5890e 100644
|
95
|
+
--- a/qemu-io.c
|
96
|
+
+++ b/qemu-io.c
|
97
|
+
@@ -33,6 +33,12 @@ static BlockDriverState *bs;
|
98
|
+
|
99
|
+
static int misalign;
|
100
|
+
|
101
|
+
+static int64_t cvtnum(const char *s)
|
102
|
+
+{
|
103
|
+
+ char *end;
|
104
|
+
+ return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
|
105
|
+
+}
|
106
|
+
+
|
107
|
+
/*
|
108
|
+
* Parse the pattern argument to various sub-commands.
|
109
|
+
*
|
110
|
+
--
|
111
|
+
1.8.3.1
|
112
|
+
|
@@ -0,0 +1,369 @@
|
|
1
|
+
From 828d09abacc6ae7f0643957301cc3ddee269d7a0 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:31 +0100
|
4
|
+
Subject: [PATCH 12/27] qemu-io: Move command_loop() and friends
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-13-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68441
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 12/21] qemu-io: Move command_loop() and friends
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
18
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
19
|
+
(cherry picked from commit d1174f13e78e2f43f7ae33d59b62b0b94468c8db)
|
20
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
21
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
22
|
+
---
|
23
|
+
cmd.c | 139 --------------------------------------------------------------
|
24
|
+
cmd.h | 9 ----
|
25
|
+
qemu-io.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
26
|
+
3 files changed, 139 insertions(+), 148 deletions(-)
|
27
|
+
|
28
|
+
diff --git a/cmd.c b/cmd.c
|
29
|
+
index 6616d61..26d38a8 100644
|
30
|
+
--- a/cmd.c
|
31
|
+
+++ b/cmd.c
|
32
|
+
|
33
|
+
|
34
|
+
/* from libxcmd/command.c */
|
35
|
+
|
36
|
+
-static int ncmdline;
|
37
|
+
-static char **cmdline;
|
38
|
+
-
|
39
|
+
-
|
40
|
+
-void add_user_command(char *optarg)
|
41
|
+
-{
|
42
|
+
- cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));
|
43
|
+
- cmdline[ncmdline-1] = optarg;
|
44
|
+
-}
|
45
|
+
-
|
46
|
+
-static void prep_fetchline(void *opaque)
|
47
|
+
-{
|
48
|
+
- int *fetchable = opaque;
|
49
|
+
-
|
50
|
+
- qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
|
51
|
+
- *fetchable= 1;
|
52
|
+
-}
|
53
|
+
-
|
54
|
+
-static char *get_prompt(void);
|
55
|
+
-
|
56
|
+
-void command_loop(void)
|
57
|
+
-{
|
58
|
+
- int i, done = 0, fetchable = 0, prompted = 0;
|
59
|
+
- char *input;
|
60
|
+
-
|
61
|
+
- for (i = 0; !done && i < ncmdline; i++) {
|
62
|
+
- done = qemuio_command(cmdline[i]);
|
63
|
+
- }
|
64
|
+
- if (cmdline) {
|
65
|
+
- g_free(cmdline);
|
66
|
+
- return;
|
67
|
+
- }
|
68
|
+
-
|
69
|
+
- while (!done) {
|
70
|
+
- if (!prompted) {
|
71
|
+
- printf("%s", get_prompt());
|
72
|
+
- fflush(stdout);
|
73
|
+
- qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
|
74
|
+
- prompted = 1;
|
75
|
+
- }
|
76
|
+
-
|
77
|
+
- main_loop_wait(false);
|
78
|
+
-
|
79
|
+
- if (!fetchable) {
|
80
|
+
- continue;
|
81
|
+
- }
|
82
|
+
-
|
83
|
+
- input = fetchline();
|
84
|
+
- if (input == NULL) {
|
85
|
+
- break;
|
86
|
+
- }
|
87
|
+
- done = qemuio_command(input);
|
88
|
+
- free(input);
|
89
|
+
-
|
90
|
+
- prompted = 0;
|
91
|
+
- fetchable = 0;
|
92
|
+
- }
|
93
|
+
- qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
|
94
|
+
-}
|
95
|
+
-
|
96
|
+
-/* from libxcmd/input.c */
|
97
|
+
-
|
98
|
+
-#if defined(ENABLE_READLINE)
|
99
|
+
-# include <readline/history.h>
|
100
|
+
-# include <readline/readline.h>
|
101
|
+
-#elif defined(ENABLE_EDITLINE)
|
102
|
+
-# include <histedit.h>
|
103
|
+
-#endif
|
104
|
+
-
|
105
|
+
-static char *
|
106
|
+
-get_prompt(void)
|
107
|
+
-{
|
108
|
+
- static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
|
109
|
+
-
|
110
|
+
- if (!prompt[0])
|
111
|
+
- snprintf(prompt, sizeof(prompt), "%s> ", progname);
|
112
|
+
- return prompt;
|
113
|
+
-}
|
114
|
+
-
|
115
|
+
-#if defined(ENABLE_READLINE)
|
116
|
+
-char *
|
117
|
+
-fetchline(void)
|
118
|
+
-{
|
119
|
+
- char *line;
|
120
|
+
-
|
121
|
+
- line = readline(get_prompt());
|
122
|
+
- if (line && *line)
|
123
|
+
- add_history(line);
|
124
|
+
- return line;
|
125
|
+
-}
|
126
|
+
-#elif defined(ENABLE_EDITLINE)
|
127
|
+
-static char *el_get_prompt(EditLine *e) { return get_prompt(); }
|
128
|
+
-char *
|
129
|
+
-fetchline(void)
|
130
|
+
-{
|
131
|
+
- static EditLine *el;
|
132
|
+
- static History *hist;
|
133
|
+
- HistEvent hevent;
|
134
|
+
- char *line;
|
135
|
+
- int count;
|
136
|
+
-
|
137
|
+
- if (!el) {
|
138
|
+
- hist = history_init();
|
139
|
+
- history(hist, &hevent, H_SETSIZE, 100);
|
140
|
+
- el = el_init(progname, stdin, stdout, stderr);
|
141
|
+
- el_source(el, NULL);
|
142
|
+
- el_set(el, EL_SIGNAL, 1);
|
143
|
+
- el_set(el, EL_PROMPT, el_get_prompt);
|
144
|
+
- el_set(el, EL_HIST, history, (const char *)hist);
|
145
|
+
- }
|
146
|
+
- line = strdup(el_gets(el, &count));
|
147
|
+
- if (line) {
|
148
|
+
- if (count > 0)
|
149
|
+
- line[count-1] = '\0';
|
150
|
+
- if (*line)
|
151
|
+
- history(hist, &hevent, H_ENTER, line);
|
152
|
+
- }
|
153
|
+
- return line;
|
154
|
+
-}
|
155
|
+
-#else
|
156
|
+
-# define MAXREADLINESZ 1024
|
157
|
+
-char *
|
158
|
+
-fetchline(void)
|
159
|
+
-{
|
160
|
+
- char *p, *line = malloc(MAXREADLINESZ);
|
161
|
+
-
|
162
|
+
- if (!line)
|
163
|
+
- return NULL;
|
164
|
+
- if (!fgets(line, MAXREADLINESZ, stdin)) {
|
165
|
+
- free(line);
|
166
|
+
- return NULL;
|
167
|
+
- }
|
168
|
+
- p = line + strlen(line);
|
169
|
+
- if (p != line && p[-1] == '\n')
|
170
|
+
- p[-1] = '\0';
|
171
|
+
- return line;
|
172
|
+
-}
|
173
|
+
-#endif
|
174
|
+
-
|
175
|
+
#define EXABYTES(x) ((long long)(x) << 60)
|
176
|
+
#define PETABYTES(x) ((long long)(x) << 50)
|
177
|
+
#define TERABYTES(x) ((long long)(x) << 40)
|
178
|
+
diff --git a/cmd.h b/cmd.h
|
179
|
+
index 0d01a33..da0c7cf 100644
|
180
|
+
--- a/cmd.h
|
181
|
+
+++ b/cmd.h
|
182
|
+
@@ -39,18 +39,11 @@ typedef struct cmdinfo {
|
183
|
+
helpfunc_t help;
|
184
|
+
} cmdinfo_t;
|
185
|
+
|
186
|
+
-typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
|
187
|
+
-
|
188
|
+
void qemuio_add_command(const cmdinfo_t *ci);
|
189
|
+
-void add_user_command(char *optarg);
|
190
|
+
-void add_check_command(checkfunc_t cf);
|
191
|
+
|
192
|
+
-void command_loop(void);
|
193
|
+
int qemuio_command_usage(const cmdinfo_t *ci);
|
194
|
+
|
195
|
+
/* from input.h */
|
196
|
+
-char *fetchline(void);
|
197
|
+
-
|
198
|
+
void cvtstr(double value, char *str, size_t sz);
|
199
|
+
|
200
|
+
struct timeval tsub(struct timeval t1, struct timeval t2);
|
201
|
+
@@ -64,8 +57,6 @@ enum {
|
202
|
+
|
203
|
+
void timestr(struct timeval *tv, char *str, size_t sz, int flags);
|
204
|
+
|
205
|
+
-extern char *progname;
|
206
|
+
-
|
207
|
+
bool qemuio_command(const char *cmd);
|
208
|
+
|
209
|
+
#endif /* __COMMAND_H__ */
|
210
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
211
|
+
index 97af39e..da9944e 100644
|
212
|
+
--- a/qemu-io.c
|
213
|
+
+++ b/qemu-io.c
|
214
|
+
@@ -34,6 +34,10 @@ BlockDriverState *qemuio_bs;
|
215
|
+
|
216
|
+
extern int qemuio_misalign;
|
217
|
+
|
218
|
+
+/* qemu-io commands passed using -c */
|
219
|
+
+static int ncmdline;
|
220
|
+
+static char **cmdline;
|
221
|
+
+
|
222
|
+
static int close_f(BlockDriverState *bs, int argc, char **argv)
|
223
|
+
{
|
224
|
+
bdrv_unref(bs);
|
225
|
+
@@ -207,6 +211,141 @@ static void usage(const char *name)
|
226
|
+
}
|
227
|
+
|
228
|
+
|
229
|
+
+#if defined(ENABLE_READLINE)
|
230
|
+
+# include <readline/history.h>
|
231
|
+
+# include <readline/readline.h>
|
232
|
+
+#elif defined(ENABLE_EDITLINE)
|
233
|
+
+# include <histedit.h>
|
234
|
+
+#endif
|
235
|
+
+
|
236
|
+
+static char *get_prompt(void)
|
237
|
+
+{
|
238
|
+
+ static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
|
239
|
+
+
|
240
|
+
+ if (!prompt[0]) {
|
241
|
+
+ snprintf(prompt, sizeof(prompt), "%s> ", progname);
|
242
|
+
+ }
|
243
|
+
+
|
244
|
+
+ return prompt;
|
245
|
+
+}
|
246
|
+
+
|
247
|
+
+#if defined(ENABLE_READLINE)
|
248
|
+
+static char *fetchline(void)
|
249
|
+
+{
|
250
|
+
+ char *line = readline(get_prompt());
|
251
|
+
+ if (line && *line) {
|
252
|
+
+ add_history(line);
|
253
|
+
+ }
|
254
|
+
+ return line;
|
255
|
+
+}
|
256
|
+
+#elif defined(ENABLE_EDITLINE)
|
257
|
+
+static char *el_get_prompt(EditLine *e)
|
258
|
+
+{
|
259
|
+
+ return get_prompt();
|
260
|
+
+}
|
261
|
+
+
|
262
|
+
+static char *fetchline(void)
|
263
|
+
+{
|
264
|
+
+ static EditLine *el;
|
265
|
+
+ static History *hist;
|
266
|
+
+ HistEvent hevent;
|
267
|
+
+ char *line;
|
268
|
+
+ int count;
|
269
|
+
+
|
270
|
+
+ if (!el) {
|
271
|
+
+ hist = history_init();
|
272
|
+
+ history(hist, &hevent, H_SETSIZE, 100);
|
273
|
+
+ el = el_init(progname, stdin, stdout, stderr);
|
274
|
+
+ el_source(el, NULL);
|
275
|
+
+ el_set(el, EL_SIGNAL, 1);
|
276
|
+
+ el_set(el, EL_PROMPT, el_get_prompt);
|
277
|
+
+ el_set(el, EL_HIST, history, (const char *)hist);
|
278
|
+
+ }
|
279
|
+
+ line = strdup(el_gets(el, &count));
|
280
|
+
+ if (line) {
|
281
|
+
+ if (count > 0) {
|
282
|
+
+ line[count-1] = '\0';
|
283
|
+
+ }
|
284
|
+
+ if (*line) {
|
285
|
+
+ history(hist, &hevent, H_ENTER, line);
|
286
|
+
+ }
|
287
|
+
+ }
|
288
|
+
+ return line;
|
289
|
+
+}
|
290
|
+
+#else
|
291
|
+
+# define MAXREADLINESZ 1024
|
292
|
+
+static char *fetchline(void)
|
293
|
+
+{
|
294
|
+
+ char *p, *line = g_malloc(MAXREADLINESZ);
|
295
|
+
+
|
296
|
+
+ if (!fgets(line, MAXREADLINESZ, stdin)) {
|
297
|
+
+ g_free(line);
|
298
|
+
+ return NULL;
|
299
|
+
+ }
|
300
|
+
+
|
301
|
+
+ p = line + strlen(line);
|
302
|
+
+ if (p != line && p[-1] == '\n') {
|
303
|
+
+ p[-1] = '\0';
|
304
|
+
+ }
|
305
|
+
+
|
306
|
+
+ return line;
|
307
|
+
+}
|
308
|
+
+#endif
|
309
|
+
+
|
310
|
+
+static void prep_fetchline(void *opaque)
|
311
|
+
+{
|
312
|
+
+ int *fetchable = opaque;
|
313
|
+
+
|
314
|
+
+ qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
|
315
|
+
+ *fetchable= 1;
|
316
|
+
+}
|
317
|
+
+
|
318
|
+
+static void command_loop(void)
|
319
|
+
+{
|
320
|
+
+ int i, done = 0, fetchable = 0, prompted = 0;
|
321
|
+
+ char *input;
|
322
|
+
+
|
323
|
+
+ for (i = 0; !done && i < ncmdline; i++) {
|
324
|
+
+ done = qemuio_command(cmdline[i]);
|
325
|
+
+ }
|
326
|
+
+ if (cmdline) {
|
327
|
+
+ g_free(cmdline);
|
328
|
+
+ return;
|
329
|
+
+ }
|
330
|
+
+
|
331
|
+
+ while (!done) {
|
332
|
+
+ if (!prompted) {
|
333
|
+
+ printf("%s", get_prompt());
|
334
|
+
+ fflush(stdout);
|
335
|
+
+ qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
|
336
|
+
+ prompted = 1;
|
337
|
+
+ }
|
338
|
+
+
|
339
|
+
+ main_loop_wait(false);
|
340
|
+
+
|
341
|
+
+ if (!fetchable) {
|
342
|
+
+ continue;
|
343
|
+
+ }
|
344
|
+
+
|
345
|
+
+ input = fetchline();
|
346
|
+
+ if (input == NULL) {
|
347
|
+
+ break;
|
348
|
+
+ }
|
349
|
+
+ done = qemuio_command(input);
|
350
|
+
+ g_free(input);
|
351
|
+
+
|
352
|
+
+ prompted = 0;
|
353
|
+
+ fetchable = 0;
|
354
|
+
+ }
|
355
|
+
+ qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
|
356
|
+
+}
|
357
|
+
+
|
358
|
+
+static void add_user_command(char *optarg)
|
359
|
+
+{
|
360
|
+
+ cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));
|
361
|
+
+ cmdline[ncmdline-1] = optarg;
|
362
|
+
+}
|
363
|
+
+
|
364
|
+
int main(int argc, char **argv)
|
365
|
+
{
|
366
|
+
int readonly = 0;
|
367
|
+
--
|
368
|
+
1.8.3.1
|
369
|
+
|
@@ -0,0 +1,551 @@
|
|
1
|
+
From df682d833654f2f42595d6156341439644a8848d Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:30 +0100
|
4
|
+
Subject: [PATCH 11/27] qemu-io: Move functions for registering and running
|
5
|
+
commands
|
6
|
+
|
7
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
8
|
+
Message-id: <1448300320-7772-12-git-send-email-jsnow@redhat.com>
|
9
|
+
Patchwork-id: 68439
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 11/21] qemu-io: Move functions for registering and running commands
|
11
|
+
Bugzilla: 1272523
|
12
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
13
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
14
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
15
|
+
|
16
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
17
|
+
|
18
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
19
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
20
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
21
|
+
(cherry picked from commit c2cdf5c5892165cbe7d3567bff5930521bc52669)
|
22
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
23
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
24
|
+
|
25
|
+
Conflicts:
|
26
|
+
qemu-io-cmds.c: Conflicts over sleep_f, again.
|
27
|
+
|
28
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
29
|
+
---
|
30
|
+
cmd.c | 113 ---------------------------------
|
31
|
+
cmd.h | 11 +---
|
32
|
+
qemu-io-cmds.c | 194 +++++++++++++++++++++++++++++++++++++++++----------------
|
33
|
+
qemu-io.c | 10 +--
|
34
|
+
4 files changed, 149 insertions(+), 179 deletions(-)
|
35
|
+
|
36
|
+
diff --git a/cmd.c b/cmd.c
|
37
|
+
index f6bf2c5..6616d61 100644
|
38
|
+
--- a/cmd.c
|
39
|
+
+++ b/cmd.c
|
40
|
+
|
41
|
+
|
42
|
+
/* from libxcmd/command.c */
|
43
|
+
|
44
|
+
-cmdinfo_t *cmdtab;
|
45
|
+
-int ncmds;
|
46
|
+
-
|
47
|
+
-static checkfunc_t check_func;
|
48
|
+
static int ncmdline;
|
49
|
+
static char **cmdline;
|
50
|
+
|
51
|
+
-static int
|
52
|
+
-compare(const void *a, const void *b)
|
53
|
+
-{
|
54
|
+
- return strcmp(((const cmdinfo_t *)a)->name,
|
55
|
+
- ((const cmdinfo_t *)b)->name);
|
56
|
+
-}
|
57
|
+
-
|
58
|
+
-void add_command(const cmdinfo_t *ci)
|
59
|
+
-{
|
60
|
+
- cmdtab = g_realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab));
|
61
|
+
- cmdtab[ncmds - 1] = *ci;
|
62
|
+
- qsort(cmdtab, ncmds, sizeof(*cmdtab), compare);
|
63
|
+
-}
|
64
|
+
-
|
65
|
+
-static int
|
66
|
+
-check_command(
|
67
|
+
- const cmdinfo_t *ci)
|
68
|
+
-{
|
69
|
+
- if (check_func)
|
70
|
+
- return check_func(qemuio_bs, ci);
|
71
|
+
- return 1;
|
72
|
+
-}
|
73
|
+
-
|
74
|
+
-void
|
75
|
+
-add_check_command(
|
76
|
+
- checkfunc_t cf)
|
77
|
+
-{
|
78
|
+
- check_func = cf;
|
79
|
+
-}
|
80
|
+
-
|
81
|
+
-int
|
82
|
+
-command_usage(
|
83
|
+
- const cmdinfo_t *ci)
|
84
|
+
-{
|
85
|
+
- printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
|
86
|
+
- return 0;
|
87
|
+
-}
|
88
|
+
-
|
89
|
+
-int
|
90
|
+
-command(
|
91
|
+
- const cmdinfo_t *ct,
|
92
|
+
- int argc,
|
93
|
+
- char **argv)
|
94
|
+
-{
|
95
|
+
- char *cmd = argv[0];
|
96
|
+
-
|
97
|
+
- if (!check_command(ct))
|
98
|
+
- return 0;
|
99
|
+
-
|
100
|
+
- if (argc-1 < ct->argmin || (ct->argmax != -1 && argc-1 > ct->argmax)) {
|
101
|
+
- if (ct->argmax == -1)
|
102
|
+
- fprintf(stderr,
|
103
|
+
- _("bad argument count %d to %s, expected at least %d arguments\n"),
|
104
|
+
- argc-1, cmd, ct->argmin);
|
105
|
+
- else if (ct->argmin == ct->argmax)
|
106
|
+
- fprintf(stderr,
|
107
|
+
- _("bad argument count %d to %s, expected %d arguments\n"),
|
108
|
+
- argc-1, cmd, ct->argmin);
|
109
|
+
- else
|
110
|
+
- fprintf(stderr,
|
111
|
+
- _("bad argument count %d to %s, expected between %d and %d arguments\n"),
|
112
|
+
- argc-1, cmd, ct->argmin, ct->argmax);
|
113
|
+
- return 0;
|
114
|
+
- }
|
115
|
+
- optind = 0;
|
116
|
+
- return ct->cfunc(qemuio_bs, argc, argv);
|
117
|
+
-}
|
118
|
+
-
|
119
|
+
-const cmdinfo_t *
|
120
|
+
-find_command(
|
121
|
+
- const char *cmd)
|
122
|
+
-{
|
123
|
+
- cmdinfo_t *ct;
|
124
|
+
-
|
125
|
+
- for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
|
126
|
+
- if (strcmp(ct->name, cmd) == 0 ||
|
127
|
+
- (ct->altname && strcmp(ct->altname, cmd) == 0))
|
128
|
+
- return (const cmdinfo_t *)ct;
|
129
|
+
- }
|
130
|
+
- return NULL;
|
131
|
+
-}
|
132
|
+
|
133
|
+
void add_user_command(char *optarg)
|
134
|
+
{
|
135
|
+
@@ -255,34 +170,6 @@ fetchline(void)
|
136
|
+
}
|
137
|
+
#endif
|
138
|
+
|
139
|
+
-char **breakline(char *input, int *count)
|
140
|
+
-{
|
141
|
+
- int c = 0;
|
142
|
+
- char *p;
|
143
|
+
- char **rval = calloc(sizeof(char *), 1);
|
144
|
+
- char **tmp;
|
145
|
+
-
|
146
|
+
- while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
|
147
|
+
- if (!*p) {
|
148
|
+
- continue;
|
149
|
+
- }
|
150
|
+
- c++;
|
151
|
+
- tmp = realloc(rval, sizeof(*rval) * (c + 1));
|
152
|
+
- if (!tmp) {
|
153
|
+
- free(rval);
|
154
|
+
- rval = NULL;
|
155
|
+
- c = 0;
|
156
|
+
- break;
|
157
|
+
- } else {
|
158
|
+
- rval = tmp;
|
159
|
+
- }
|
160
|
+
- rval[c - 1] = p;
|
161
|
+
- rval[c] = NULL;
|
162
|
+
- }
|
163
|
+
- *count = c;
|
164
|
+
- return rval;
|
165
|
+
-}
|
166
|
+
-
|
167
|
+
#define EXABYTES(x) ((long long)(x) << 60)
|
168
|
+
#define PETABYTES(x) ((long long)(x) << 50)
|
169
|
+
#define TERABYTES(x) ((long long)(x) << 40)
|
170
|
+
diff --git a/cmd.h b/cmd.h
|
171
|
+
index 5b6f61b..0d01a33 100644
|
172
|
+
--- a/cmd.h
|
173
|
+
+++ b/cmd.h
|
174
|
+
@@ -39,23 +39,16 @@ typedef struct cmdinfo {
|
175
|
+
helpfunc_t help;
|
176
|
+
} cmdinfo_t;
|
177
|
+
|
178
|
+
-extern cmdinfo_t *cmdtab;
|
179
|
+
-extern int ncmds;
|
180
|
+
-
|
181
|
+
typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
|
182
|
+
|
183
|
+
-void add_command(const cmdinfo_t *ci);
|
184
|
+
+void qemuio_add_command(const cmdinfo_t *ci);
|
185
|
+
void add_user_command(char *optarg);
|
186
|
+
void add_check_command(checkfunc_t cf);
|
187
|
+
|
188
|
+
-const cmdinfo_t *find_command(const char *cmd);
|
189
|
+
-
|
190
|
+
void command_loop(void);
|
191
|
+
-int command_usage(const cmdinfo_t *ci);
|
192
|
+
-int command(const cmdinfo_t *ci, int argc, char **argv);
|
193
|
+
+int qemuio_command_usage(const cmdinfo_t *ci);
|
194
|
+
|
195
|
+
/* from input.h */
|
196
|
+
-char **breakline(char *input, int *count);
|
197
|
+
char *fetchline(void);
|
198
|
+
|
199
|
+
void cvtstr(double value, char *str, size_t sz);
|
200
|
+
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
201
|
+
index a8e891a..27a903f 100644
|
202
|
+
--- a/qemu-io-cmds.c
|
203
|
+
+++ b/qemu-io-cmds.c
|
204
|
+
|
205
|
+
|
206
|
+
int qemuio_misalign;
|
207
|
+
|
208
|
+
+static cmdinfo_t *cmdtab;
|
209
|
+
+static int ncmds;
|
210
|
+
+
|
211
|
+
+static int compare_cmdname(const void *a, const void *b)
|
212
|
+
+{
|
213
|
+
+ return strcmp(((const cmdinfo_t *)a)->name,
|
214
|
+
+ ((const cmdinfo_t *)b)->name);
|
215
|
+
+}
|
216
|
+
+
|
217
|
+
+void qemuio_add_command(const cmdinfo_t *ci)
|
218
|
+
+{
|
219
|
+
+ cmdtab = g_realloc(cmdtab, ++ncmds * sizeof(*cmdtab));
|
220
|
+
+ cmdtab[ncmds - 1] = *ci;
|
221
|
+
+ qsort(cmdtab, ncmds, sizeof(*cmdtab), compare_cmdname);
|
222
|
+
+}
|
223
|
+
+
|
224
|
+
+int qemuio_command_usage(const cmdinfo_t *ci)
|
225
|
+
+{
|
226
|
+
+ printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
|
227
|
+
+ return 0;
|
228
|
+
+}
|
229
|
+
+
|
230
|
+
+static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
|
231
|
+
+{
|
232
|
+
+ if (ct->flags & CMD_FLAG_GLOBAL) {
|
233
|
+
+ return 1;
|
234
|
+
+ }
|
235
|
+
+ if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
|
236
|
+
+ fprintf(stderr, "no file open, try 'help open'\n");
|
237
|
+
+ return 0;
|
238
|
+
+ }
|
239
|
+
+ return 1;
|
240
|
+
+}
|
241
|
+
+
|
242
|
+
+static int command(const cmdinfo_t *ct, int argc, char **argv)
|
243
|
+
+{
|
244
|
+
+ char *cmd = argv[0];
|
245
|
+
+
|
246
|
+
+ if (!init_check_command(qemuio_bs, ct)) {
|
247
|
+
+ return 0;
|
248
|
+
+ }
|
249
|
+
+
|
250
|
+
+ if (argc - 1 < ct->argmin || (ct->argmax != -1 && argc - 1 > ct->argmax)) {
|
251
|
+
+ if (ct->argmax == -1) {
|
252
|
+
+ fprintf(stderr,
|
253
|
+
+ "bad argument count %d to %s, expected at least %d arguments\n",
|
254
|
+
+ argc-1, cmd, ct->argmin);
|
255
|
+
+ } else if (ct->argmin == ct->argmax) {
|
256
|
+
+ fprintf(stderr,
|
257
|
+
+ "bad argument count %d to %s, expected %d arguments\n",
|
258
|
+
+ argc-1, cmd, ct->argmin);
|
259
|
+
+ } else {
|
260
|
+
+ fprintf(stderr,
|
261
|
+
+ "bad argument count %d to %s, expected between %d and %d arguments\n",
|
262
|
+
+ argc-1, cmd, ct->argmin, ct->argmax);
|
263
|
+
+ }
|
264
|
+
+ return 0;
|
265
|
+
+ }
|
266
|
+
+ optind = 0;
|
267
|
+
+ return ct->cfunc(qemuio_bs, argc, argv);
|
268
|
+
+}
|
269
|
+
+
|
270
|
+
+static const cmdinfo_t *find_command(const char *cmd)
|
271
|
+
+{
|
272
|
+
+ cmdinfo_t *ct;
|
273
|
+
+
|
274
|
+
+ for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
|
275
|
+
+ if (strcmp(ct->name, cmd) == 0 ||
|
276
|
+
+ (ct->altname && strcmp(ct->altname, cmd) == 0))
|
277
|
+
+ {
|
278
|
+
+ return (const cmdinfo_t *)ct;
|
279
|
+
+ }
|
280
|
+
+ }
|
281
|
+
+ return NULL;
|
282
|
+
+}
|
283
|
+
+
|
284
|
+
+static char **breakline(char *input, int *count)
|
285
|
+
+{
|
286
|
+
+ int c = 0;
|
287
|
+
+ char *p;
|
288
|
+
+ char **rval = g_malloc0(sizeof(char *));
|
289
|
+
+ char **tmp;
|
290
|
+
+
|
291
|
+
+ while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
|
292
|
+
+ if (!*p) {
|
293
|
+
+ continue;
|
294
|
+
+ }
|
295
|
+
+ c++;
|
296
|
+
+ tmp = g_realloc(rval, sizeof(*rval) * (c + 1));
|
297
|
+
+ if (!tmp) {
|
298
|
+
+ g_free(rval);
|
299
|
+
+ rval = NULL;
|
300
|
+
+ c = 0;
|
301
|
+
+ break;
|
302
|
+
+ } else {
|
303
|
+
+ rval = tmp;
|
304
|
+
+ }
|
305
|
+
+ rval[c - 1] = p;
|
306
|
+
+ rval[c] = NULL;
|
307
|
+
+ }
|
308
|
+
+ *count = c;
|
309
|
+
+ return rval;
|
310
|
+
+}
|
311
|
+
+
|
312
|
+
static int64_t cvtnum(const char *s)
|
313
|
+
{
|
314
|
+
char *end;
|
315
|
+
@@ -468,12 +572,12 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
|
316
|
+
vflag = 1;
|
317
|
+
break;
|
318
|
+
default:
|
319
|
+
- return command_usage(&read_cmd);
|
320
|
+
+ return qemuio_command_usage(&read_cmd);
|
321
|
+
}
|
322
|
+
}
|
323
|
+
|
324
|
+
if (optind != argc - 2) {
|
325
|
+
- return command_usage(&read_cmd);
|
326
|
+
+ return qemuio_command_usage(&read_cmd);
|
327
|
+
}
|
328
|
+
|
329
|
+
if (bflag && pflag) {
|
330
|
+
@@ -495,7 +599,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
|
331
|
+
}
|
332
|
+
|
333
|
+
if (!Pflag && (lflag || sflag)) {
|
334
|
+
- return command_usage(&read_cmd);
|
335
|
+
+ return qemuio_command_usage(&read_cmd);
|
336
|
+
}
|
337
|
+
|
338
|
+
if (!lflag) {
|
339
|
+
@@ -630,12 +734,12 @@ static int readv_f(BlockDriverState *bs, int argc, char **argv)
|
340
|
+
vflag = 1;
|
341
|
+
break;
|
342
|
+
default:
|
343
|
+
- return command_usage(&readv_cmd);
|
344
|
+
+ return qemuio_command_usage(&readv_cmd);
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
if (optind > argc - 2) {
|
349
|
+
- return command_usage(&readv_cmd);
|
350
|
+
+ return qemuio_command_usage(&readv_cmd);
|
351
|
+
}
|
352
|
+
|
353
|
+
|
354
|
+
@@ -770,12 +874,12 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
|
355
|
+
zflag = 1;
|
356
|
+
break;
|
357
|
+
default:
|
358
|
+
- return command_usage(&write_cmd);
|
359
|
+
+ return qemuio_command_usage(&write_cmd);
|
360
|
+
}
|
361
|
+
}
|
362
|
+
|
363
|
+
if (optind != argc - 2) {
|
364
|
+
- return command_usage(&write_cmd);
|
365
|
+
+ return qemuio_command_usage(&write_cmd);
|
366
|
+
}
|
367
|
+
|
368
|
+
if (bflag + pflag + zflag > 1) {
|
369
|
+
@@ -912,12 +1016,12 @@ static int writev_f(BlockDriverState *bs, int argc, char **argv)
|
370
|
+
}
|
371
|
+
break;
|
372
|
+
default:
|
373
|
+
- return command_usage(&writev_cmd);
|
374
|
+
+ return qemuio_command_usage(&writev_cmd);
|
375
|
+
}
|
376
|
+
}
|
377
|
+
|
378
|
+
if (optind > argc - 2) {
|
379
|
+
- return command_usage(&writev_cmd);
|
380
|
+
+ return qemuio_command_usage(&writev_cmd);
|
381
|
+
}
|
382
|
+
|
383
|
+
offset = cvtnum(argv[optind]);
|
384
|
+
@@ -1024,12 +1128,12 @@ static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
|
385
|
+
}
|
386
|
+
break;
|
387
|
+
default:
|
388
|
+
- return command_usage(&writev_cmd);
|
389
|
+
+ return qemuio_command_usage(&writev_cmd);
|
390
|
+
}
|
391
|
+
}
|
392
|
+
|
393
|
+
if (optind > argc - 2) {
|
394
|
+
- return command_usage(&writev_cmd);
|
395
|
+
+ return qemuio_command_usage(&writev_cmd);
|
396
|
+
}
|
397
|
+
|
398
|
+
nr_reqs = 1;
|
399
|
+
@@ -1258,13 +1362,13 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
|
400
|
+
break;
|
401
|
+
default:
|
402
|
+
g_free(ctx);
|
403
|
+
- return command_usage(&aio_read_cmd);
|
404
|
+
+ return qemuio_command_usage(&aio_read_cmd);
|
405
|
+
}
|
406
|
+
}
|
407
|
+
|
408
|
+
if (optind > argc - 2) {
|
409
|
+
g_free(ctx);
|
410
|
+
- return command_usage(&aio_read_cmd);
|
411
|
+
+ return qemuio_command_usage(&aio_read_cmd);
|
412
|
+
}
|
413
|
+
|
414
|
+
ctx->offset = cvtnum(argv[optind]);
|
415
|
+
@@ -1350,13 +1454,13 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
|
416
|
+
break;
|
417
|
+
default:
|
418
|
+
g_free(ctx);
|
419
|
+
- return command_usage(&aio_write_cmd);
|
420
|
+
+ return qemuio_command_usage(&aio_write_cmd);
|
421
|
+
}
|
422
|
+
}
|
423
|
+
|
424
|
+
if (optind > argc - 2) {
|
425
|
+
g_free(ctx);
|
426
|
+
- return command_usage(&aio_write_cmd);
|
427
|
+
+ return qemuio_command_usage(&aio_write_cmd);
|
428
|
+
}
|
429
|
+
|
430
|
+
ctx->offset = cvtnum(argv[optind]);
|
431
|
+
@@ -1556,12 +1660,12 @@ static int discard_f(BlockDriverState *bs, int argc, char **argv)
|
432
|
+
qflag = 1;
|
433
|
+
break;
|
434
|
+
default:
|
435
|
+
- return command_usage(&discard_cmd);
|
436
|
+
+ return qemuio_command_usage(&discard_cmd);
|
437
|
+
}
|
438
|
+
}
|
439
|
+
|
440
|
+
if (optind != argc - 2) {
|
441
|
+
- return command_usage(&discard_cmd);
|
442
|
+
+ return qemuio_command_usage(&discard_cmd);
|
443
|
+
}
|
444
|
+
|
445
|
+
offset = cvtnum(argv[optind]);
|
446
|
+
@@ -1876,18 +1980,6 @@ static const cmdinfo_t help_cmd = {
|
447
|
+
.oneline = "help for one or all commands",
|
448
|
+
};
|
449
|
+
|
450
|
+
-static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
|
451
|
+
-{
|
452
|
+
- if (ct->flags & CMD_FLAG_GLOBAL) {
|
453
|
+
- return 1;
|
454
|
+
- }
|
455
|
+
- if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
|
456
|
+
- fprintf(stderr, "no file open, try 'help open'\n");
|
457
|
+
- return 0;
|
458
|
+
- }
|
459
|
+
- return 1;
|
460
|
+
-}
|
461
|
+
-
|
462
|
+
bool qemuio_command(const char *cmd)
|
463
|
+
{
|
464
|
+
char *input;
|
465
|
+
@@ -1915,27 +2007,25 @@ bool qemuio_command(const char *cmd)
|
466
|
+
static void __attribute((constructor)) init_qemuio_commands(void)
|
467
|
+
{
|
468
|
+
/* initialize commands */
|
469
|
+
- add_command(&help_cmd);
|
470
|
+
- add_command(&read_cmd);
|
471
|
+
- add_command(&readv_cmd);
|
472
|
+
- add_command(&write_cmd);
|
473
|
+
- add_command(&writev_cmd);
|
474
|
+
- add_command(&multiwrite_cmd);
|
475
|
+
- add_command(&aio_read_cmd);
|
476
|
+
- add_command(&aio_write_cmd);
|
477
|
+
- add_command(&aio_flush_cmd);
|
478
|
+
- add_command(&flush_cmd);
|
479
|
+
- add_command(&truncate_cmd);
|
480
|
+
- add_command(&length_cmd);
|
481
|
+
- add_command(&info_cmd);
|
482
|
+
- add_command(&discard_cmd);
|
483
|
+
- add_command(&alloc_cmd);
|
484
|
+
- add_command(&map_cmd);
|
485
|
+
- add_command(&break_cmd);
|
486
|
+
- add_command(&resume_cmd);
|
487
|
+
- add_command(&wait_break_cmd);
|
488
|
+
- add_command(&abort_cmd);
|
489
|
+
- add_command(&sleep_cmd);
|
490
|
+
-
|
491
|
+
- add_check_command(init_check_command);
|
492
|
+
+ qemuio_add_command(&help_cmd);
|
493
|
+
+ qemuio_add_command(&read_cmd);
|
494
|
+
+ qemuio_add_command(&readv_cmd);
|
495
|
+
+ qemuio_add_command(&write_cmd);
|
496
|
+
+ qemuio_add_command(&writev_cmd);
|
497
|
+
+ qemuio_add_command(&multiwrite_cmd);
|
498
|
+
+ qemuio_add_command(&aio_read_cmd);
|
499
|
+
+ qemuio_add_command(&aio_write_cmd);
|
500
|
+
+ qemuio_add_command(&aio_flush_cmd);
|
501
|
+
+ qemuio_add_command(&flush_cmd);
|
502
|
+
+ qemuio_add_command(&truncate_cmd);
|
503
|
+
+ qemuio_add_command(&length_cmd);
|
504
|
+
+ qemuio_add_command(&info_cmd);
|
505
|
+
+ qemuio_add_command(&discard_cmd);
|
506
|
+
+ qemuio_add_command(&alloc_cmd);
|
507
|
+
+ qemuio_add_command(&map_cmd);
|
508
|
+
+ qemuio_add_command(&break_cmd);
|
509
|
+
+ qemuio_add_command(&resume_cmd);
|
510
|
+
+ qemuio_add_command(&wait_break_cmd);
|
511
|
+
+ qemuio_add_command(&abort_cmd);
|
512
|
+
+ qemuio_add_command(&sleep_cmd);
|
513
|
+
}
|
514
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
515
|
+
index b86bfbf..97af39e 100644
|
516
|
+
--- a/qemu-io.c
|
517
|
+
+++ b/qemu-io.c
|
518
|
+
@@ -155,7 +155,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
|
519
|
+
qemu_opts_del(qopts);
|
520
|
+
break;
|
521
|
+
default:
|
522
|
+
- return command_usage(&open_cmd);
|
523
|
+
+ return qemuio_command_usage(&open_cmd);
|
524
|
+
}
|
525
|
+
}
|
526
|
+
|
527
|
+
@@ -164,7 +164,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
|
528
|
+
}
|
529
|
+
|
530
|
+
if (optind != argc - 1) {
|
531
|
+
- return command_usage(&open_cmd);
|
532
|
+
+ return qemuio_command_usage(&open_cmd);
|
533
|
+
}
|
534
|
+
|
535
|
+
return openfile(argv[optind], flags, growable, opts);
|
536
|
+
@@ -300,9 +300,9 @@ int main(int argc, char **argv)
|
537
|
+
bdrv_init();
|
538
|
+
|
539
|
+
/* initialize commands */
|
540
|
+
- add_command(&quit_cmd);
|
541
|
+
- add_command(&open_cmd);
|
542
|
+
- add_command(&close_cmd);
|
543
|
+
+ qemuio_add_command(&quit_cmd);
|
544
|
+
+ qemuio_add_command(&open_cmd);
|
545
|
+
+ qemuio_add_command(&close_cmd);
|
546
|
+
|
547
|
+
/* open the device */
|
548
|
+
if (!readonly) {
|
549
|
+
--
|
550
|
+
1.8.3.1
|
551
|
+
|
@@ -0,0 +1,223 @@
|
|
1
|
+
From 8d6f59c923b536461df1aea18045535b090984fb Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:27 +0100
|
4
|
+
Subject: [PATCH 08/27] qemu-io: Move 'help' function
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-9-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68435
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 08/21] qemu-io: Move 'help' function
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
No reason to treat it different from other commands. Move it to
|
18
|
+
qemu-io-cmds.c, adapt the coding style and register it like any other
|
19
|
+
command.
|
20
|
+
|
21
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
22
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
23
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
24
|
+
(cherry picked from commit f18a834a92f0b490cefeb71410f3f25b969d336f)
|
25
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
26
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
27
|
+
|
28
|
+
Conflicts:
|
29
|
+
qemu-io-cmds: patch context (from sleep_f)
|
30
|
+
|
31
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
32
|
+
---
|
33
|
+
cmd.c | 79 ----------------------------------------------------------
|
34
|
+
cmd.h | 1 -
|
35
|
+
qemu-io-cmds.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++-
|
36
|
+
3 files changed, 65 insertions(+), 81 deletions(-)
|
37
|
+
|
38
|
+
diff --git a/cmd.c b/cmd.c
|
39
|
+
index 7ae978f..2941ad3 100644
|
40
|
+
--- a/cmd.c
|
41
|
+
+++ b/cmd.c
|
42
|
+
@@ -439,82 +439,3 @@ quit_init(void)
|
43
|
+
|
44
|
+
add_command(&quit_cmd);
|
45
|
+
}
|
46
|
+
-
|
47
|
+
-/* from libxcmd/help.c */
|
48
|
+
-
|
49
|
+
-static cmdinfo_t help_cmd;
|
50
|
+
-static void help_onecmd(const char *cmd, const cmdinfo_t *ct);
|
51
|
+
-static void help_oneline(const char *cmd, const cmdinfo_t *ct);
|
52
|
+
-
|
53
|
+
-static void
|
54
|
+
-help_all(void)
|
55
|
+
-{
|
56
|
+
- const cmdinfo_t *ct;
|
57
|
+
-
|
58
|
+
- for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++)
|
59
|
+
- help_oneline(ct->name, ct);
|
60
|
+
- printf(_("\nUse 'help commandname' for extended help.\n"));
|
61
|
+
-}
|
62
|
+
-
|
63
|
+
-static int
|
64
|
+
-help_f(
|
65
|
+
- BlockDriverState *bs,
|
66
|
+
- int argc,
|
67
|
+
- char **argv)
|
68
|
+
-{
|
69
|
+
- const cmdinfo_t *ct;
|
70
|
+
-
|
71
|
+
- if (argc == 1) {
|
72
|
+
- help_all();
|
73
|
+
- return 0;
|
74
|
+
- }
|
75
|
+
- ct = find_command(argv[1]);
|
76
|
+
- if (ct == NULL) {
|
77
|
+
- printf(_("command %s not found\n"), argv[1]);
|
78
|
+
- return 0;
|
79
|
+
- }
|
80
|
+
- help_onecmd(argv[1], ct);
|
81
|
+
- return 0;
|
82
|
+
-}
|
83
|
+
-
|
84
|
+
-static void
|
85
|
+
-help_onecmd(
|
86
|
+
- const char *cmd,
|
87
|
+
- const cmdinfo_t *ct)
|
88
|
+
-{
|
89
|
+
- help_oneline(cmd, ct);
|
90
|
+
- if (ct->help)
|
91
|
+
- ct->help();
|
92
|
+
-}
|
93
|
+
-
|
94
|
+
-static void
|
95
|
+
-help_oneline(
|
96
|
+
- const char *cmd,
|
97
|
+
- const cmdinfo_t *ct)
|
98
|
+
-{
|
99
|
+
- if (cmd)
|
100
|
+
- printf("%s ", cmd);
|
101
|
+
- else {
|
102
|
+
- printf("%s ", ct->name);
|
103
|
+
- if (ct->altname)
|
104
|
+
- printf("(or %s) ", ct->altname);
|
105
|
+
- }
|
106
|
+
- if (ct->args)
|
107
|
+
- printf("%s ", ct->args);
|
108
|
+
- printf("-- %s\n", ct->oneline);
|
109
|
+
-}
|
110
|
+
-
|
111
|
+
-void
|
112
|
+
-help_init(void)
|
113
|
+
-{
|
114
|
+
- help_cmd.name = _("help");
|
115
|
+
- help_cmd.altname = _("?");
|
116
|
+
- help_cmd.cfunc = help_f;
|
117
|
+
- help_cmd.argmin = 0;
|
118
|
+
- help_cmd.argmax = 1;
|
119
|
+
- help_cmd.flags = CMD_FLAG_GLOBAL;
|
120
|
+
- help_cmd.args = _("[command]");
|
121
|
+
- help_cmd.oneline = _("help for one or all commands");
|
122
|
+
-
|
123
|
+
- add_command(&help_cmd);
|
124
|
+
-}
|
125
|
+
diff --git a/cmd.h b/cmd.h
|
126
|
+
index d676408..89e7c6e 100644
|
127
|
+
--- a/cmd.h
|
128
|
+
+++ b/cmd.h
|
129
|
+
@@ -42,7 +42,6 @@ typedef struct cmdinfo {
|
130
|
+
extern cmdinfo_t *cmdtab;
|
131
|
+
extern int ncmds;
|
132
|
+
|
133
|
+
-void help_init(void);
|
134
|
+
void quit_init(void);
|
135
|
+
|
136
|
+
typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
|
137
|
+
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
138
|
+
index 09e4099..a8e891a 100644
|
139
|
+
--- a/qemu-io-cmds.c
|
140
|
+
+++ b/qemu-io-cmds.c
|
141
|
+
@@ -1811,6 +1811,70 @@ static const cmdinfo_t sleep_cmd = {
|
142
|
+
.oneline = "waits for the given value in milliseconds",
|
143
|
+
};
|
144
|
+
|
145
|
+
+static void help_oneline(const char *cmd, const cmdinfo_t *ct)
|
146
|
+
+{
|
147
|
+
+ if (cmd) {
|
148
|
+
+ printf("%s ", cmd);
|
149
|
+
+ } else {
|
150
|
+
+ printf("%s ", ct->name);
|
151
|
+
+ if (ct->altname) {
|
152
|
+
+ printf("(or %s) ", ct->altname);
|
153
|
+
+ }
|
154
|
+
+ }
|
155
|
+
+
|
156
|
+
+ if (ct->args) {
|
157
|
+
+ printf("%s ", ct->args);
|
158
|
+
+ }
|
159
|
+
+ printf("-- %s\n", ct->oneline);
|
160
|
+
+}
|
161
|
+
+
|
162
|
+
+static void help_onecmd(const char *cmd, const cmdinfo_t *ct)
|
163
|
+
+{
|
164
|
+
+ help_oneline(cmd, ct);
|
165
|
+
+ if (ct->help) {
|
166
|
+
+ ct->help();
|
167
|
+
+ }
|
168
|
+
+}
|
169
|
+
+
|
170
|
+
+static void help_all(void)
|
171
|
+
+{
|
172
|
+
+ const cmdinfo_t *ct;
|
173
|
+
+
|
174
|
+
+ for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
|
175
|
+
+ help_oneline(ct->name, ct);
|
176
|
+
+ }
|
177
|
+
+ printf("\nUse 'help commandname' for extended help.\n");
|
178
|
+
+}
|
179
|
+
+
|
180
|
+
+static int help_f(BlockDriverState *bs, int argc, char **argv)
|
181
|
+
+{
|
182
|
+
+ const cmdinfo_t *ct;
|
183
|
+
+
|
184
|
+
+ if (argc == 1) {
|
185
|
+
+ help_all();
|
186
|
+
+ return 0;
|
187
|
+
+ }
|
188
|
+
+
|
189
|
+
+ ct = find_command(argv[1]);
|
190
|
+
+ if (ct == NULL) {
|
191
|
+
+ printf("command %s not found\n", argv[1]);
|
192
|
+
+ return 0;
|
193
|
+
+ }
|
194
|
+
+
|
195
|
+
+ help_onecmd(argv[1], ct);
|
196
|
+
+ return 0;
|
197
|
+
+}
|
198
|
+
+
|
199
|
+
+static const cmdinfo_t help_cmd = {
|
200
|
+
+ .name = "help",
|
201
|
+
+ .altname = "?",
|
202
|
+
+ .cfunc = help_f,
|
203
|
+
+ .argmin = 0,
|
204
|
+
+ .argmax = 1,
|
205
|
+
+ .flags = CMD_FLAG_GLOBAL,
|
206
|
+
+ .args = "[command]",
|
207
|
+
+ .oneline = "help for one or all commands",
|
208
|
+
+};
|
209
|
+
|
210
|
+
static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
|
211
|
+
{
|
212
|
+
@@ -1851,7 +1915,7 @@ bool qemuio_command(const char *cmd)
|
213
|
+
static void __attribute((constructor)) init_qemuio_commands(void)
|
214
|
+
{
|
215
|
+
/* initialize commands */
|
216
|
+
- help_init();
|
217
|
+
+ add_command(&help_cmd);
|
218
|
+
add_command(&read_cmd);
|
219
|
+
add_command(&readv_cmd);
|
220
|
+
add_command(&write_cmd);
|
221
|
+
--
|
222
|
+
1.8.3.1
|
223
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
From 4ab2a72fcfc65bd78cf60e6e5a29e2189fddf877 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:29 +0100
|
4
|
+
Subject: [PATCH 10/27] qemu-io: Move qemu_strsep() to cutils.c
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-11-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68440
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 10/21] qemu-io: Move qemu_strsep() to cutils.c
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
18
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
19
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
20
|
+
(cherry picked from commit a38ed811474e953371f848233208c2026c2d1195)
|
21
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
22
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
23
|
+
---
|
24
|
+
cmd.c | 21 ---------------------
|
25
|
+
include/qemu-common.h | 1 +
|
26
|
+
util/cutils.c | 21 +++++++++++++++++++++
|
27
|
+
3 files changed, 22 insertions(+), 21 deletions(-)
|
28
|
+
|
29
|
+
diff --git a/cmd.c b/cmd.c
|
30
|
+
index 8496e74..f6bf2c5 100644
|
31
|
+
--- a/cmd.c
|
32
|
+
+++ b/cmd.c
|
33
|
+
@@ -255,27 +255,6 @@ fetchline(void)
|
34
|
+
}
|
35
|
+
#endif
|
36
|
+
|
37
|
+
-static char *qemu_strsep(char **input, const char *delim)
|
38
|
+
-{
|
39
|
+
- char *result = *input;
|
40
|
+
- if (result != NULL) {
|
41
|
+
- char *p;
|
42
|
+
-
|
43
|
+
- for (p = result; *p != '\0'; p++) {
|
44
|
+
- if (strchr(delim, *p)) {
|
45
|
+
- break;
|
46
|
+
- }
|
47
|
+
- }
|
48
|
+
- if (*p == '\0') {
|
49
|
+
- *input = NULL;
|
50
|
+
- } else {
|
51
|
+
- *p = '\0';
|
52
|
+
- *input = p + 1;
|
53
|
+
- }
|
54
|
+
- }
|
55
|
+
- return result;
|
56
|
+
-}
|
57
|
+
-
|
58
|
+
char **breakline(char *input, int *count)
|
59
|
+
{
|
60
|
+
int c = 0;
|
61
|
+
diff --git a/include/qemu-common.h b/include/qemu-common.h
|
62
|
+
index 67f57c9..8c1132c 100644
|
63
|
+
--- a/include/qemu-common.h
|
64
|
+
+++ b/include/qemu-common.h
|
65
|
+
@@ -161,6 +161,7 @@ char *pstrcat(char *buf, int buf_size, const char *s);
|
66
|
+
int strstart(const char *str, const char *val, const char **ptr);
|
67
|
+
int stristart(const char *str, const char *val, const char **ptr);
|
68
|
+
int qemu_strnlen(const char *s, int max_len);
|
69
|
+
+char *qemu_strsep(char **input, const char *delim);
|
70
|
+
time_t mktimegm(struct tm *tm);
|
71
|
+
int qemu_fls(int i);
|
72
|
+
int qemu_fdatasync(int fd);
|
73
|
+
diff --git a/util/cutils.c b/util/cutils.c
|
74
|
+
index 8f28896..0116fcd 100644
|
75
|
+
--- a/util/cutils.c
|
76
|
+
+++ b/util/cutils.c
|
77
|
+
@@ -107,6 +107,27 @@ int qemu_strnlen(const char *s, int max_len)
|
78
|
+
return i;
|
79
|
+
}
|
80
|
+
|
81
|
+
+char *qemu_strsep(char **input, const char *delim)
|
82
|
+
+{
|
83
|
+
+ char *result = *input;
|
84
|
+
+ if (result != NULL) {
|
85
|
+
+ char *p;
|
86
|
+
+
|
87
|
+
+ for (p = result; *p != '\0'; p++) {
|
88
|
+
+ if (strchr(delim, *p)) {
|
89
|
+
+ break;
|
90
|
+
+ }
|
91
|
+
+ }
|
92
|
+
+ if (*p == '\0') {
|
93
|
+
+ *input = NULL;
|
94
|
+
+ } else {
|
95
|
+
+ *p = '\0';
|
96
|
+
+ *input = p + 1;
|
97
|
+
+ }
|
98
|
+
+ }
|
99
|
+
+ return result;
|
100
|
+
+}
|
101
|
+
+
|
102
|
+
time_t mktimegm(struct tm *tm)
|
103
|
+
{
|
104
|
+
time_t t;
|
105
|
+
--
|
106
|
+
1.8.3.1
|
107
|
+
|
@@ -0,0 +1,119 @@
|
|
1
|
+
From 6ea43a1599b4abdfe480d6e963dbbafa9339601a Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:28 +0100
|
4
|
+
Subject: [PATCH 09/27] qemu-io: Move 'quit' function
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-10-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68436
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 09/21] qemu-io: Move 'quit' function
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
This one only makes sense in the context of the qemu-io tool, so move it
|
18
|
+
to qemu-io.c. Adapt coding style and register it like other commands.
|
19
|
+
|
20
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
21
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
22
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
23
|
+
(cherry picked from commit e681be7eca0143fe7259ce8233fe5dd8898d072f)
|
24
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
cmd.c | 29 -----------------------------
|
28
|
+
cmd.h | 2 --
|
29
|
+
qemu-io.c | 17 ++++++++++++++++-
|
30
|
+
3 files changed, 16 insertions(+), 32 deletions(-)
|
31
|
+
|
32
|
+
diff --git a/cmd.c b/cmd.c
|
33
|
+
index 2941ad3..8496e74 100644
|
34
|
+
--- a/cmd.c
|
35
|
+
+++ b/cmd.c
|
36
|
+
@@ -410,32 +410,3 @@ timestr(
|
37
|
+
snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
|
38
|
+
}
|
39
|
+
}
|
40
|
+
-
|
41
|
+
-
|
42
|
+
-/* from libxcmd/quit.c */
|
43
|
+
-
|
44
|
+
-static cmdinfo_t quit_cmd;
|
45
|
+
-
|
46
|
+
-/* ARGSUSED */
|
47
|
+
-static int
|
48
|
+
-quit_f(
|
49
|
+
- BlockDriverState *bs,
|
50
|
+
- int argc,
|
51
|
+
- char **argv)
|
52
|
+
-{
|
53
|
+
- return 1;
|
54
|
+
-}
|
55
|
+
-
|
56
|
+
-void
|
57
|
+
-quit_init(void)
|
58
|
+
-{
|
59
|
+
- quit_cmd.name = _("quit");
|
60
|
+
- quit_cmd.altname = _("q");
|
61
|
+
- quit_cmd.cfunc = quit_f;
|
62
|
+
- quit_cmd.argmin = -1;
|
63
|
+
- quit_cmd.argmax = -1;
|
64
|
+
- quit_cmd.flags = CMD_FLAG_GLOBAL;
|
65
|
+
- quit_cmd.oneline = _("exit the program");
|
66
|
+
-
|
67
|
+
- add_command(&quit_cmd);
|
68
|
+
-}
|
69
|
+
diff --git a/cmd.h b/cmd.h
|
70
|
+
index 89e7c6e..5b6f61b 100644
|
71
|
+
--- a/cmd.h
|
72
|
+
+++ b/cmd.h
|
73
|
+
@@ -42,8 +42,6 @@ typedef struct cmdinfo {
|
74
|
+
extern cmdinfo_t *cmdtab;
|
75
|
+
extern int ncmds;
|
76
|
+
|
77
|
+
-void quit_init(void);
|
78
|
+
-
|
79
|
+
typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
|
80
|
+
|
81
|
+
void add_command(const cmdinfo_t *ci);
|
82
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
83
|
+
index 4f1c808..b86bfbf 100644
|
84
|
+
--- a/qemu-io.c
|
85
|
+
+++ b/qemu-io.c
|
86
|
+
@@ -170,6 +170,21 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
|
87
|
+
return openfile(argv[optind], flags, growable, opts);
|
88
|
+
}
|
89
|
+
|
90
|
+
+static int quit_f(BlockDriverState *bs, int argc, char **argv)
|
91
|
+
+{
|
92
|
+
+ return 1;
|
93
|
+
+}
|
94
|
+
+
|
95
|
+
+static const cmdinfo_t quit_cmd = {
|
96
|
+
+ .name = "quit",
|
97
|
+
+ .altname = "q",
|
98
|
+
+ .cfunc = quit_f,
|
99
|
+
+ .argmin = -1,
|
100
|
+
+ .argmax = -1,
|
101
|
+
+ .flags = CMD_FLAG_GLOBAL,
|
102
|
+
+ .oneline = "exit the program",
|
103
|
+
+};
|
104
|
+
+
|
105
|
+
static void usage(const char *name)
|
106
|
+
{
|
107
|
+
printf(
|
108
|
+
@@ -285,7 +300,7 @@ int main(int argc, char **argv)
|
109
|
+
bdrv_init();
|
110
|
+
|
111
|
+
/* initialize commands */
|
112
|
+
- quit_init();
|
113
|
+
+ add_command(&quit_cmd);
|
114
|
+
add_command(&open_cmd);
|
115
|
+
add_command(&close_cmd);
|
116
|
+
|
117
|
+
--
|
118
|
+
1.8.3.1
|
119
|
+
|
@@ -0,0 +1,330 @@
|
|
1
|
+
From f0e4ec43a0a3af6f1e385fae17527ed76cdb00e4 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:32 +0100
|
4
|
+
Subject: [PATCH 13/27] qemu-io: Move remaining helpers from cmd.c
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-14-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68437
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 13/21] qemu-io: Move remaining helpers from cmd.c
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
18
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
19
|
+
(cherry picked from commit 0b613881ae8fc59359b3d91e666fea6c9b1e731b)
|
20
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
21
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
22
|
+
---
|
23
|
+
Makefile | 2 +-
|
24
|
+
cmd.c | 139 ---------------------------------------------------------
|
25
|
+
cmd.h | 14 ------
|
26
|
+
qemu-io-cmds.c | 104 ++++++++++++++++++++++++++++++++++++++++++
|
27
|
+
4 files changed, 105 insertions(+), 154 deletions(-)
|
28
|
+
delete mode 100644 cmd.c
|
29
|
+
|
30
|
+
diff --git a/Makefile b/Makefile
|
31
|
+
index f28ce29..f403057 100644
|
32
|
+
--- a/Makefile
|
33
|
+
+++ b/Makefile
|
34
|
+
@@ -205,7 +205,7 @@ qemu-img.o: qemu-img-cmds.h
|
35
|
+
|
36
|
+
qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
|
37
|
+
qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
|
38
|
+
-qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
|
39
|
+
+qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o $(block-obj-y) libqemuutil.a libqemustub.a
|
40
|
+
|
41
|
+
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
|
42
|
+
|
43
|
+
diff --git a/cmd.c b/cmd.c
|
44
|
+
deleted file mode 100644
|
45
|
+
index 26d38a8..0000000
|
46
|
+
--- a/cmd.c
|
47
|
+
+++ /dev/null
|
48
|
+
|
49
|
+
-/*
|
50
|
+
- * Copyright (c) 2003-2005 Silicon Graphics, Inc.
|
51
|
+
- * All Rights Reserved.
|
52
|
+
- *
|
53
|
+
- * This program is free software; you can redistribute it and/or
|
54
|
+
- * modify it under the terms of the GNU General Public License as
|
55
|
+
- * published by the Free Software Foundation.
|
56
|
+
- *
|
57
|
+
- * This program is distributed in the hope that it would be useful,
|
58
|
+
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
59
|
+
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
60
|
+
- * GNU General Public License for more details.
|
61
|
+
- *
|
62
|
+
- * You should have received a copy of the GNU General Public License
|
63
|
+
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
64
|
+
- */
|
65
|
+
-
|
66
|
+
-#include <stdio.h>
|
67
|
+
-#include <stdlib.h>
|
68
|
+
-#include <string.h>
|
69
|
+
-#include <ctype.h>
|
70
|
+
-#include <errno.h>
|
71
|
+
-#include <sys/time.h>
|
72
|
+
-#include <getopt.h>
|
73
|
+
-
|
74
|
+
-#include "cmd.h"
|
75
|
+
-#include "block/aio.h"
|
76
|
+
-#include "qemu/main-loop.h"
|
77
|
+
-
|
78
|
+
-#define _(x) x /* not gettext support yet */
|
79
|
+
-
|
80
|
+
-/* from libxcmd/command.c */
|
81
|
+
-
|
82
|
+
-#define EXABYTES(x) ((long long)(x) << 60)
|
83
|
+
-#define PETABYTES(x) ((long long)(x) << 50)
|
84
|
+
-#define TERABYTES(x) ((long long)(x) << 40)
|
85
|
+
-#define GIGABYTES(x) ((long long)(x) << 30)
|
86
|
+
-#define MEGABYTES(x) ((long long)(x) << 20)
|
87
|
+
-#define KILOBYTES(x) ((long long)(x) << 10)
|
88
|
+
-
|
89
|
+
-#define TO_EXABYTES(x) ((x) / EXABYTES(1))
|
90
|
+
-#define TO_PETABYTES(x) ((x) / PETABYTES(1))
|
91
|
+
-#define TO_TERABYTES(x) ((x) / TERABYTES(1))
|
92
|
+
-#define TO_GIGABYTES(x) ((x) / GIGABYTES(1))
|
93
|
+
-#define TO_MEGABYTES(x) ((x) / MEGABYTES(1))
|
94
|
+
-#define TO_KILOBYTES(x) ((x) / KILOBYTES(1))
|
95
|
+
-
|
96
|
+
-void
|
97
|
+
-cvtstr(
|
98
|
+
- double value,
|
99
|
+
- char *str,
|
100
|
+
- size_t size)
|
101
|
+
-{
|
102
|
+
- char *trim;
|
103
|
+
- const char *suffix;
|
104
|
+
-
|
105
|
+
- if (value >= EXABYTES(1)) {
|
106
|
+
- suffix = " EiB";
|
107
|
+
- snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
|
108
|
+
- } else if (value >= PETABYTES(1)) {
|
109
|
+
- suffix = " PiB";
|
110
|
+
- snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
|
111
|
+
- } else if (value >= TERABYTES(1)) {
|
112
|
+
- suffix = " TiB";
|
113
|
+
- snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
|
114
|
+
- } else if (value >= GIGABYTES(1)) {
|
115
|
+
- suffix = " GiB";
|
116
|
+
- snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
|
117
|
+
- } else if (value >= MEGABYTES(1)) {
|
118
|
+
- suffix = " MiB";
|
119
|
+
- snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
|
120
|
+
- } else if (value >= KILOBYTES(1)) {
|
121
|
+
- suffix = " KiB";
|
122
|
+
- snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
|
123
|
+
- } else {
|
124
|
+
- suffix = " bytes";
|
125
|
+
- snprintf(str, size - 6, "%f", value);
|
126
|
+
- }
|
127
|
+
-
|
128
|
+
- trim = strstr(str, ".000");
|
129
|
+
- if (trim) {
|
130
|
+
- strcpy(trim, suffix);
|
131
|
+
- } else {
|
132
|
+
- strcat(str, suffix);
|
133
|
+
- }
|
134
|
+
-}
|
135
|
+
-
|
136
|
+
-struct timeval
|
137
|
+
-tsub(struct timeval t1, struct timeval t2)
|
138
|
+
-{
|
139
|
+
- t1.tv_usec -= t2.tv_usec;
|
140
|
+
- if (t1.tv_usec < 0) {
|
141
|
+
- t1.tv_usec += 1000000;
|
142
|
+
- t1.tv_sec--;
|
143
|
+
- }
|
144
|
+
- t1.tv_sec -= t2.tv_sec;
|
145
|
+
- return t1;
|
146
|
+
-}
|
147
|
+
-
|
148
|
+
-double
|
149
|
+
-tdiv(double value, struct timeval tv)
|
150
|
+
-{
|
151
|
+
- return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
|
152
|
+
-}
|
153
|
+
-
|
154
|
+
-#define HOURS(sec) ((sec) / (60 * 60))
|
155
|
+
-#define MINUTES(sec) (((sec) % (60 * 60)) / 60)
|
156
|
+
-#define SECONDS(sec) ((sec) % 60)
|
157
|
+
-
|
158
|
+
-void
|
159
|
+
-timestr(
|
160
|
+
- struct timeval *tv,
|
161
|
+
- char *ts,
|
162
|
+
- size_t size,
|
163
|
+
- int format)
|
164
|
+
-{
|
165
|
+
- double usec = (double)tv->tv_usec / 1000000.0;
|
166
|
+
-
|
167
|
+
- if (format & TERSE_FIXED_TIME) {
|
168
|
+
- if (!HOURS(tv->tv_sec)) {
|
169
|
+
- snprintf(ts, size, "%u:%02u.%02u",
|
170
|
+
- (unsigned int) MINUTES(tv->tv_sec),
|
171
|
+
- (unsigned int) SECONDS(tv->tv_sec),
|
172
|
+
- (unsigned int) (usec * 100));
|
173
|
+
- return;
|
174
|
+
- }
|
175
|
+
- format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
|
176
|
+
- }
|
177
|
+
-
|
178
|
+
- if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
|
179
|
+
- snprintf(ts, size, "%u:%02u:%02u.%02u",
|
180
|
+
- (unsigned int) HOURS(tv->tv_sec),
|
181
|
+
- (unsigned int) MINUTES(tv->tv_sec),
|
182
|
+
- (unsigned int) SECONDS(tv->tv_sec),
|
183
|
+
- (unsigned int) (usec * 100));
|
184
|
+
- } else {
|
185
|
+
- snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
|
186
|
+
- }
|
187
|
+
-}
|
188
|
+
diff --git a/cmd.h b/cmd.h
|
189
|
+
index da0c7cf..9907795 100644
|
190
|
+
--- a/cmd.h
|
191
|
+
+++ b/cmd.h
|
192
|
+
@@ -43,20 +43,6 @@ void qemuio_add_command(const cmdinfo_t *ci);
|
193
|
+
|
194
|
+
int qemuio_command_usage(const cmdinfo_t *ci);
|
195
|
+
|
196
|
+
-/* from input.h */
|
197
|
+
-void cvtstr(double value, char *str, size_t sz);
|
198
|
+
-
|
199
|
+
-struct timeval tsub(struct timeval t1, struct timeval t2);
|
200
|
+
-double tdiv(double value, struct timeval tv);
|
201
|
+
-
|
202
|
+
-enum {
|
203
|
+
- DEFAULT_TIME = 0x0,
|
204
|
+
- TERSE_FIXED_TIME = 0x1,
|
205
|
+
- VERBOSE_FIXED_TIME = 0x2
|
206
|
+
-};
|
207
|
+
-
|
208
|
+
-void timestr(struct timeval *tv, char *str, size_t sz, int flags);
|
209
|
+
-
|
210
|
+
bool qemuio_command(const char *cmd);
|
211
|
+
|
212
|
+
#endif /* __COMMAND_H__ */
|
213
|
+
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
214
|
+
index 27a903f..1db7fb9 100644
|
215
|
+
--- a/qemu-io-cmds.c
|
216
|
+
+++ b/qemu-io-cmds.c
|
217
|
+
@@ -127,6 +127,110 @@ static int64_t cvtnum(const char *s)
|
218
|
+
return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
|
219
|
+
}
|
220
|
+
|
221
|
+
+#define EXABYTES(x) ((long long)(x) << 60)
|
222
|
+
+#define PETABYTES(x) ((long long)(x) << 50)
|
223
|
+
+#define TERABYTES(x) ((long long)(x) << 40)
|
224
|
+
+#define GIGABYTES(x) ((long long)(x) << 30)
|
225
|
+
+#define MEGABYTES(x) ((long long)(x) << 20)
|
226
|
+
+#define KILOBYTES(x) ((long long)(x) << 10)
|
227
|
+
+
|
228
|
+
+#define TO_EXABYTES(x) ((x) / EXABYTES(1))
|
229
|
+
+#define TO_PETABYTES(x) ((x) / PETABYTES(1))
|
230
|
+
+#define TO_TERABYTES(x) ((x) / TERABYTES(1))
|
231
|
+
+#define TO_GIGABYTES(x) ((x) / GIGABYTES(1))
|
232
|
+
+#define TO_MEGABYTES(x) ((x) / MEGABYTES(1))
|
233
|
+
+#define TO_KILOBYTES(x) ((x) / KILOBYTES(1))
|
234
|
+
+
|
235
|
+
+static void cvtstr(double value, char *str, size_t size)
|
236
|
+
+{
|
237
|
+
+ char *trim;
|
238
|
+
+ const char *suffix;
|
239
|
+
+
|
240
|
+
+ if (value >= EXABYTES(1)) {
|
241
|
+
+ suffix = " EiB";
|
242
|
+
+ snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
|
243
|
+
+ } else if (value >= PETABYTES(1)) {
|
244
|
+
+ suffix = " PiB";
|
245
|
+
+ snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
|
246
|
+
+ } else if (value >= TERABYTES(1)) {
|
247
|
+
+ suffix = " TiB";
|
248
|
+
+ snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
|
249
|
+
+ } else if (value >= GIGABYTES(1)) {
|
250
|
+
+ suffix = " GiB";
|
251
|
+
+ snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
|
252
|
+
+ } else if (value >= MEGABYTES(1)) {
|
253
|
+
+ suffix = " MiB";
|
254
|
+
+ snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
|
255
|
+
+ } else if (value >= KILOBYTES(1)) {
|
256
|
+
+ suffix = " KiB";
|
257
|
+
+ snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
|
258
|
+
+ } else {
|
259
|
+
+ suffix = " bytes";
|
260
|
+
+ snprintf(str, size - 6, "%f", value);
|
261
|
+
+ }
|
262
|
+
+
|
263
|
+
+ trim = strstr(str, ".000");
|
264
|
+
+ if (trim) {
|
265
|
+
+ strcpy(trim, suffix);
|
266
|
+
+ } else {
|
267
|
+
+ strcat(str, suffix);
|
268
|
+
+ }
|
269
|
+
+}
|
270
|
+
+
|
271
|
+
+
|
272
|
+
+
|
273
|
+
+static struct timeval tsub(struct timeval t1, struct timeval t2)
|
274
|
+
+{
|
275
|
+
+ t1.tv_usec -= t2.tv_usec;
|
276
|
+
+ if (t1.tv_usec < 0) {
|
277
|
+
+ t1.tv_usec += 1000000;
|
278
|
+
+ t1.tv_sec--;
|
279
|
+
+ }
|
280
|
+
+ t1.tv_sec -= t2.tv_sec;
|
281
|
+
+ return t1;
|
282
|
+
+}
|
283
|
+
+
|
284
|
+
+static double tdiv(double value, struct timeval tv)
|
285
|
+
+{
|
286
|
+
+ return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
|
287
|
+
+}
|
288
|
+
+
|
289
|
+
+#define HOURS(sec) ((sec) / (60 * 60))
|
290
|
+
+#define MINUTES(sec) (((sec) % (60 * 60)) / 60)
|
291
|
+
+#define SECONDS(sec) ((sec) % 60)
|
292
|
+
+
|
293
|
+
+enum {
|
294
|
+
+ DEFAULT_TIME = 0x0,
|
295
|
+
+ TERSE_FIXED_TIME = 0x1,
|
296
|
+
+ VERBOSE_FIXED_TIME = 0x2,
|
297
|
+
+};
|
298
|
+
+
|
299
|
+
+static void timestr(struct timeval *tv, char *ts, size_t size, int format)
|
300
|
+
+{
|
301
|
+
+ double usec = (double)tv->tv_usec / 1000000.0;
|
302
|
+
+
|
303
|
+
+ if (format & TERSE_FIXED_TIME) {
|
304
|
+
+ if (!HOURS(tv->tv_sec)) {
|
305
|
+
+ snprintf(ts, size, "%u:%02u.%02u",
|
306
|
+
+ (unsigned int) MINUTES(tv->tv_sec),
|
307
|
+
+ (unsigned int) SECONDS(tv->tv_sec),
|
308
|
+
+ (unsigned int) (usec * 100));
|
309
|
+
+ return;
|
310
|
+
+ }
|
311
|
+
+ format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
|
312
|
+
+ }
|
313
|
+
+
|
314
|
+
+ if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
|
315
|
+
+ snprintf(ts, size, "%u:%02u:%02u.%02u",
|
316
|
+
+ (unsigned int) HOURS(tv->tv_sec),
|
317
|
+
+ (unsigned int) MINUTES(tv->tv_sec),
|
318
|
+
+ (unsigned int) SECONDS(tv->tv_sec),
|
319
|
+
+ (unsigned int) (usec * 100));
|
320
|
+
+ } else {
|
321
|
+
+ snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
|
322
|
+
+ }
|
323
|
+
+}
|
324
|
+
+
|
325
|
+
/*
|
326
|
+
* Parse the pattern argument to various sub-commands.
|
327
|
+
*
|
328
|
+
--
|
329
|
+
1.8.3.1
|
330
|
+
|
@@ -0,0 +1,141 @@
|
|
1
|
+
From d16c34d6dc39a159326efda97101aed3c1481812 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:20 +0100
|
4
|
+
Subject: [PATCH 01/27] qemu-io: Remove unused args_command
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-2-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68429
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 01/21] qemu-io: Remove unused args_command
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
The original intention seems to be something with handling multiple
|
18
|
+
images at once, but this has never been implemented and the only
|
19
|
+
function ever registered is implemented to make everything behave like a
|
20
|
+
"global" command. Just do that unconditionally now.
|
21
|
+
|
22
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
23
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
24
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
25
|
+
(cherry picked from commit a23818f4ff3d7981f49453b739f589e4205930b5)
|
26
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
27
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
28
|
+
---
|
29
|
+
cmd.c | 28 ++--------------------------
|
30
|
+
cmd.h | 2 --
|
31
|
+
qemu-io.c | 10 ----------
|
32
|
+
3 files changed, 2 insertions(+), 38 deletions(-)
|
33
|
+
|
34
|
+
diff --git a/cmd.c b/cmd.c
|
35
|
+
index 10a8688..4e7579b 100644
|
36
|
+
--- a/cmd.c
|
37
|
+
+++ b/cmd.c
|
38
|
+
|
39
|
+
cmdinfo_t *cmdtab;
|
40
|
+
int ncmds;
|
41
|
+
|
42
|
+
-static argsfunc_t args_func;
|
43
|
+
static checkfunc_t check_func;
|
44
|
+
static int ncmdline;
|
45
|
+
static char **cmdline;
|
46
|
+
@@ -127,22 +126,6 @@ void add_user_command(char *optarg)
|
47
|
+
cmdline[ncmdline-1] = optarg;
|
48
|
+
}
|
49
|
+
|
50
|
+
-static int
|
51
|
+
-args_command(
|
52
|
+
- int index)
|
53
|
+
-{
|
54
|
+
- if (args_func)
|
55
|
+
- return args_func(index);
|
56
|
+
- return 0;
|
57
|
+
-}
|
58
|
+
-
|
59
|
+
-void
|
60
|
+
-add_args_command(
|
61
|
+
- argsfunc_t af)
|
62
|
+
-{
|
63
|
+
- args_func = af;
|
64
|
+
-}
|
65
|
+
-
|
66
|
+
static void prep_fetchline(void *opaque)
|
67
|
+
{
|
68
|
+
int *fetchable = opaque;
|
69
|
+
@@ -155,7 +138,7 @@ static char *get_prompt(void);
|
70
|
+
|
71
|
+
void command_loop(void)
|
72
|
+
{
|
73
|
+
- int c, i, j = 0, done = 0, fetchable = 0, prompted = 0;
|
74
|
+
+ int c, i, done = 0, fetchable = 0, prompted = 0;
|
75
|
+
char *input;
|
76
|
+
char **v;
|
77
|
+
const cmdinfo_t *ct;
|
78
|
+
@@ -171,14 +154,7 @@ void command_loop(void)
|
79
|
+
if (c) {
|
80
|
+
ct = find_command(v[0]);
|
81
|
+
if (ct) {
|
82
|
+
- if (ct->flags & CMD_FLAG_GLOBAL) {
|
83
|
+
- done = command(ct, c, v);
|
84
|
+
- } else {
|
85
|
+
- j = 0;
|
86
|
+
- while (!done && (j = args_command(j))) {
|
87
|
+
- done = command(ct, c, v);
|
88
|
+
- }
|
89
|
+
- }
|
90
|
+
+ done = command(ct, c, v);
|
91
|
+
} else {
|
92
|
+
fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
|
93
|
+
}
|
94
|
+
diff --git a/cmd.h b/cmd.h
|
95
|
+
index b763b19..8e6f753 100644
|
96
|
+
--- a/cmd.h
|
97
|
+
+++ b/cmd.h
|
98
|
+
@@ -41,12 +41,10 @@ extern int ncmds;
|
99
|
+
void help_init(void);
|
100
|
+
void quit_init(void);
|
101
|
+
|
102
|
+
-typedef int (*argsfunc_t)(int index);
|
103
|
+
typedef int (*checkfunc_t)(const cmdinfo_t *ci);
|
104
|
+
|
105
|
+
void add_command(const cmdinfo_t *ci);
|
106
|
+
void add_user_command(char *optarg);
|
107
|
+
-void add_args_command(argsfunc_t af);
|
108
|
+
void add_check_command(checkfunc_t cf);
|
109
|
+
|
110
|
+
const cmdinfo_t *find_command(const char *cmd);
|
111
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
112
|
+
index cc89947..9f66a78 100644
|
113
|
+
--- a/qemu-io.c
|
114
|
+
+++ b/qemu-io.c
|
115
|
+
@@ -1935,15 +1935,6 @@ static int open_f(int argc, char **argv)
|
116
|
+
return openfile(argv[optind], flags, growable, opts);
|
117
|
+
}
|
118
|
+
|
119
|
+
-static int init_args_command(int index)
|
120
|
+
-{
|
121
|
+
- /* only one device allowed so far */
|
122
|
+
- if (index >= 1) {
|
123
|
+
- return 0;
|
124
|
+
- }
|
125
|
+
- return ++index;
|
126
|
+
-}
|
127
|
+
-
|
128
|
+
static int init_check_command(const cmdinfo_t *ct)
|
129
|
+
{
|
130
|
+
if (ct->flags & CMD_FLAG_GLOBAL) {
|
131
|
+
@@ -2096,7 +2087,6 @@ int main(int argc, char **argv)
|
132
|
+
add_command(&abort_cmd);
|
133
|
+
add_command(&sleep_cmd);
|
134
|
+
|
135
|
+
- add_args_command(init_args_command);
|
136
|
+
add_check_command(init_check_command);
|
137
|
+
|
138
|
+
/* open the device */
|
139
|
+
--
|
140
|
+
1.8.3.1
|
141
|
+
|
@@ -0,0 +1,3789 @@
|
|
1
|
+
From 9bd448e0f256ac9327363a0f370b9616d967e986 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:25 +0100
|
4
|
+
Subject: [PATCH 06/27] qemu-io: Split off commands to qemu-io-cmds.c
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-7-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68434
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 06/21] qemu-io: Split off commands to qemu-io-cmds.c
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
This is the implementation of all qemu-io commands that make sense to be
|
18
|
+
called from the qemu monitor, i.e. everything except open, close and
|
19
|
+
quit.
|
20
|
+
|
21
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
22
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
23
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
24
|
+
(cherry picked from commit 797ac58cb2093ab9192d8998a1fef85d87cc8661)
|
25
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
26
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
27
|
+
|
28
|
+
Conflicts:
|
29
|
+
qemu-io.c: Minor differences, but as this is code motion,
|
30
|
+
The code motion had to be re-done to preserve
|
31
|
+
any backported changes.
|
32
|
+
qemu-io-cmds.c: re-created from downstream qemu-io.c.
|
33
|
+
|
34
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
35
|
+
---
|
36
|
+
Makefile | 2 +-
|
37
|
+
qemu-io-cmds.c | 1853 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
38
|
+
qemu-io.c | 1831 +------------------------------------------------------
|
39
|
+
3 files changed, 1856 insertions(+), 1830 deletions(-)
|
40
|
+
create mode 100644 qemu-io-cmds.c
|
41
|
+
|
42
|
+
diff --git a/Makefile b/Makefile
|
43
|
+
index 8407945..f28ce29 100644
|
44
|
+
--- a/Makefile
|
45
|
+
+++ b/Makefile
|
46
|
+
@@ -205,7 +205,7 @@ qemu-img.o: qemu-img-cmds.h
|
47
|
+
|
48
|
+
qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
|
49
|
+
qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
|
50
|
+
-qemu-io$(EXESUF): qemu-io.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
|
51
|
+
+qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
|
52
|
+
|
53
|
+
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
|
54
|
+
|
55
|
+
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
56
|
+
new file mode 100644
|
57
|
+
index 0000000..efa6070
|
58
|
+
--- /dev/null
|
59
|
+
+++ b/qemu-io-cmds.c
|
60
|
+
|
61
|
+
+/*
|
62
|
+
+ * Command line utility to exercise the QEMU I/O path.
|
63
|
+
+ *
|
64
|
+
+ * Copyright (C) 2009 Red Hat, Inc.
|
65
|
+
+ * Copyright (c) 2003-2005 Silicon Graphics, Inc.
|
66
|
+
+ *
|
67
|
+
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
68
|
+
+ * See the COPYING file in the top-level directory.
|
69
|
+
+ */
|
70
|
+
+
|
71
|
+
+#include "qemu-common.h"
|
72
|
+
+#include "block/block_int.h"
|
73
|
+
+#include "block/qapi.h"
|
74
|
+
+#include "cmd.h"
|
75
|
+
+
|
76
|
+
+#define CMD_NOFILE_OK 0x01
|
77
|
+
+
|
78
|
+
+int qemuio_misalign;
|
79
|
+
+
|
80
|
+
+static int64_t cvtnum(const char *s)
|
81
|
+
+{
|
82
|
+
+ char *end;
|
83
|
+
+ return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
|
84
|
+
+}
|
85
|
+
+
|
86
|
+
+/*
|
87
|
+
+ * Parse the pattern argument to various sub-commands.
|
88
|
+
+ *
|
89
|
+
+ * Because the pattern is used as an argument to memset it must evaluate
|
90
|
+
+ * to an unsigned integer that fits into a single byte.
|
91
|
+
+ */
|
92
|
+
+static int parse_pattern(const char *arg)
|
93
|
+
+{
|
94
|
+
+ char *endptr = NULL;
|
95
|
+
+ long pattern;
|
96
|
+
+
|
97
|
+
+ pattern = strtol(arg, &endptr, 0);
|
98
|
+
+ if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
|
99
|
+
+ printf("%s is not a valid pattern byte\n", arg);
|
100
|
+
+ return -1;
|
101
|
+
+ }
|
102
|
+
+
|
103
|
+
+ return pattern;
|
104
|
+
+}
|
105
|
+
+
|
106
|
+
+/*
|
107
|
+
+ * Memory allocation helpers.
|
108
|
+
+ *
|
109
|
+
+ * Make sure memory is aligned by default, or purposefully misaligned if
|
110
|
+
+ * that is specified on the command line.
|
111
|
+
+ */
|
112
|
+
+
|
113
|
+
+#define MISALIGN_OFFSET 16
|
114
|
+
+static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
|
115
|
+
+{
|
116
|
+
+ void *buf;
|
117
|
+
+
|
118
|
+
+ if (qemuio_misalign) {
|
119
|
+
+ len += MISALIGN_OFFSET;
|
120
|
+
+ }
|
121
|
+
+ buf = qemu_blockalign(bs, len);
|
122
|
+
+ memset(buf, pattern, len);
|
123
|
+
+ if (qemuio_misalign) {
|
124
|
+
+ buf += MISALIGN_OFFSET;
|
125
|
+
+ }
|
126
|
+
+ return buf;
|
127
|
+
+}
|
128
|
+
+
|
129
|
+
+static void qemu_io_free(void *p)
|
130
|
+
+{
|
131
|
+
+ if (qemuio_misalign) {
|
132
|
+
+ p -= MISALIGN_OFFSET;
|
133
|
+
+ }
|
134
|
+
+ qemu_vfree(p);
|
135
|
+
+}
|
136
|
+
+
|
137
|
+
+static void dump_buffer(const void *buffer, int64_t offset, int len)
|
138
|
+
+{
|
139
|
+
+ int i, j;
|
140
|
+
+ const uint8_t *p;
|
141
|
+
+
|
142
|
+
+ for (i = 0, p = buffer; i < len; i += 16) {
|
143
|
+
+ const uint8_t *s = p;
|
144
|
+
+
|
145
|
+
+ printf("%08" PRIx64 ": ", offset + i);
|
146
|
+
+ for (j = 0; j < 16 && i + j < len; j++, p++) {
|
147
|
+
+ printf("%02x ", *p);
|
148
|
+
+ }
|
149
|
+
+ printf(" ");
|
150
|
+
+ for (j = 0; j < 16 && i + j < len; j++, s++) {
|
151
|
+
+ if (isalnum(*s)) {
|
152
|
+
+ printf("%c", *s);
|
153
|
+
+ } else {
|
154
|
+
+ printf(".");
|
155
|
+
+ }
|
156
|
+
+ }
|
157
|
+
+ printf("\n");
|
158
|
+
+ }
|
159
|
+
+}
|
160
|
+
+
|
161
|
+
+static void print_report(const char *op, struct timeval *t, int64_t offset,
|
162
|
+
+ int count, int total, int cnt, int Cflag)
|
163
|
+
+{
|
164
|
+
+ char s1[64], s2[64], ts[64];
|
165
|
+
+
|
166
|
+
+ timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
|
167
|
+
+ if (!Cflag) {
|
168
|
+
+ cvtstr((double)total, s1, sizeof(s1));
|
169
|
+
+ cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
|
170
|
+
+ printf("%s %d/%d bytes at offset %" PRId64 "\n",
|
171
|
+
+ op, total, count, offset);
|
172
|
+
+ printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
|
173
|
+
+ s1, cnt, ts, s2, tdiv((double)cnt, *t));
|
174
|
+
+ } else {/* bytes,ops,time,bytes/sec,ops/sec */
|
175
|
+
+ printf("%d,%d,%s,%.3f,%.3f\n",
|
176
|
+
+ total, cnt, ts,
|
177
|
+
+ tdiv((double)total, *t),
|
178
|
+
+ tdiv((double)cnt, *t));
|
179
|
+
+ }
|
180
|
+
+}
|
181
|
+
+
|
182
|
+
+/*
|
183
|
+
+ * Parse multiple length statements for vectored I/O, and construct an I/O
|
184
|
+
+ * vector matching it.
|
185
|
+
+ */
|
186
|
+
+static void *
|
187
|
+
+create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
|
188
|
+
+ int pattern)
|
189
|
+
+{
|
190
|
+
+ size_t *sizes = g_new0(size_t, nr_iov);
|
191
|
+
+ size_t count = 0;
|
192
|
+
+ void *buf = NULL;
|
193
|
+
+ void *p;
|
194
|
+
+ int i;
|
195
|
+
+
|
196
|
+
+ for (i = 0; i < nr_iov; i++) {
|
197
|
+
+ char *arg = argv[i];
|
198
|
+
+ int64_t len;
|
199
|
+
+
|
200
|
+
+ len = cvtnum(arg);
|
201
|
+
+ if (len < 0) {
|
202
|
+
+ printf("non-numeric length argument -- %s\n", arg);
|
203
|
+
+ goto fail;
|
204
|
+
+ }
|
205
|
+
+
|
206
|
+
+ /* should be SIZE_T_MAX, but that doesn't exist */
|
207
|
+
+ if (len > INT_MAX) {
|
208
|
+
+ printf("too large length argument -- %s\n", arg);
|
209
|
+
+ goto fail;
|
210
|
+
+ }
|
211
|
+
+
|
212
|
+
+ if (len & 0x1ff) {
|
213
|
+
+ printf("length argument %" PRId64
|
214
|
+
+ " is not sector aligned\n", len);
|
215
|
+
+ goto fail;
|
216
|
+
+ }
|
217
|
+
+
|
218
|
+
+ sizes[i] = len;
|
219
|
+
+ count += len;
|
220
|
+
+ }
|
221
|
+
+
|
222
|
+
+ qemu_iovec_init(qiov, nr_iov);
|
223
|
+
+
|
224
|
+
+ buf = p = qemu_io_alloc(bs, count, pattern);
|
225
|
+
+
|
226
|
+
+ for (i = 0; i < nr_iov; i++) {
|
227
|
+
+ qemu_iovec_add(qiov, p, sizes[i]);
|
228
|
+
+ p += sizes[i];
|
229
|
+
+ }
|
230
|
+
+
|
231
|
+
+fail:
|
232
|
+
+ g_free(sizes);
|
233
|
+
+ return buf;
|
234
|
+
+}
|
235
|
+
+
|
236
|
+
+static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
237
|
+
+ int *total)
|
238
|
+
+{
|
239
|
+
+ int ret;
|
240
|
+
+
|
241
|
+
+ ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
|
242
|
+
+ if (ret < 0) {
|
243
|
+
+ return ret;
|
244
|
+
+ }
|
245
|
+
+ *total = count;
|
246
|
+
+ return 1;
|
247
|
+
+}
|
248
|
+
+
|
249
|
+
+static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
250
|
+
+ int *total)
|
251
|
+
+{
|
252
|
+
+ int ret;
|
253
|
+
+
|
254
|
+
+ ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
|
255
|
+
+ if (ret < 0) {
|
256
|
+
+ return ret;
|
257
|
+
+ }
|
258
|
+
+ *total = count;
|
259
|
+
+ return 1;
|
260
|
+
+}
|
261
|
+
+
|
262
|
+
+static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
263
|
+
+ int *total)
|
264
|
+
+{
|
265
|
+
+ *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
|
266
|
+
+ if (*total < 0) {
|
267
|
+
+ return *total;
|
268
|
+
+ }
|
269
|
+
+ return 1;
|
270
|
+
+}
|
271
|
+
+
|
272
|
+
+static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
273
|
+
+ int *total)
|
274
|
+
+{
|
275
|
+
+ *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
|
276
|
+
+ if (*total < 0) {
|
277
|
+
+ return *total;
|
278
|
+
+ }
|
279
|
+
+ return 1;
|
280
|
+
+}
|
281
|
+
+
|
282
|
+
+typedef struct {
|
283
|
+
+ BlockDriverState *bs;
|
284
|
+
+ int64_t offset;
|
285
|
+
+ int count;
|
286
|
+
+ int *total;
|
287
|
+
+ int ret;
|
288
|
+
+ bool done;
|
289
|
+
+} CoWriteZeroes;
|
290
|
+
+
|
291
|
+
+static void coroutine_fn co_write_zeroes_entry(void *opaque)
|
292
|
+
+{
|
293
|
+
+ CoWriteZeroes *data = opaque;
|
294
|
+
+
|
295
|
+
+ data->ret = bdrv_co_write_zeroes(data->bs, data->offset / BDRV_SECTOR_SIZE,
|
296
|
+
+ data->count / BDRV_SECTOR_SIZE, 0);
|
297
|
+
+ data->done = true;
|
298
|
+
+ if (data->ret < 0) {
|
299
|
+
+ *data->total = data->ret;
|
300
|
+
+ return;
|
301
|
+
+ }
|
302
|
+
+
|
303
|
+
+ *data->total = data->count;
|
304
|
+
+}
|
305
|
+
+
|
306
|
+
+static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
|
307
|
+
+ int *total)
|
308
|
+
+{
|
309
|
+
+ Coroutine *co;
|
310
|
+
+ CoWriteZeroes data = {
|
311
|
+
+ .bs = bs,
|
312
|
+
+ .offset = offset,
|
313
|
+
+ .count = count,
|
314
|
+
+ .total = total,
|
315
|
+
+ .done = false,
|
316
|
+
+ };
|
317
|
+
+
|
318
|
+
+ co = qemu_coroutine_create(co_write_zeroes_entry);
|
319
|
+
+ qemu_coroutine_enter(co, &data);
|
320
|
+
+ while (!data.done) {
|
321
|
+
+ qemu_aio_wait();
|
322
|
+
+ }
|
323
|
+
+ if (data.ret < 0) {
|
324
|
+
+ return data.ret;
|
325
|
+
+ } else {
|
326
|
+
+ return 1;
|
327
|
+
+ }
|
328
|
+
+}
|
329
|
+
+
|
330
|
+
+static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
|
331
|
+
+ int count, int *total)
|
332
|
+
+{
|
333
|
+
+ int ret;
|
334
|
+
+
|
335
|
+
+ ret = bdrv_write_compressed(bs, offset >> 9, (uint8_t *)buf, count >> 9);
|
336
|
+
+ if (ret < 0) {
|
337
|
+
+ return ret;
|
338
|
+
+ }
|
339
|
+
+ *total = count;
|
340
|
+
+ return 1;
|
341
|
+
+}
|
342
|
+
+
|
343
|
+
+static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
|
344
|
+
+ int count, int *total)
|
345
|
+
+{
|
346
|
+
+ *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
|
347
|
+
+ if (*total < 0) {
|
348
|
+
+ return *total;
|
349
|
+
+ }
|
350
|
+
+ return 1;
|
351
|
+
+}
|
352
|
+
+
|
353
|
+
+static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
|
354
|
+
+ int count, int *total)
|
355
|
+
+{
|
356
|
+
+ *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
|
357
|
+
+ if (*total < 0) {
|
358
|
+
+ return *total;
|
359
|
+
+ }
|
360
|
+
+ return 1;
|
361
|
+
+}
|
362
|
+
+
|
363
|
+
+#define NOT_DONE 0x7fffffff
|
364
|
+
+static void aio_rw_done(void *opaque, int ret)
|
365
|
+
+{
|
366
|
+
+ *(int *)opaque = ret;
|
367
|
+
+}
|
368
|
+
+
|
369
|
+
+static int do_aio_readv(BlockDriverState *bs, QEMUIOVector *qiov,
|
370
|
+
+ int64_t offset, int *total)
|
371
|
+
+{
|
372
|
+
+ int async_ret = NOT_DONE;
|
373
|
+
+
|
374
|
+
+ bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
|
375
|
+
+ aio_rw_done, &async_ret);
|
376
|
+
+ while (async_ret == NOT_DONE) {
|
377
|
+
+ main_loop_wait(false);
|
378
|
+
+ }
|
379
|
+
+
|
380
|
+
+ *total = qiov->size;
|
381
|
+
+ return async_ret < 0 ? async_ret : 1;
|
382
|
+
+}
|
383
|
+
+
|
384
|
+
+static int do_aio_writev(BlockDriverState *bs, QEMUIOVector *qiov,
|
385
|
+
+ int64_t offset, int *total)
|
386
|
+
+{
|
387
|
+
+ int async_ret = NOT_DONE;
|
388
|
+
+
|
389
|
+
+ bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
|
390
|
+
+ aio_rw_done, &async_ret);
|
391
|
+
+ while (async_ret == NOT_DONE) {
|
392
|
+
+ main_loop_wait(false);
|
393
|
+
+ }
|
394
|
+
+
|
395
|
+
+ *total = qiov->size;
|
396
|
+
+ return async_ret < 0 ? async_ret : 1;
|
397
|
+
+}
|
398
|
+
+
|
399
|
+
+struct multiwrite_async_ret {
|
400
|
+
+ int num_done;
|
401
|
+
+ int error;
|
402
|
+
+};
|
403
|
+
+
|
404
|
+
+static void multiwrite_cb(void *opaque, int ret)
|
405
|
+
+{
|
406
|
+
+ struct multiwrite_async_ret *async_ret = opaque;
|
407
|
+
+
|
408
|
+
+ async_ret->num_done++;
|
409
|
+
+ if (ret < 0) {
|
410
|
+
+ async_ret->error = ret;
|
411
|
+
+ }
|
412
|
+
+}
|
413
|
+
+
|
414
|
+
+static int do_aio_multiwrite(BlockDriverState *bs, BlockRequest* reqs,
|
415
|
+
+ int num_reqs, int *total)
|
416
|
+
+{
|
417
|
+
+ int i, ret;
|
418
|
+
+ struct multiwrite_async_ret async_ret = {
|
419
|
+
+ .num_done = 0,
|
420
|
+
+ .error = 0,
|
421
|
+
+ };
|
422
|
+
+
|
423
|
+
+ *total = 0;
|
424
|
+
+ for (i = 0; i < num_reqs; i++) {
|
425
|
+
+ reqs[i].cb = multiwrite_cb;
|
426
|
+
+ reqs[i].opaque = &async_ret;
|
427
|
+
+ *total += reqs[i].qiov->size;
|
428
|
+
+ }
|
429
|
+
+
|
430
|
+
+ ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
|
431
|
+
+ if (ret < 0) {
|
432
|
+
+ return ret;
|
433
|
+
+ }
|
434
|
+
+
|
435
|
+
+ while (async_ret.num_done < num_reqs) {
|
436
|
+
+ main_loop_wait(false);
|
437
|
+
+ }
|
438
|
+
+
|
439
|
+
+ return async_ret.error < 0 ? async_ret.error : 1;
|
440
|
+
+}
|
441
|
+
+
|
442
|
+
+static void read_help(void)
|
443
|
+
+{
|
444
|
+
+ printf(
|
445
|
+
+"\n"
|
446
|
+
+" reads a range of bytes from the given offset\n"
|
447
|
+
+"\n"
|
448
|
+
+" Example:\n"
|
449
|
+
+" 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
|
450
|
+
+"\n"
|
451
|
+
+" Reads a segment of the currently open file, optionally dumping it to the\n"
|
452
|
+
+" standard output stream (with -v option) for subsequent inspection.\n"
|
453
|
+
+" -b, -- read from the VM state rather than the virtual disk\n"
|
454
|
+
+" -C, -- report statistics in a machine parsable format\n"
|
455
|
+
+" -l, -- length for pattern verification (only with -P)\n"
|
456
|
+
+" -p, -- use bdrv_pread to read the file\n"
|
457
|
+
+" -P, -- use a pattern to verify read data\n"
|
458
|
+
+" -q, -- quiet mode, do not show I/O statistics\n"
|
459
|
+
+" -s, -- start offset for pattern verification (only with -P)\n"
|
460
|
+
+" -v, -- dump buffer to standard output\n"
|
461
|
+
+"\n");
|
462
|
+
+}
|
463
|
+
+
|
464
|
+
+static int read_f(BlockDriverState *bs, int argc, char **argv);
|
465
|
+
+
|
466
|
+
+static const cmdinfo_t read_cmd = {
|
467
|
+
+ .name = "read",
|
468
|
+
+ .altname = "r",
|
469
|
+
+ .cfunc = read_f,
|
470
|
+
+ .argmin = 2,
|
471
|
+
+ .argmax = -1,
|
472
|
+
+ .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
|
473
|
+
+ .oneline = "reads a number of bytes at a specified offset",
|
474
|
+
+ .help = read_help,
|
475
|
+
+};
|
476
|
+
+
|
477
|
+
+static int read_f(BlockDriverState *bs, int argc, char **argv)
|
478
|
+
+{
|
479
|
+
+ struct timeval t1, t2;
|
480
|
+
+ int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
|
481
|
+
+ int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
|
482
|
+
+ int c, cnt;
|
483
|
+
+ char *buf;
|
484
|
+
+ int64_t offset;
|
485
|
+
+ int count;
|
486
|
+
+ /* Some compilers get confused and warn if this is not initialized. */
|
487
|
+
+ int total = 0;
|
488
|
+
+ int pattern = 0, pattern_offset = 0, pattern_count = 0;
|
489
|
+
+
|
490
|
+
+ while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
|
491
|
+
+ switch (c) {
|
492
|
+
+ case 'b':
|
493
|
+
+ bflag = 1;
|
494
|
+
+ break;
|
495
|
+
+ case 'C':
|
496
|
+
+ Cflag = 1;
|
497
|
+
+ break;
|
498
|
+
+ case 'l':
|
499
|
+
+ lflag = 1;
|
500
|
+
+ pattern_count = cvtnum(optarg);
|
501
|
+
+ if (pattern_count < 0) {
|
502
|
+
+ printf("non-numeric length argument -- %s\n", optarg);
|
503
|
+
+ return 0;
|
504
|
+
+ }
|
505
|
+
+ break;
|
506
|
+
+ case 'p':
|
507
|
+
+ pflag = 1;
|
508
|
+
+ break;
|
509
|
+
+ case 'P':
|
510
|
+
+ Pflag = 1;
|
511
|
+
+ pattern = parse_pattern(optarg);
|
512
|
+
+ if (pattern < 0) {
|
513
|
+
+ return 0;
|
514
|
+
+ }
|
515
|
+
+ break;
|
516
|
+
+ case 'q':
|
517
|
+
+ qflag = 1;
|
518
|
+
+ break;
|
519
|
+
+ case 's':
|
520
|
+
+ sflag = 1;
|
521
|
+
+ pattern_offset = cvtnum(optarg);
|
522
|
+
+ if (pattern_offset < 0) {
|
523
|
+
+ printf("non-numeric length argument -- %s\n", optarg);
|
524
|
+
+ return 0;
|
525
|
+
+ }
|
526
|
+
+ break;
|
527
|
+
+ case 'v':
|
528
|
+
+ vflag = 1;
|
529
|
+
+ break;
|
530
|
+
+ default:
|
531
|
+
+ return command_usage(&read_cmd);
|
532
|
+
+ }
|
533
|
+
+ }
|
534
|
+
+
|
535
|
+
+ if (optind != argc - 2) {
|
536
|
+
+ return command_usage(&read_cmd);
|
537
|
+
+ }
|
538
|
+
+
|
539
|
+
+ if (bflag && pflag) {
|
540
|
+
+ printf("-b and -p cannot be specified at the same time\n");
|
541
|
+
+ return 0;
|
542
|
+
+ }
|
543
|
+
+
|
544
|
+
+ offset = cvtnum(argv[optind]);
|
545
|
+
+ if (offset < 0) {
|
546
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
547
|
+
+ return 0;
|
548
|
+
+ }
|
549
|
+
+
|
550
|
+
+ optind++;
|
551
|
+
+ count = cvtnum(argv[optind]);
|
552
|
+
+ if (count < 0) {
|
553
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
554
|
+
+ return 0;
|
555
|
+
+ }
|
556
|
+
+
|
557
|
+
+ if (!Pflag && (lflag || sflag)) {
|
558
|
+
+ return command_usage(&read_cmd);
|
559
|
+
+ }
|
560
|
+
+
|
561
|
+
+ if (!lflag) {
|
562
|
+
+ pattern_count = count - pattern_offset;
|
563
|
+
+ }
|
564
|
+
+
|
565
|
+
+ if ((pattern_count < 0) || (pattern_count + pattern_offset > count)) {
|
566
|
+
+ printf("pattern verification range exceeds end of read data\n");
|
567
|
+
+ return 0;
|
568
|
+
+ }
|
569
|
+
+
|
570
|
+
+ if (!pflag) {
|
571
|
+
+ if (offset & 0x1ff) {
|
572
|
+
+ printf("offset %" PRId64 " is not sector aligned\n",
|
573
|
+
+ offset);
|
574
|
+
+ return 0;
|
575
|
+
+ }
|
576
|
+
+ if (count & 0x1ff) {
|
577
|
+
+ printf("count %d is not sector aligned\n",
|
578
|
+
+ count);
|
579
|
+
+ return 0;
|
580
|
+
+ }
|
581
|
+
+ }
|
582
|
+
+
|
583
|
+
+ buf = qemu_io_alloc(bs, count, 0xab);
|
584
|
+
+
|
585
|
+
+ gettimeofday(&t1, NULL);
|
586
|
+
+ if (pflag) {
|
587
|
+
+ cnt = do_pread(bs, buf, offset, count, &total);
|
588
|
+
+ } else if (bflag) {
|
589
|
+
+ cnt = do_load_vmstate(bs, buf, offset, count, &total);
|
590
|
+
+ } else {
|
591
|
+
+ cnt = do_read(bs, buf, offset, count, &total);
|
592
|
+
+ }
|
593
|
+
+ gettimeofday(&t2, NULL);
|
594
|
+
+
|
595
|
+
+ if (cnt < 0) {
|
596
|
+
+ printf("read failed: %s\n", strerror(-cnt));
|
597
|
+
+ goto out;
|
598
|
+
+ }
|
599
|
+
+
|
600
|
+
+ if (Pflag) {
|
601
|
+
+ void *cmp_buf = g_malloc(pattern_count);
|
602
|
+
+ memset(cmp_buf, pattern, pattern_count);
|
603
|
+
+ if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
|
604
|
+
+ printf("Pattern verification failed at offset %"
|
605
|
+
+ PRId64 ", %d bytes\n",
|
606
|
+
+ offset + pattern_offset, pattern_count);
|
607
|
+
+ }
|
608
|
+
+ g_free(cmp_buf);
|
609
|
+
+ }
|
610
|
+
+
|
611
|
+
+ if (qflag) {
|
612
|
+
+ goto out;
|
613
|
+
+ }
|
614
|
+
+
|
615
|
+
+ if (vflag) {
|
616
|
+
+ dump_buffer(buf, offset, count);
|
617
|
+
+ }
|
618
|
+
+
|
619
|
+
+ /* Finally, report back -- -C gives a parsable format */
|
620
|
+
+ t2 = tsub(t2, t1);
|
621
|
+
+ print_report("read", &t2, offset, count, total, cnt, Cflag);
|
622
|
+
+
|
623
|
+
+out:
|
624
|
+
+ qemu_io_free(buf);
|
625
|
+
+
|
626
|
+
+ return 0;
|
627
|
+
+}
|
628
|
+
+
|
629
|
+
+static void readv_help(void)
|
630
|
+
+{
|
631
|
+
+ printf(
|
632
|
+
+"\n"
|
633
|
+
+" reads a range of bytes from the given offset into multiple buffers\n"
|
634
|
+
+"\n"
|
635
|
+
+" Example:\n"
|
636
|
+
+" 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
|
637
|
+
+"\n"
|
638
|
+
+" Reads a segment of the currently open file, optionally dumping it to the\n"
|
639
|
+
+" standard output stream (with -v option) for subsequent inspection.\n"
|
640
|
+
+" Uses multiple iovec buffers if more than one byte range is specified.\n"
|
641
|
+
+" -C, -- report statistics in a machine parsable format\n"
|
642
|
+
+" -P, -- use a pattern to verify read data\n"
|
643
|
+
+" -v, -- dump buffer to standard output\n"
|
644
|
+
+" -q, -- quiet mode, do not show I/O statistics\n"
|
645
|
+
+"\n");
|
646
|
+
+}
|
647
|
+
+
|
648
|
+
+static int readv_f(BlockDriverState *bs, int argc, char **argv);
|
649
|
+
+
|
650
|
+
+static const cmdinfo_t readv_cmd = {
|
651
|
+
+ .name = "readv",
|
652
|
+
+ .cfunc = readv_f,
|
653
|
+
+ .argmin = 2,
|
654
|
+
+ .argmax = -1,
|
655
|
+
+ .args = "[-Cqv] [-P pattern ] off len [len..]",
|
656
|
+
+ .oneline = "reads a number of bytes at a specified offset",
|
657
|
+
+ .help = readv_help,
|
658
|
+
+};
|
659
|
+
+
|
660
|
+
+static int readv_f(BlockDriverState *bs, int argc, char **argv)
|
661
|
+
+{
|
662
|
+
+ struct timeval t1, t2;
|
663
|
+
+ int Cflag = 0, qflag = 0, vflag = 0;
|
664
|
+
+ int c, cnt;
|
665
|
+
+ char *buf;
|
666
|
+
+ int64_t offset;
|
667
|
+
+ /* Some compilers get confused and warn if this is not initialized. */
|
668
|
+
+ int total = 0;
|
669
|
+
+ int nr_iov;
|
670
|
+
+ QEMUIOVector qiov;
|
671
|
+
+ int pattern = 0;
|
672
|
+
+ int Pflag = 0;
|
673
|
+
+
|
674
|
+
+ while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
|
675
|
+
+ switch (c) {
|
676
|
+
+ case 'C':
|
677
|
+
+ Cflag = 1;
|
678
|
+
+ break;
|
679
|
+
+ case 'P':
|
680
|
+
+ Pflag = 1;
|
681
|
+
+ pattern = parse_pattern(optarg);
|
682
|
+
+ if (pattern < 0) {
|
683
|
+
+ return 0;
|
684
|
+
+ }
|
685
|
+
+ break;
|
686
|
+
+ case 'q':
|
687
|
+
+ qflag = 1;
|
688
|
+
+ break;
|
689
|
+
+ case 'v':
|
690
|
+
+ vflag = 1;
|
691
|
+
+ break;
|
692
|
+
+ default:
|
693
|
+
+ return command_usage(&readv_cmd);
|
694
|
+
+ }
|
695
|
+
+ }
|
696
|
+
+
|
697
|
+
+ if (optind > argc - 2) {
|
698
|
+
+ return command_usage(&readv_cmd);
|
699
|
+
+ }
|
700
|
+
+
|
701
|
+
+
|
702
|
+
+ offset = cvtnum(argv[optind]);
|
703
|
+
+ if (offset < 0) {
|
704
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
705
|
+
+ return 0;
|
706
|
+
+ }
|
707
|
+
+ optind++;
|
708
|
+
+
|
709
|
+
+ if (offset & 0x1ff) {
|
710
|
+
+ printf("offset %" PRId64 " is not sector aligned\n",
|
711
|
+
+ offset);
|
712
|
+
+ return 0;
|
713
|
+
+ }
|
714
|
+
+
|
715
|
+
+ nr_iov = argc - optind;
|
716
|
+
+ buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, 0xab);
|
717
|
+
+ if (buf == NULL) {
|
718
|
+
+ return 0;
|
719
|
+
+ }
|
720
|
+
+
|
721
|
+
+ gettimeofday(&t1, NULL);
|
722
|
+
+ cnt = do_aio_readv(bs, &qiov, offset, &total);
|
723
|
+
+ gettimeofday(&t2, NULL);
|
724
|
+
+
|
725
|
+
+ if (cnt < 0) {
|
726
|
+
+ printf("readv failed: %s\n", strerror(-cnt));
|
727
|
+
+ goto out;
|
728
|
+
+ }
|
729
|
+
+
|
730
|
+
+ if (Pflag) {
|
731
|
+
+ void *cmp_buf = g_malloc(qiov.size);
|
732
|
+
+ memset(cmp_buf, pattern, qiov.size);
|
733
|
+
+ if (memcmp(buf, cmp_buf, qiov.size)) {
|
734
|
+
+ printf("Pattern verification failed at offset %"
|
735
|
+
+ PRId64 ", %zd bytes\n", offset, qiov.size);
|
736
|
+
+ }
|
737
|
+
+ g_free(cmp_buf);
|
738
|
+
+ }
|
739
|
+
+
|
740
|
+
+ if (qflag) {
|
741
|
+
+ goto out;
|
742
|
+
+ }
|
743
|
+
+
|
744
|
+
+ if (vflag) {
|
745
|
+
+ dump_buffer(buf, offset, qiov.size);
|
746
|
+
+ }
|
747
|
+
+
|
748
|
+
+ /* Finally, report back -- -C gives a parsable format */
|
749
|
+
+ t2 = tsub(t2, t1);
|
750
|
+
+ print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
|
751
|
+
+
|
752
|
+
+out:
|
753
|
+
+ qemu_iovec_destroy(&qiov);
|
754
|
+
+ qemu_io_free(buf);
|
755
|
+
+ return 0;
|
756
|
+
+}
|
757
|
+
+
|
758
|
+
+static void write_help(void)
|
759
|
+
+{
|
760
|
+
+ printf(
|
761
|
+
+"\n"
|
762
|
+
+" writes a range of bytes from the given offset\n"
|
763
|
+
+"\n"
|
764
|
+
+" Example:\n"
|
765
|
+
+" 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
|
766
|
+
+"\n"
|
767
|
+
+" Writes into a segment of the currently open file, using a buffer\n"
|
768
|
+
+" filled with a set pattern (0xcdcdcdcd).\n"
|
769
|
+
+" -b, -- write to the VM state rather than the virtual disk\n"
|
770
|
+
+" -c, -- write compressed data with bdrv_write_compressed\n"
|
771
|
+
+" -p, -- use bdrv_pwrite to write the file\n"
|
772
|
+
+" -P, -- use different pattern to fill file\n"
|
773
|
+
+" -C, -- report statistics in a machine parsable format\n"
|
774
|
+
+" -q, -- quiet mode, do not show I/O statistics\n"
|
775
|
+
+" -z, -- write zeroes using bdrv_co_write_zeroes\n"
|
776
|
+
+"\n");
|
777
|
+
+}
|
778
|
+
+
|
779
|
+
+static int write_f(BlockDriverState *bs, int argc, char **argv);
|
780
|
+
+
|
781
|
+
+static const cmdinfo_t write_cmd = {
|
782
|
+
+ .name = "write",
|
783
|
+
+ .altname = "w",
|
784
|
+
+ .cfunc = write_f,
|
785
|
+
+ .argmin = 2,
|
786
|
+
+ .argmax = -1,
|
787
|
+
+ .args = "[-bcCpqz] [-P pattern ] off len",
|
788
|
+
+ .oneline = "writes a number of bytes at a specified offset",
|
789
|
+
+ .help = write_help,
|
790
|
+
+};
|
791
|
+
+
|
792
|
+
+static int write_f(BlockDriverState *bs, int argc, char **argv)
|
793
|
+
+{
|
794
|
+
+ struct timeval t1, t2;
|
795
|
+
+ int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
|
796
|
+
+ int cflag = 0;
|
797
|
+
+ int c, cnt;
|
798
|
+
+ char *buf = NULL;
|
799
|
+
+ int64_t offset;
|
800
|
+
+ int count;
|
801
|
+
+ /* Some compilers get confused and warn if this is not initialized. */
|
802
|
+
+ int total = 0;
|
803
|
+
+ int pattern = 0xcd;
|
804
|
+
+
|
805
|
+
+ while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) {
|
806
|
+
+ switch (c) {
|
807
|
+
+ case 'b':
|
808
|
+
+ bflag = 1;
|
809
|
+
+ break;
|
810
|
+
+ case 'c':
|
811
|
+
+ cflag = 1;
|
812
|
+
+ break;
|
813
|
+
+ case 'C':
|
814
|
+
+ Cflag = 1;
|
815
|
+
+ break;
|
816
|
+
+ case 'p':
|
817
|
+
+ pflag = 1;
|
818
|
+
+ break;
|
819
|
+
+ case 'P':
|
820
|
+
+ Pflag = 1;
|
821
|
+
+ pattern = parse_pattern(optarg);
|
822
|
+
+ if (pattern < 0) {
|
823
|
+
+ return 0;
|
824
|
+
+ }
|
825
|
+
+ break;
|
826
|
+
+ case 'q':
|
827
|
+
+ qflag = 1;
|
828
|
+
+ break;
|
829
|
+
+ case 'z':
|
830
|
+
+ zflag = 1;
|
831
|
+
+ break;
|
832
|
+
+ default:
|
833
|
+
+ return command_usage(&write_cmd);
|
834
|
+
+ }
|
835
|
+
+ }
|
836
|
+
+
|
837
|
+
+ if (optind != argc - 2) {
|
838
|
+
+ return command_usage(&write_cmd);
|
839
|
+
+ }
|
840
|
+
+
|
841
|
+
+ if (bflag + pflag + zflag > 1) {
|
842
|
+
+ printf("-b, -p, or -z cannot be specified at the same time\n");
|
843
|
+
+ return 0;
|
844
|
+
+ }
|
845
|
+
+
|
846
|
+
+ if (zflag && Pflag) {
|
847
|
+
+ printf("-z and -P cannot be specified at the same time\n");
|
848
|
+
+ return 0;
|
849
|
+
+ }
|
850
|
+
+
|
851
|
+
+ offset = cvtnum(argv[optind]);
|
852
|
+
+ if (offset < 0) {
|
853
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
854
|
+
+ return 0;
|
855
|
+
+ }
|
856
|
+
+
|
857
|
+
+ optind++;
|
858
|
+
+ count = cvtnum(argv[optind]);
|
859
|
+
+ if (count < 0) {
|
860
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
861
|
+
+ return 0;
|
862
|
+
+ }
|
863
|
+
+
|
864
|
+
+ if (!pflag) {
|
865
|
+
+ if (offset & 0x1ff) {
|
866
|
+
+ printf("offset %" PRId64 " is not sector aligned\n",
|
867
|
+
+ offset);
|
868
|
+
+ return 0;
|
869
|
+
+ }
|
870
|
+
+
|
871
|
+
+ if (count & 0x1ff) {
|
872
|
+
+ printf("count %d is not sector aligned\n",
|
873
|
+
+ count);
|
874
|
+
+ return 0;
|
875
|
+
+ }
|
876
|
+
+ }
|
877
|
+
+
|
878
|
+
+ if (!zflag) {
|
879
|
+
+ buf = qemu_io_alloc(bs, count, pattern);
|
880
|
+
+ }
|
881
|
+
+
|
882
|
+
+ gettimeofday(&t1, NULL);
|
883
|
+
+ if (pflag) {
|
884
|
+
+ cnt = do_pwrite(bs, buf, offset, count, &total);
|
885
|
+
+ } else if (bflag) {
|
886
|
+
+ cnt = do_save_vmstate(bs, buf, offset, count, &total);
|
887
|
+
+ } else if (zflag) {
|
888
|
+
+ cnt = do_co_write_zeroes(bs, offset, count, &total);
|
889
|
+
+ } else if (cflag) {
|
890
|
+
+ cnt = do_write_compressed(bs, buf, offset, count, &total);
|
891
|
+
+ } else {
|
892
|
+
+ cnt = do_write(bs, buf, offset, count, &total);
|
893
|
+
+ }
|
894
|
+
+ gettimeofday(&t2, NULL);
|
895
|
+
+
|
896
|
+
+ if (cnt < 0) {
|
897
|
+
+ printf("write failed: %s\n", strerror(-cnt));
|
898
|
+
+ goto out;
|
899
|
+
+ }
|
900
|
+
+
|
901
|
+
+ if (qflag) {
|
902
|
+
+ goto out;
|
903
|
+
+ }
|
904
|
+
+
|
905
|
+
+ /* Finally, report back -- -C gives a parsable format */
|
906
|
+
+ t2 = tsub(t2, t1);
|
907
|
+
+ print_report("wrote", &t2, offset, count, total, cnt, Cflag);
|
908
|
+
+
|
909
|
+
+out:
|
910
|
+
+ if (!zflag) {
|
911
|
+
+ qemu_io_free(buf);
|
912
|
+
+ }
|
913
|
+
+
|
914
|
+
+ return 0;
|
915
|
+
+}
|
916
|
+
+
|
917
|
+
+static void
|
918
|
+
+writev_help(void)
|
919
|
+
+{
|
920
|
+
+ printf(
|
921
|
+
+"\n"
|
922
|
+
+" writes a range of bytes from the given offset source from multiple buffers\n"
|
923
|
+
+"\n"
|
924
|
+
+" Example:\n"
|
925
|
+
+" 'write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
|
926
|
+
+"\n"
|
927
|
+
+" Writes into a segment of the currently open file, using a buffer\n"
|
928
|
+
+" filled with a set pattern (0xcdcdcdcd).\n"
|
929
|
+
+" -P, -- use different pattern to fill file\n"
|
930
|
+
+" -C, -- report statistics in a machine parsable format\n"
|
931
|
+
+" -q, -- quiet mode, do not show I/O statistics\n"
|
932
|
+
+"\n");
|
933
|
+
+}
|
934
|
+
+
|
935
|
+
+static int writev_f(BlockDriverState *bs, int argc, char **argv);
|
936
|
+
+
|
937
|
+
+static const cmdinfo_t writev_cmd = {
|
938
|
+
+ .name = "writev",
|
939
|
+
+ .cfunc = writev_f,
|
940
|
+
+ .argmin = 2,
|
941
|
+
+ .argmax = -1,
|
942
|
+
+ .args = "[-Cq] [-P pattern ] off len [len..]",
|
943
|
+
+ .oneline = "writes a number of bytes at a specified offset",
|
944
|
+
+ .help = writev_help,
|
945
|
+
+};
|
946
|
+
+
|
947
|
+
+static int writev_f(BlockDriverState *bs, int argc, char **argv)
|
948
|
+
+{
|
949
|
+
+ struct timeval t1, t2;
|
950
|
+
+ int Cflag = 0, qflag = 0;
|
951
|
+
+ int c, cnt;
|
952
|
+
+ char *buf;
|
953
|
+
+ int64_t offset;
|
954
|
+
+ /* Some compilers get confused and warn if this is not initialized. */
|
955
|
+
+ int total = 0;
|
956
|
+
+ int nr_iov;
|
957
|
+
+ int pattern = 0xcd;
|
958
|
+
+ QEMUIOVector qiov;
|
959
|
+
+
|
960
|
+
+ while ((c = getopt(argc, argv, "CqP:")) != EOF) {
|
961
|
+
+ switch (c) {
|
962
|
+
+ case 'C':
|
963
|
+
+ Cflag = 1;
|
964
|
+
+ break;
|
965
|
+
+ case 'q':
|
966
|
+
+ qflag = 1;
|
967
|
+
+ break;
|
968
|
+
+ case 'P':
|
969
|
+
+ pattern = parse_pattern(optarg);
|
970
|
+
+ if (pattern < 0) {
|
971
|
+
+ return 0;
|
972
|
+
+ }
|
973
|
+
+ break;
|
974
|
+
+ default:
|
975
|
+
+ return command_usage(&writev_cmd);
|
976
|
+
+ }
|
977
|
+
+ }
|
978
|
+
+
|
979
|
+
+ if (optind > argc - 2) {
|
980
|
+
+ return command_usage(&writev_cmd);
|
981
|
+
+ }
|
982
|
+
+
|
983
|
+
+ offset = cvtnum(argv[optind]);
|
984
|
+
+ if (offset < 0) {
|
985
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
986
|
+
+ return 0;
|
987
|
+
+ }
|
988
|
+
+ optind++;
|
989
|
+
+
|
990
|
+
+ if (offset & 0x1ff) {
|
991
|
+
+ printf("offset %" PRId64 " is not sector aligned\n",
|
992
|
+
+ offset);
|
993
|
+
+ return 0;
|
994
|
+
+ }
|
995
|
+
+
|
996
|
+
+ nr_iov = argc - optind;
|
997
|
+
+ buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, pattern);
|
998
|
+
+ if (buf == NULL) {
|
999
|
+
+ return 0;
|
1000
|
+
+ }
|
1001
|
+
+
|
1002
|
+
+ gettimeofday(&t1, NULL);
|
1003
|
+
+ cnt = do_aio_writev(bs, &qiov, offset, &total);
|
1004
|
+
+ gettimeofday(&t2, NULL);
|
1005
|
+
+
|
1006
|
+
+ if (cnt < 0) {
|
1007
|
+
+ printf("writev failed: %s\n", strerror(-cnt));
|
1008
|
+
+ goto out;
|
1009
|
+
+ }
|
1010
|
+
+
|
1011
|
+
+ if (qflag) {
|
1012
|
+
+ goto out;
|
1013
|
+
+ }
|
1014
|
+
+
|
1015
|
+
+ /* Finally, report back -- -C gives a parsable format */
|
1016
|
+
+ t2 = tsub(t2, t1);
|
1017
|
+
+ print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
|
1018
|
+
+out:
|
1019
|
+
+ qemu_iovec_destroy(&qiov);
|
1020
|
+
+ qemu_io_free(buf);
|
1021
|
+
+ return 0;
|
1022
|
+
+}
|
1023
|
+
+
|
1024
|
+
+static void multiwrite_help(void)
|
1025
|
+
+{
|
1026
|
+
+ printf(
|
1027
|
+
+"\n"
|
1028
|
+
+" writes a range of bytes from the given offset source from multiple buffers,\n"
|
1029
|
+
+" in a batch of requests that may be merged by qemu\n"
|
1030
|
+
+"\n"
|
1031
|
+
+" Example:\n"
|
1032
|
+
+" 'multiwrite 512 1k 1k ; 4k 1k'\n"
|
1033
|
+
+" writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
|
1034
|
+
+"\n"
|
1035
|
+
+" Writes into a segment of the currently open file, using a buffer\n"
|
1036
|
+
+" filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
|
1037
|
+
+" by one for each request contained in the multiwrite command.\n"
|
1038
|
+
+" -P, -- use different pattern to fill file\n"
|
1039
|
+
+" -C, -- report statistics in a machine parsable format\n"
|
1040
|
+
+" -q, -- quiet mode, do not show I/O statistics\n"
|
1041
|
+
+"\n");
|
1042
|
+
+}
|
1043
|
+
+
|
1044
|
+
+static int multiwrite_f(BlockDriverState *bs, int argc, char **argv);
|
1045
|
+
+
|
1046
|
+
+static const cmdinfo_t multiwrite_cmd = {
|
1047
|
+
+ .name = "multiwrite",
|
1048
|
+
+ .cfunc = multiwrite_f,
|
1049
|
+
+ .argmin = 2,
|
1050
|
+
+ .argmax = -1,
|
1051
|
+
+ .args = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
|
1052
|
+
+ .oneline = "issues multiple write requests at once",
|
1053
|
+
+ .help = multiwrite_help,
|
1054
|
+
+};
|
1055
|
+
+
|
1056
|
+
+static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
|
1057
|
+
+{
|
1058
|
+
+ struct timeval t1, t2;
|
1059
|
+
+ int Cflag = 0, qflag = 0;
|
1060
|
+
+ int c, cnt;
|
1061
|
+
+ char **buf;
|
1062
|
+
+ int64_t offset, first_offset = 0;
|
1063
|
+
+ /* Some compilers get confused and warn if this is not initialized. */
|
1064
|
+
+ int total = 0;
|
1065
|
+
+ int nr_iov;
|
1066
|
+
+ int nr_reqs;
|
1067
|
+
+ int pattern = 0xcd;
|
1068
|
+
+ QEMUIOVector *qiovs;
|
1069
|
+
+ int i;
|
1070
|
+
+ BlockRequest *reqs;
|
1071
|
+
+
|
1072
|
+
+ while ((c = getopt(argc, argv, "CqP:")) != EOF) {
|
1073
|
+
+ switch (c) {
|
1074
|
+
+ case 'C':
|
1075
|
+
+ Cflag = 1;
|
1076
|
+
+ break;
|
1077
|
+
+ case 'q':
|
1078
|
+
+ qflag = 1;
|
1079
|
+
+ break;
|
1080
|
+
+ case 'P':
|
1081
|
+
+ pattern = parse_pattern(optarg);
|
1082
|
+
+ if (pattern < 0) {
|
1083
|
+
+ return 0;
|
1084
|
+
+ }
|
1085
|
+
+ break;
|
1086
|
+
+ default:
|
1087
|
+
+ return command_usage(&writev_cmd);
|
1088
|
+
+ }
|
1089
|
+
+ }
|
1090
|
+
+
|
1091
|
+
+ if (optind > argc - 2) {
|
1092
|
+
+ return command_usage(&writev_cmd);
|
1093
|
+
+ }
|
1094
|
+
+
|
1095
|
+
+ nr_reqs = 1;
|
1096
|
+
+ for (i = optind; i < argc; i++) {
|
1097
|
+
+ if (!strcmp(argv[i], ";")) {
|
1098
|
+
+ nr_reqs++;
|
1099
|
+
+ }
|
1100
|
+
+ }
|
1101
|
+
+
|
1102
|
+
+ reqs = g_malloc0(nr_reqs * sizeof(*reqs));
|
1103
|
+
+ buf = g_malloc0(nr_reqs * sizeof(*buf));
|
1104
|
+
+ qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
|
1105
|
+
+
|
1106
|
+
+ for (i = 0; i < nr_reqs && optind < argc; i++) {
|
1107
|
+
+ int j;
|
1108
|
+
+
|
1109
|
+
+ /* Read the offset of the request */
|
1110
|
+
+ offset = cvtnum(argv[optind]);
|
1111
|
+
+ if (offset < 0) {
|
1112
|
+
+ printf("non-numeric offset argument -- %s\n", argv[optind]);
|
1113
|
+
+ goto out;
|
1114
|
+
+ }
|
1115
|
+
+ optind++;
|
1116
|
+
+
|
1117
|
+
+ if (offset & 0x1ff) {
|
1118
|
+
+ printf("offset %lld is not sector aligned\n",
|
1119
|
+
+ (long long)offset);
|
1120
|
+
+ goto out;
|
1121
|
+
+ }
|
1122
|
+
+
|
1123
|
+
+ if (i == 0) {
|
1124
|
+
+ first_offset = offset;
|
1125
|
+
+ }
|
1126
|
+
+
|
1127
|
+
+ /* Read lengths for qiov entries */
|
1128
|
+
+ for (j = optind; j < argc; j++) {
|
1129
|
+
+ if (!strcmp(argv[j], ";")) {
|
1130
|
+
+ break;
|
1131
|
+
+ }
|
1132
|
+
+ }
|
1133
|
+
+
|
1134
|
+
+ nr_iov = j - optind;
|
1135
|
+
+
|
1136
|
+
+ /* Build request */
|
1137
|
+
+ buf[i] = create_iovec(bs, &qiovs[i], &argv[optind], nr_iov, pattern);
|
1138
|
+
+ if (buf[i] == NULL) {
|
1139
|
+
+ goto out;
|
1140
|
+
+ }
|
1141
|
+
+
|
1142
|
+
+ reqs[i].qiov = &qiovs[i];
|
1143
|
+
+ reqs[i].sector = offset >> 9;
|
1144
|
+
+ reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
|
1145
|
+
+
|
1146
|
+
+ optind = j + 1;
|
1147
|
+
+
|
1148
|
+
+ pattern++;
|
1149
|
+
+ }
|
1150
|
+
+
|
1151
|
+
+ /* If there were empty requests at the end, ignore them */
|
1152
|
+
+ nr_reqs = i;
|
1153
|
+
+
|
1154
|
+
+ gettimeofday(&t1, NULL);
|
1155
|
+
+ cnt = do_aio_multiwrite(bs, reqs, nr_reqs, &total);
|
1156
|
+
+ gettimeofday(&t2, NULL);
|
1157
|
+
+
|
1158
|
+
+ if (cnt < 0) {
|
1159
|
+
+ printf("aio_multiwrite failed: %s\n", strerror(-cnt));
|
1160
|
+
+ goto out;
|
1161
|
+
+ }
|
1162
|
+
+
|
1163
|
+
+ if (qflag) {
|
1164
|
+
+ goto out;
|
1165
|
+
+ }
|
1166
|
+
+
|
1167
|
+
+ /* Finally, report back -- -C gives a parsable format */
|
1168
|
+
+ t2 = tsub(t2, t1);
|
1169
|
+
+ print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
|
1170
|
+
+out:
|
1171
|
+
+ for (i = 0; i < nr_reqs; i++) {
|
1172
|
+
+ qemu_io_free(buf[i]);
|
1173
|
+
+ if (reqs[i].qiov != NULL) {
|
1174
|
+
+ qemu_iovec_destroy(&qiovs[i]);
|
1175
|
+
+ }
|
1176
|
+
+ }
|
1177
|
+
+ g_free(buf);
|
1178
|
+
+ g_free(reqs);
|
1179
|
+
+ g_free(qiovs);
|
1180
|
+
+ return 0;
|
1181
|
+
+}
|
1182
|
+
+
|
1183
|
+
+struct aio_ctx {
|
1184
|
+
+ QEMUIOVector qiov;
|
1185
|
+
+ int64_t offset;
|
1186
|
+
+ char *buf;
|
1187
|
+
+ int qflag;
|
1188
|
+
+ int vflag;
|
1189
|
+
+ int Cflag;
|
1190
|
+
+ int Pflag;
|
1191
|
+
+ int pattern;
|
1192
|
+
+ struct timeval t1;
|
1193
|
+
+};
|
1194
|
+
+
|
1195
|
+
+static void aio_write_done(void *opaque, int ret)
|
1196
|
+
+{
|
1197
|
+
+ struct aio_ctx *ctx = opaque;
|
1198
|
+
+ struct timeval t2;
|
1199
|
+
+
|
1200
|
+
+ gettimeofday(&t2, NULL);
|
1201
|
+
+
|
1202
|
+
+
|
1203
|
+
+ if (ret < 0) {
|
1204
|
+
+ printf("aio_write failed: %s\n", strerror(-ret));
|
1205
|
+
+ goto out;
|
1206
|
+
+ }
|
1207
|
+
+
|
1208
|
+
+ if (ctx->qflag) {
|
1209
|
+
+ goto out;
|
1210
|
+
+ }
|
1211
|
+
+
|
1212
|
+
+ /* Finally, report back -- -C gives a parsable format */
|
1213
|
+
+ t2 = tsub(t2, ctx->t1);
|
1214
|
+
+ print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
|
1215
|
+
+ ctx->qiov.size, 1, ctx->Cflag);
|
1216
|
+
+out:
|
1217
|
+
+ qemu_io_free(ctx->buf);
|
1218
|
+
+ qemu_iovec_destroy(&ctx->qiov);
|
1219
|
+
+ g_free(ctx);
|
1220
|
+
+}
|
1221
|
+
+
|
1222
|
+
+static void aio_read_done(void *opaque, int ret)
|
1223
|
+
+{
|
1224
|
+
+ struct aio_ctx *ctx = opaque;
|
1225
|
+
+ struct timeval t2;
|
1226
|
+
+
|
1227
|
+
+ gettimeofday(&t2, NULL);
|
1228
|
+
+
|
1229
|
+
+ if (ret < 0) {
|
1230
|
+
+ printf("readv failed: %s\n", strerror(-ret));
|
1231
|
+
+ goto out;
|
1232
|
+
+ }
|
1233
|
+
+
|
1234
|
+
+ if (ctx->Pflag) {
|
1235
|
+
+ void *cmp_buf = g_malloc(ctx->qiov.size);
|
1236
|
+
+
|
1237
|
+
+ memset(cmp_buf, ctx->pattern, ctx->qiov.size);
|
1238
|
+
+ if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
|
1239
|
+
+ printf("Pattern verification failed at offset %"
|
1240
|
+
+ PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
|
1241
|
+
+ }
|
1242
|
+
+ g_free(cmp_buf);
|
1243
|
+
+ }
|
1244
|
+
+
|
1245
|
+
+ if (ctx->qflag) {
|
1246
|
+
+ goto out;
|
1247
|
+
+ }
|
1248
|
+
+
|
1249
|
+
+ if (ctx->vflag) {
|
1250
|
+
+ dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
|
1251
|
+
+ }
|
1252
|
+
+
|
1253
|
+
+ /* Finally, report back -- -C gives a parsable format */
|
1254
|
+
+ t2 = tsub(t2, ctx->t1);
|
1255
|
+
+ print_report("read", &t2, ctx->offset, ctx->qiov.size,
|
1256
|
+
+ ctx->qiov.size, 1, ctx->Cflag);
|
1257
|
+
+out:
|
1258
|
+
+ qemu_io_free(ctx->buf);
|
1259
|
+
+ qemu_iovec_destroy(&ctx->qiov);
|
1260
|
+
+ g_free(ctx);
|
1261
|
+
+}
|
1262
|
+
+
|
1263
|
+
+static void aio_read_help(void)
|
1264
|
+
+{
|
1265
|
+
+ printf(
|
1266
|
+
+"\n"
|
1267
|
+
+" asynchronously reads a range of bytes from the given offset\n"
|
1268
|
+
+"\n"
|
1269
|
+
+" Example:\n"
|
1270
|
+
+" 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
|
1271
|
+
+"\n"
|
1272
|
+
+" Reads a segment of the currently open file, optionally dumping it to the\n"
|
1273
|
+
+" standard output stream (with -v option) for subsequent inspection.\n"
|
1274
|
+
+" The read is performed asynchronously and the aio_flush command must be\n"
|
1275
|
+
+" used to ensure all outstanding aio requests have been completed.\n"
|
1276
|
+
+" -C, -- report statistics in a machine parsable format\n"
|
1277
|
+
+" -P, -- use a pattern to verify read data\n"
|
1278
|
+
+" -v, -- dump buffer to standard output\n"
|
1279
|
+
+" -q, -- quiet mode, do not show I/O statistics\n"
|
1280
|
+
+"\n");
|
1281
|
+
+}
|
1282
|
+
+
|
1283
|
+
+static int aio_read_f(BlockDriverState *bs, int argc, char **argv);
|
1284
|
+
+
|
1285
|
+
+static const cmdinfo_t aio_read_cmd = {
|
1286
|
+
+ .name = "aio_read",
|
1287
|
+
+ .cfunc = aio_read_f,
|
1288
|
+
+ .argmin = 2,
|
1289
|
+
+ .argmax = -1,
|
1290
|
+
+ .args = "[-Cqv] [-P pattern ] off len [len..]",
|
1291
|
+
+ .oneline = "asynchronously reads a number of bytes",
|
1292
|
+
+ .help = aio_read_help,
|
1293
|
+
+};
|
1294
|
+
+
|
1295
|
+
+static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
|
1296
|
+
+{
|
1297
|
+
+ int nr_iov, c;
|
1298
|
+
+ struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
|
1299
|
+
+
|
1300
|
+
+ while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
|
1301
|
+
+ switch (c) {
|
1302
|
+
+ case 'C':
|
1303
|
+
+ ctx->Cflag = 1;
|
1304
|
+
+ break;
|
1305
|
+
+ case 'P':
|
1306
|
+
+ ctx->Pflag = 1;
|
1307
|
+
+ ctx->pattern = parse_pattern(optarg);
|
1308
|
+
+ if (ctx->pattern < 0) {
|
1309
|
+
+ g_free(ctx);
|
1310
|
+
+ return 0;
|
1311
|
+
+ }
|
1312
|
+
+ break;
|
1313
|
+
+ case 'q':
|
1314
|
+
+ ctx->qflag = 1;
|
1315
|
+
+ break;
|
1316
|
+
+ case 'v':
|
1317
|
+
+ ctx->vflag = 1;
|
1318
|
+
+ break;
|
1319
|
+
+ default:
|
1320
|
+
+ g_free(ctx);
|
1321
|
+
+ return command_usage(&aio_read_cmd);
|
1322
|
+
+ }
|
1323
|
+
+ }
|
1324
|
+
+
|
1325
|
+
+ if (optind > argc - 2) {
|
1326
|
+
+ g_free(ctx);
|
1327
|
+
+ return command_usage(&aio_read_cmd);
|
1328
|
+
+ }
|
1329
|
+
+
|
1330
|
+
+ ctx->offset = cvtnum(argv[optind]);
|
1331
|
+
+ if (ctx->offset < 0) {
|
1332
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
1333
|
+
+ g_free(ctx);
|
1334
|
+
+ return 0;
|
1335
|
+
+ }
|
1336
|
+
+ optind++;
|
1337
|
+
+
|
1338
|
+
+ if (ctx->offset & 0x1ff) {
|
1339
|
+
+ printf("offset %" PRId64 " is not sector aligned\n",
|
1340
|
+
+ ctx->offset);
|
1341
|
+
+ g_free(ctx);
|
1342
|
+
+ return 0;
|
1343
|
+
+ }
|
1344
|
+
+
|
1345
|
+
+ nr_iov = argc - optind;
|
1346
|
+
+ ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, 0xab);
|
1347
|
+
+ if (ctx->buf == NULL) {
|
1348
|
+
+ g_free(ctx);
|
1349
|
+
+ return 0;
|
1350
|
+
+ }
|
1351
|
+
+
|
1352
|
+
+ gettimeofday(&ctx->t1, NULL);
|
1353
|
+
+ bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
|
1354
|
+
+ ctx->qiov.size >> 9, aio_read_done, ctx);
|
1355
|
+
+ return 0;
|
1356
|
+
+}
|
1357
|
+
+
|
1358
|
+
+static void aio_write_help(void)
|
1359
|
+
+{
|
1360
|
+
+ printf(
|
1361
|
+
+"\n"
|
1362
|
+
+" asynchronously writes a range of bytes from the given offset source\n"
|
1363
|
+
+" from multiple buffers\n"
|
1364
|
+
+"\n"
|
1365
|
+
+" Example:\n"
|
1366
|
+
+" 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
|
1367
|
+
+"\n"
|
1368
|
+
+" Writes into a segment of the currently open file, using a buffer\n"
|
1369
|
+
+" filled with a set pattern (0xcdcdcdcd).\n"
|
1370
|
+
+" The write is performed asynchronously and the aio_flush command must be\n"
|
1371
|
+
+" used to ensure all outstanding aio requests have been completed.\n"
|
1372
|
+
+" -P, -- use different pattern to fill file\n"
|
1373
|
+
+" -C, -- report statistics in a machine parsable format\n"
|
1374
|
+
+" -q, -- quiet mode, do not show I/O statistics\n"
|
1375
|
+
+"\n");
|
1376
|
+
+}
|
1377
|
+
+
|
1378
|
+
+static int aio_write_f(BlockDriverState *bs, int argc, char **argv);
|
1379
|
+
+
|
1380
|
+
+static const cmdinfo_t aio_write_cmd = {
|
1381
|
+
+ .name = "aio_write",
|
1382
|
+
+ .cfunc = aio_write_f,
|
1383
|
+
+ .argmin = 2,
|
1384
|
+
+ .argmax = -1,
|
1385
|
+
+ .args = "[-Cq] [-P pattern ] off len [len..]",
|
1386
|
+
+ .oneline = "asynchronously writes a number of bytes",
|
1387
|
+
+ .help = aio_write_help,
|
1388
|
+
+};
|
1389
|
+
+
|
1390
|
+
+static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
|
1391
|
+
+{
|
1392
|
+
+ int nr_iov, c;
|
1393
|
+
+ int pattern = 0xcd;
|
1394
|
+
+ struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
|
1395
|
+
+
|
1396
|
+
+ while ((c = getopt(argc, argv, "CqP:")) != EOF) {
|
1397
|
+
+ switch (c) {
|
1398
|
+
+ case 'C':
|
1399
|
+
+ ctx->Cflag = 1;
|
1400
|
+
+ break;
|
1401
|
+
+ case 'q':
|
1402
|
+
+ ctx->qflag = 1;
|
1403
|
+
+ break;
|
1404
|
+
+ case 'P':
|
1405
|
+
+ pattern = parse_pattern(optarg);
|
1406
|
+
+ if (pattern < 0) {
|
1407
|
+
+ g_free(ctx);
|
1408
|
+
+ return 0;
|
1409
|
+
+ }
|
1410
|
+
+ break;
|
1411
|
+
+ default:
|
1412
|
+
+ g_free(ctx);
|
1413
|
+
+ return command_usage(&aio_write_cmd);
|
1414
|
+
+ }
|
1415
|
+
+ }
|
1416
|
+
+
|
1417
|
+
+ if (optind > argc - 2) {
|
1418
|
+
+ g_free(ctx);
|
1419
|
+
+ return command_usage(&aio_write_cmd);
|
1420
|
+
+ }
|
1421
|
+
+
|
1422
|
+
+ ctx->offset = cvtnum(argv[optind]);
|
1423
|
+
+ if (ctx->offset < 0) {
|
1424
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
1425
|
+
+ g_free(ctx);
|
1426
|
+
+ return 0;
|
1427
|
+
+ }
|
1428
|
+
+ optind++;
|
1429
|
+
+
|
1430
|
+
+ if (ctx->offset & 0x1ff) {
|
1431
|
+
+ printf("offset %" PRId64 " is not sector aligned\n",
|
1432
|
+
+ ctx->offset);
|
1433
|
+
+ g_free(ctx);
|
1434
|
+
+ return 0;
|
1435
|
+
+ }
|
1436
|
+
+
|
1437
|
+
+ nr_iov = argc - optind;
|
1438
|
+
+ ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, pattern);
|
1439
|
+
+ if (ctx->buf == NULL) {
|
1440
|
+
+ g_free(ctx);
|
1441
|
+
+ return 0;
|
1442
|
+
+ }
|
1443
|
+
+
|
1444
|
+
+ gettimeofday(&ctx->t1, NULL);
|
1445
|
+
+ bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
|
1446
|
+
+ ctx->qiov.size >> 9, aio_write_done, ctx);
|
1447
|
+
+ return 0;
|
1448
|
+
+}
|
1449
|
+
+
|
1450
|
+
+static int aio_flush_f(BlockDriverState *bs, int argc, char **argv)
|
1451
|
+
+{
|
1452
|
+
+ bdrv_drain_all();
|
1453
|
+
+ return 0;
|
1454
|
+
+}
|
1455
|
+
+
|
1456
|
+
+static const cmdinfo_t aio_flush_cmd = {
|
1457
|
+
+ .name = "aio_flush",
|
1458
|
+
+ .cfunc = aio_flush_f,
|
1459
|
+
+ .oneline = "completes all outstanding aio requests"
|
1460
|
+
+};
|
1461
|
+
+
|
1462
|
+
+static int flush_f(BlockDriverState *bs, int argc, char **argv)
|
1463
|
+
+{
|
1464
|
+
+ bdrv_flush(bs);
|
1465
|
+
+ return 0;
|
1466
|
+
+}
|
1467
|
+
+
|
1468
|
+
+static const cmdinfo_t flush_cmd = {
|
1469
|
+
+ .name = "flush",
|
1470
|
+
+ .altname = "f",
|
1471
|
+
+ .cfunc = flush_f,
|
1472
|
+
+ .oneline = "flush all in-core file state to disk",
|
1473
|
+
+};
|
1474
|
+
+
|
1475
|
+
+static int truncate_f(BlockDriverState *bs, int argc, char **argv)
|
1476
|
+
+{
|
1477
|
+
+ int64_t offset;
|
1478
|
+
+ int ret;
|
1479
|
+
+
|
1480
|
+
+ offset = cvtnum(argv[1]);
|
1481
|
+
+ if (offset < 0) {
|
1482
|
+
+ printf("non-numeric truncate argument -- %s\n", argv[1]);
|
1483
|
+
+ return 0;
|
1484
|
+
+ }
|
1485
|
+
+
|
1486
|
+
+ ret = bdrv_truncate(bs, offset);
|
1487
|
+
+ if (ret < 0) {
|
1488
|
+
+ printf("truncate: %s\n", strerror(-ret));
|
1489
|
+
+ return 0;
|
1490
|
+
+ }
|
1491
|
+
+
|
1492
|
+
+ return 0;
|
1493
|
+
+}
|
1494
|
+
+
|
1495
|
+
+static const cmdinfo_t truncate_cmd = {
|
1496
|
+
+ .name = "truncate",
|
1497
|
+
+ .altname = "t",
|
1498
|
+
+ .cfunc = truncate_f,
|
1499
|
+
+ .argmin = 1,
|
1500
|
+
+ .argmax = 1,
|
1501
|
+
+ .args = "off",
|
1502
|
+
+ .oneline = "truncates the current file at the given offset",
|
1503
|
+
+};
|
1504
|
+
+
|
1505
|
+
+static int length_f(BlockDriverState *bs, int argc, char **argv)
|
1506
|
+
+{
|
1507
|
+
+ int64_t size;
|
1508
|
+
+ char s1[64];
|
1509
|
+
+
|
1510
|
+
+ size = bdrv_getlength(bs);
|
1511
|
+
+ if (size < 0) {
|
1512
|
+
+ printf("getlength: %s\n", strerror(-size));
|
1513
|
+
+ return 0;
|
1514
|
+
+ }
|
1515
|
+
+
|
1516
|
+
+ cvtstr(size, s1, sizeof(s1));
|
1517
|
+
+ printf("%s\n", s1);
|
1518
|
+
+ return 0;
|
1519
|
+
+}
|
1520
|
+
+
|
1521
|
+
+
|
1522
|
+
+static const cmdinfo_t length_cmd = {
|
1523
|
+
+ .name = "length",
|
1524
|
+
+ .altname = "l",
|
1525
|
+
+ .cfunc = length_f,
|
1526
|
+
+ .oneline = "gets the length of the current file",
|
1527
|
+
+};
|
1528
|
+
+
|
1529
|
+
+
|
1530
|
+
+static int info_f(BlockDriverState *bs, int argc, char **argv)
|
1531
|
+
+{
|
1532
|
+
+ BlockDriverInfo bdi;
|
1533
|
+
+ ImageInfoSpecific *spec_info;
|
1534
|
+
+ char s1[64], s2[64];
|
1535
|
+
+ int ret;
|
1536
|
+
+
|
1537
|
+
+ if (bs->drv && bs->drv->format_name) {
|
1538
|
+
+ printf("format name: %s\n", bs->drv->format_name);
|
1539
|
+
+ }
|
1540
|
+
+ if (bs->drv && bs->drv->protocol_name) {
|
1541
|
+
+ printf("format name: %s\n", bs->drv->protocol_name);
|
1542
|
+
+ }
|
1543
|
+
+
|
1544
|
+
+ ret = bdrv_get_info(bs, &bdi);
|
1545
|
+
+ if (ret) {
|
1546
|
+
+ return 0;
|
1547
|
+
+ }
|
1548
|
+
+
|
1549
|
+
+ cvtstr(bdi.cluster_size, s1, sizeof(s1));
|
1550
|
+
+ cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
|
1551
|
+
+
|
1552
|
+
+ printf("cluster size: %s\n", s1);
|
1553
|
+
+ printf("vm state offset: %s\n", s2);
|
1554
|
+
+
|
1555
|
+
+ spec_info = bdrv_get_specific_info(bs);
|
1556
|
+
+ if (spec_info) {
|
1557
|
+
+ printf("Format specific information:\n");
|
1558
|
+
+ bdrv_image_info_specific_dump(fprintf, stdout, spec_info);
|
1559
|
+
+ qapi_free_ImageInfoSpecific(spec_info);
|
1560
|
+
+ }
|
1561
|
+
+
|
1562
|
+
+ return 0;
|
1563
|
+
+}
|
1564
|
+
+
|
1565
|
+
+
|
1566
|
+
+
|
1567
|
+
+static const cmdinfo_t info_cmd = {
|
1568
|
+
+ .name = "info",
|
1569
|
+
+ .altname = "i",
|
1570
|
+
+ .cfunc = info_f,
|
1571
|
+
+ .oneline = "prints information about the current file",
|
1572
|
+
+};
|
1573
|
+
+
|
1574
|
+
+static void discard_help(void)
|
1575
|
+
+{
|
1576
|
+
+ printf(
|
1577
|
+
+"\n"
|
1578
|
+
+" discards a range of bytes from the given offset\n"
|
1579
|
+
+"\n"
|
1580
|
+
+" Example:\n"
|
1581
|
+
+" 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
|
1582
|
+
+"\n"
|
1583
|
+
+" Discards a segment of the currently open file.\n"
|
1584
|
+
+" -C, -- report statistics in a machine parsable format\n"
|
1585
|
+
+" -q, -- quiet mode, do not show I/O statistics\n"
|
1586
|
+
+"\n");
|
1587
|
+
+}
|
1588
|
+
+
|
1589
|
+
+static int discard_f(BlockDriverState *bs, int argc, char **argv);
|
1590
|
+
+
|
1591
|
+
+static const cmdinfo_t discard_cmd = {
|
1592
|
+
+ .name = "discard",
|
1593
|
+
+ .altname = "d",
|
1594
|
+
+ .cfunc = discard_f,
|
1595
|
+
+ .argmin = 2,
|
1596
|
+
+ .argmax = -1,
|
1597
|
+
+ .args = "[-Cq] off len",
|
1598
|
+
+ .oneline = "discards a number of bytes at a specified offset",
|
1599
|
+
+ .help = discard_help,
|
1600
|
+
+};
|
1601
|
+
+
|
1602
|
+
+static int discard_f(BlockDriverState *bs, int argc, char **argv)
|
1603
|
+
+{
|
1604
|
+
+ struct timeval t1, t2;
|
1605
|
+
+ int Cflag = 0, qflag = 0;
|
1606
|
+
+ int c, ret;
|
1607
|
+
+ int64_t offset;
|
1608
|
+
+ int count;
|
1609
|
+
+
|
1610
|
+
+ while ((c = getopt(argc, argv, "Cq")) != EOF) {
|
1611
|
+
+ switch (c) {
|
1612
|
+
+ case 'C':
|
1613
|
+
+ Cflag = 1;
|
1614
|
+
+ break;
|
1615
|
+
+ case 'q':
|
1616
|
+
+ qflag = 1;
|
1617
|
+
+ break;
|
1618
|
+
+ default:
|
1619
|
+
+ return command_usage(&discard_cmd);
|
1620
|
+
+ }
|
1621
|
+
+ }
|
1622
|
+
+
|
1623
|
+
+ if (optind != argc - 2) {
|
1624
|
+
+ return command_usage(&discard_cmd);
|
1625
|
+
+ }
|
1626
|
+
+
|
1627
|
+
+ offset = cvtnum(argv[optind]);
|
1628
|
+
+ if (offset < 0) {
|
1629
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
1630
|
+
+ return 0;
|
1631
|
+
+ }
|
1632
|
+
+
|
1633
|
+
+ optind++;
|
1634
|
+
+ count = cvtnum(argv[optind]);
|
1635
|
+
+ if (count < 0) {
|
1636
|
+
+ printf("non-numeric length argument -- %s\n", argv[optind]);
|
1637
|
+
+ return 0;
|
1638
|
+
+ }
|
1639
|
+
+
|
1640
|
+
+ gettimeofday(&t1, NULL);
|
1641
|
+
+ ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
|
1642
|
+
+ count >> BDRV_SECTOR_BITS);
|
1643
|
+
+ gettimeofday(&t2, NULL);
|
1644
|
+
+
|
1645
|
+
+ if (ret < 0) {
|
1646
|
+
+ printf("discard failed: %s\n", strerror(-ret));
|
1647
|
+
+ goto out;
|
1648
|
+
+ }
|
1649
|
+
+
|
1650
|
+
+ /* Finally, report back -- -C gives a parsable format */
|
1651
|
+
+ if (!qflag) {
|
1652
|
+
+ t2 = tsub(t2, t1);
|
1653
|
+
+ print_report("discard", &t2, offset, count, count, 1, Cflag);
|
1654
|
+
+ }
|
1655
|
+
+
|
1656
|
+
+out:
|
1657
|
+
+ return 0;
|
1658
|
+
+}
|
1659
|
+
+
|
1660
|
+
+static int alloc_f(BlockDriverState *bs, int argc, char **argv)
|
1661
|
+
+{
|
1662
|
+
+ int64_t offset, sector_num;
|
1663
|
+
+ int nb_sectors, remaining;
|
1664
|
+
+ char s1[64];
|
1665
|
+
+ int num, sum_alloc;
|
1666
|
+
+ int ret;
|
1667
|
+
+
|
1668
|
+
+ offset = cvtnum(argv[1]);
|
1669
|
+
+ if (offset < 0) {
|
1670
|
+
+ printf("non-numeric offset argument -- %s\n", argv[1]);
|
1671
|
+
+ return 0;
|
1672
|
+
+ } else if (offset & 0x1ff) {
|
1673
|
+
+ printf("offset %" PRId64 " is not sector aligned\n",
|
1674
|
+
+ offset);
|
1675
|
+
+ return 0;
|
1676
|
+
+ }
|
1677
|
+
+
|
1678
|
+
+ if (argc == 3) {
|
1679
|
+
+ nb_sectors = cvtnum(argv[2]);
|
1680
|
+
+ if (nb_sectors < 0) {
|
1681
|
+
+ printf("non-numeric length argument -- %s\n", argv[2]);
|
1682
|
+
+ return 0;
|
1683
|
+
+ }
|
1684
|
+
+ } else {
|
1685
|
+
+ nb_sectors = 1;
|
1686
|
+
+ }
|
1687
|
+
+
|
1688
|
+
+ remaining = nb_sectors;
|
1689
|
+
+ sum_alloc = 0;
|
1690
|
+
+ sector_num = offset >> 9;
|
1691
|
+
+ while (remaining) {
|
1692
|
+
+ ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
|
1693
|
+
+ if (ret < 0) {
|
1694
|
+
+ printf("is_allocated failed: %s\n", strerror(-ret));
|
1695
|
+
+ return 0;
|
1696
|
+
+ }
|
1697
|
+
+ sector_num += num;
|
1698
|
+
+ remaining -= num;
|
1699
|
+
+ if (ret) {
|
1700
|
+
+ sum_alloc += num;
|
1701
|
+
+ }
|
1702
|
+
+ if (num == 0) {
|
1703
|
+
+ nb_sectors -= remaining;
|
1704
|
+
+ remaining = 0;
|
1705
|
+
+ }
|
1706
|
+
+ }
|
1707
|
+
+
|
1708
|
+
+ cvtstr(offset, s1, sizeof(s1));
|
1709
|
+
+
|
1710
|
+
+ printf("%d/%d sectors allocated at offset %s\n",
|
1711
|
+
+ sum_alloc, nb_sectors, s1);
|
1712
|
+
+ return 0;
|
1713
|
+
+}
|
1714
|
+
+
|
1715
|
+
+static const cmdinfo_t alloc_cmd = {
|
1716
|
+
+ .name = "alloc",
|
1717
|
+
+ .altname = "a",
|
1718
|
+
+ .argmin = 1,
|
1719
|
+
+ .argmax = 2,
|
1720
|
+
+ .cfunc = alloc_f,
|
1721
|
+
+ .args = "off [sectors]",
|
1722
|
+
+ .oneline = "checks if a sector is present in the file",
|
1723
|
+
+};
|
1724
|
+
+
|
1725
|
+
+static int map_f(BlockDriverState *bs, int argc, char **argv)
|
1726
|
+
+{
|
1727
|
+
+ int64_t offset;
|
1728
|
+
+ int64_t nb_sectors;
|
1729
|
+
+ char s1[64];
|
1730
|
+
+ int num, num_checked;
|
1731
|
+
+ int ret;
|
1732
|
+
+ const char *retstr;
|
1733
|
+
+
|
1734
|
+
+ offset = 0;
|
1735
|
+
+ nb_sectors = bs->total_sectors;
|
1736
|
+
+
|
1737
|
+
+ do {
|
1738
|
+
+ num_checked = MIN(nb_sectors, INT_MAX);
|
1739
|
+
+ ret = bdrv_is_allocated(bs, offset, num_checked, &num);
|
1740
|
+
+ retstr = ret ? " allocated" : "not allocated";
|
1741
|
+
+ cvtstr(offset << 9ULL, s1, sizeof(s1));
|
1742
|
+
+ printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
|
1743
|
+
+ offset << 9ULL, num, num_checked, retstr, s1, ret);
|
1744
|
+
+
|
1745
|
+
+ offset += num;
|
1746
|
+
+ nb_sectors -= num;
|
1747
|
+
+ } while (offset < bs->total_sectors);
|
1748
|
+
+
|
1749
|
+
+ return 0;
|
1750
|
+
+}
|
1751
|
+
+
|
1752
|
+
+static const cmdinfo_t map_cmd = {
|
1753
|
+
+ .name = "map",
|
1754
|
+
+ .argmin = 0,
|
1755
|
+
+ .argmax = 0,
|
1756
|
+
+ .cfunc = map_f,
|
1757
|
+
+ .args = "",
|
1758
|
+
+ .oneline = "prints the allocated areas of a file",
|
1759
|
+
+};
|
1760
|
+
+
|
1761
|
+
+static int break_f(BlockDriverState *bs, int argc, char **argv)
|
1762
|
+
+{
|
1763
|
+
+ int ret;
|
1764
|
+
+
|
1765
|
+
+ ret = bdrv_debug_breakpoint(bs, argv[1], argv[2]);
|
1766
|
+
+ if (ret < 0) {
|
1767
|
+
+ printf("Could not set breakpoint: %s\n", strerror(-ret));
|
1768
|
+
+ }
|
1769
|
+
+
|
1770
|
+
+ return 0;
|
1771
|
+
+}
|
1772
|
+
+
|
1773
|
+
+static const cmdinfo_t break_cmd = {
|
1774
|
+
+ .name = "break",
|
1775
|
+
+ .argmin = 2,
|
1776
|
+
+ .argmax = 2,
|
1777
|
+
+ .cfunc = break_f,
|
1778
|
+
+ .args = "event tag",
|
1779
|
+
+ .oneline = "sets a breakpoint on event and tags the stopped "
|
1780
|
+
+ "request as tag",
|
1781
|
+
+};
|
1782
|
+
+
|
1783
|
+
+static int resume_f(BlockDriverState *bs, int argc, char **argv)
|
1784
|
+
+{
|
1785
|
+
+ int ret;
|
1786
|
+
+
|
1787
|
+
+ ret = bdrv_debug_resume(bs, argv[1]);
|
1788
|
+
+ if (ret < 0) {
|
1789
|
+
+ printf("Could not resume request: %s\n", strerror(-ret));
|
1790
|
+
+ }
|
1791
|
+
+
|
1792
|
+
+ return 0;
|
1793
|
+
+}
|
1794
|
+
+
|
1795
|
+
+static const cmdinfo_t resume_cmd = {
|
1796
|
+
+ .name = "resume",
|
1797
|
+
+ .argmin = 1,
|
1798
|
+
+ .argmax = 1,
|
1799
|
+
+ .cfunc = resume_f,
|
1800
|
+
+ .args = "tag",
|
1801
|
+
+ .oneline = "resumes the request tagged as tag",
|
1802
|
+
+};
|
1803
|
+
+
|
1804
|
+
+static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
|
1805
|
+
+{
|
1806
|
+
+ while (!bdrv_debug_is_suspended(bs, argv[1])) {
|
1807
|
+
+ qemu_aio_wait();
|
1808
|
+
+ }
|
1809
|
+
+
|
1810
|
+
+ return 0;
|
1811
|
+
+}
|
1812
|
+
+
|
1813
|
+
+static const cmdinfo_t wait_break_cmd = {
|
1814
|
+
+ .name = "wait_break",
|
1815
|
+
+ .argmin = 1,
|
1816
|
+
+ .argmax = 1,
|
1817
|
+
+ .cfunc = wait_break_f,
|
1818
|
+
+ .args = "tag",
|
1819
|
+
+ .oneline = "waits for the suspension of a request",
|
1820
|
+
+};
|
1821
|
+
+
|
1822
|
+
+static int abort_f(BlockDriverState *bs, int argc, char **argv)
|
1823
|
+
+{
|
1824
|
+
+ abort();
|
1825
|
+
+}
|
1826
|
+
+
|
1827
|
+
+static const cmdinfo_t abort_cmd = {
|
1828
|
+
+ .name = "abort",
|
1829
|
+
+ .cfunc = abort_f,
|
1830
|
+
+ .flags = CMD_NOFILE_OK,
|
1831
|
+
+ .oneline = "simulate a program crash using abort(3)",
|
1832
|
+
+};
|
1833
|
+
+
|
1834
|
+
+static void sleep_cb(void *opaque)
|
1835
|
+
+{
|
1836
|
+
+ bool *expired = opaque;
|
1837
|
+
+ *expired = true;
|
1838
|
+
+}
|
1839
|
+
+
|
1840
|
+
+static int sleep_f(BlockDriverState *bs, int argc, char **argv)
|
1841
|
+
+{
|
1842
|
+
+ char *endptr;
|
1843
|
+
+ long ms;
|
1844
|
+
+ struct QEMUTimer *timer;
|
1845
|
+
+ bool expired = false;
|
1846
|
+
+
|
1847
|
+
+ ms = strtol(argv[1], &endptr, 0);
|
1848
|
+
+ if (ms < 0 || *endptr != '\0') {
|
1849
|
+
+ printf("%s is not a valid number\n", argv[1]);
|
1850
|
+
+ return 0;
|
1851
|
+
+ }
|
1852
|
+
+
|
1853
|
+
+ timer = qemu_new_timer_ns(host_clock, sleep_cb, &expired);
|
1854
|
+
+ qemu_mod_timer(timer, qemu_get_clock_ns(host_clock) + SCALE_MS * ms);
|
1855
|
+
+
|
1856
|
+
+ while (!expired) {
|
1857
|
+
+ main_loop_wait(false);
|
1858
|
+
+ }
|
1859
|
+
+
|
1860
|
+
+ qemu_free_timer(timer);
|
1861
|
+
+
|
1862
|
+
+ return 0;
|
1863
|
+
+}
|
1864
|
+
+
|
1865
|
+
+static const cmdinfo_t sleep_cmd = {
|
1866
|
+
+ .name = "sleep",
|
1867
|
+
+ .argmin = 1,
|
1868
|
+
+ .argmax = 1,
|
1869
|
+
+ .cfunc = sleep_f,
|
1870
|
+
+ .flags = CMD_NOFILE_OK,
|
1871
|
+
+ .oneline = "waits for the given value in milliseconds",
|
1872
|
+
+};
|
1873
|
+
+
|
1874
|
+
+
|
1875
|
+
+static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
|
1876
|
+
+{
|
1877
|
+
+ if (ct->flags & CMD_FLAG_GLOBAL) {
|
1878
|
+
+ return 1;
|
1879
|
+
+ }
|
1880
|
+
+ if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
|
1881
|
+
+ fprintf(stderr, "no file open, try 'help open'\n");
|
1882
|
+
+ return 0;
|
1883
|
+
+ }
|
1884
|
+
+ return 1;
|
1885
|
+
+}
|
1886
|
+
+
|
1887
|
+
+static void __attribute((constructor)) init_qemuio_commands(void)
|
1888
|
+
+{
|
1889
|
+
+ /* initialize commands */
|
1890
|
+
+ help_init();
|
1891
|
+
+ add_command(&read_cmd);
|
1892
|
+
+ add_command(&readv_cmd);
|
1893
|
+
+ add_command(&write_cmd);
|
1894
|
+
+ add_command(&writev_cmd);
|
1895
|
+
+ add_command(&multiwrite_cmd);
|
1896
|
+
+ add_command(&aio_read_cmd);
|
1897
|
+
+ add_command(&aio_write_cmd);
|
1898
|
+
+ add_command(&aio_flush_cmd);
|
1899
|
+
+ add_command(&flush_cmd);
|
1900
|
+
+ add_command(&truncate_cmd);
|
1901
|
+
+ add_command(&length_cmd);
|
1902
|
+
+ add_command(&info_cmd);
|
1903
|
+
+ add_command(&discard_cmd);
|
1904
|
+
+ add_command(&alloc_cmd);
|
1905
|
+
+ add_command(&map_cmd);
|
1906
|
+
+ add_command(&break_cmd);
|
1907
|
+
+ add_command(&resume_cmd);
|
1908
|
+
+ add_command(&wait_break_cmd);
|
1909
|
+
+ add_command(&abort_cmd);
|
1910
|
+
+ add_command(&sleep_cmd);
|
1911
|
+
+
|
1912
|
+
+ add_check_command(init_check_command);
|
1913
|
+
+}
|
1914
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
1915
|
+
index c3cc4f3..4f1c808 100644
|
1916
|
+
--- a/qemu-io.c
|
1917
|
+
+++ b/qemu-io.c
|
1918
|
+
|
1919
|
+
char *progname;
|
1920
|
+
|
1921
|
+
BlockDriverState *qemuio_bs;
|
1922
|
+
-static int misalign;
|
1923
|
+
|
1924
|
+
-static int64_t cvtnum(const char *s)
|
1925
|
+
-{
|
1926
|
+
- char *end;
|
1927
|
+
- return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
|
1928
|
+
-}
|
1929
|
+
-
|
1930
|
+
-/*
|
1931
|
+
- * Parse the pattern argument to various sub-commands.
|
1932
|
+
- *
|
1933
|
+
- * Because the pattern is used as an argument to memset it must evaluate
|
1934
|
+
- * to an unsigned integer that fits into a single byte.
|
1935
|
+
- */
|
1936
|
+
-static int parse_pattern(const char *arg)
|
1937
|
+
-{
|
1938
|
+
- char *endptr = NULL;
|
1939
|
+
- long pattern;
|
1940
|
+
-
|
1941
|
+
- pattern = strtol(arg, &endptr, 0);
|
1942
|
+
- if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
|
1943
|
+
- printf("%s is not a valid pattern byte\n", arg);
|
1944
|
+
- return -1;
|
1945
|
+
- }
|
1946
|
+
-
|
1947
|
+
- return pattern;
|
1948
|
+
-}
|
1949
|
+
-
|
1950
|
+
-/*
|
1951
|
+
- * Memory allocation helpers.
|
1952
|
+
- *
|
1953
|
+
- * Make sure memory is aligned by default, or purposefully misaligned if
|
1954
|
+
- * that is specified on the command line.
|
1955
|
+
- */
|
1956
|
+
-
|
1957
|
+
-#define MISALIGN_OFFSET 16
|
1958
|
+
-static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
|
1959
|
+
-{
|
1960
|
+
- void *buf;
|
1961
|
+
-
|
1962
|
+
- if (misalign) {
|
1963
|
+
- len += MISALIGN_OFFSET;
|
1964
|
+
- }
|
1965
|
+
- buf = qemu_blockalign(bs, len);
|
1966
|
+
- memset(buf, pattern, len);
|
1967
|
+
- if (misalign) {
|
1968
|
+
- buf += MISALIGN_OFFSET;
|
1969
|
+
- }
|
1970
|
+
- return buf;
|
1971
|
+
-}
|
1972
|
+
-
|
1973
|
+
-static void qemu_io_free(void *p)
|
1974
|
+
-{
|
1975
|
+
- if (misalign) {
|
1976
|
+
- p -= MISALIGN_OFFSET;
|
1977
|
+
- }
|
1978
|
+
- qemu_vfree(p);
|
1979
|
+
-}
|
1980
|
+
-
|
1981
|
+
-static void dump_buffer(const void *buffer, int64_t offset, int len)
|
1982
|
+
-{
|
1983
|
+
- int i, j;
|
1984
|
+
- const uint8_t *p;
|
1985
|
+
-
|
1986
|
+
- for (i = 0, p = buffer; i < len; i += 16) {
|
1987
|
+
- const uint8_t *s = p;
|
1988
|
+
-
|
1989
|
+
- printf("%08" PRIx64 ": ", offset + i);
|
1990
|
+
- for (j = 0; j < 16 && i + j < len; j++, p++) {
|
1991
|
+
- printf("%02x ", *p);
|
1992
|
+
- }
|
1993
|
+
- printf(" ");
|
1994
|
+
- for (j = 0; j < 16 && i + j < len; j++, s++) {
|
1995
|
+
- if (isalnum(*s)) {
|
1996
|
+
- printf("%c", *s);
|
1997
|
+
- } else {
|
1998
|
+
- printf(".");
|
1999
|
+
- }
|
2000
|
+
- }
|
2001
|
+
- printf("\n");
|
2002
|
+
- }
|
2003
|
+
-}
|
2004
|
+
-
|
2005
|
+
-static void print_report(const char *op, struct timeval *t, int64_t offset,
|
2006
|
+
- int count, int total, int cnt, int Cflag)
|
2007
|
+
-{
|
2008
|
+
- char s1[64], s2[64], ts[64];
|
2009
|
+
-
|
2010
|
+
- timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
|
2011
|
+
- if (!Cflag) {
|
2012
|
+
- cvtstr((double)total, s1, sizeof(s1));
|
2013
|
+
- cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
|
2014
|
+
- printf("%s %d/%d bytes at offset %" PRId64 "\n",
|
2015
|
+
- op, total, count, offset);
|
2016
|
+
- printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
|
2017
|
+
- s1, cnt, ts, s2, tdiv((double)cnt, *t));
|
2018
|
+
- } else {/* bytes,ops,time,bytes/sec,ops/sec */
|
2019
|
+
- printf("%d,%d,%s,%.3f,%.3f\n",
|
2020
|
+
- total, cnt, ts,
|
2021
|
+
- tdiv((double)total, *t),
|
2022
|
+
- tdiv((double)cnt, *t));
|
2023
|
+
- }
|
2024
|
+
-}
|
2025
|
+
-
|
2026
|
+
-/*
|
2027
|
+
- * Parse multiple length statements for vectored I/O, and construct an I/O
|
2028
|
+
- * vector matching it.
|
2029
|
+
- */
|
2030
|
+
-static void *
|
2031
|
+
-create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
|
2032
|
+
- int pattern)
|
2033
|
+
-{
|
2034
|
+
- size_t *sizes = g_new0(size_t, nr_iov);
|
2035
|
+
- size_t count = 0;
|
2036
|
+
- void *buf = NULL;
|
2037
|
+
- void *p;
|
2038
|
+
- int i;
|
2039
|
+
-
|
2040
|
+
- for (i = 0; i < nr_iov; i++) {
|
2041
|
+
- char *arg = argv[i];
|
2042
|
+
- int64_t len;
|
2043
|
+
-
|
2044
|
+
- len = cvtnum(arg);
|
2045
|
+
- if (len < 0) {
|
2046
|
+
- printf("non-numeric length argument -- %s\n", arg);
|
2047
|
+
- goto fail;
|
2048
|
+
- }
|
2049
|
+
-
|
2050
|
+
- /* should be SIZE_T_MAX, but that doesn't exist */
|
2051
|
+
- if (len > INT_MAX) {
|
2052
|
+
- printf("too large length argument -- %s\n", arg);
|
2053
|
+
- goto fail;
|
2054
|
+
- }
|
2055
|
+
-
|
2056
|
+
- if (len & 0x1ff) {
|
2057
|
+
- printf("length argument %" PRId64
|
2058
|
+
- " is not sector aligned\n", len);
|
2059
|
+
- goto fail;
|
2060
|
+
- }
|
2061
|
+
-
|
2062
|
+
- sizes[i] = len;
|
2063
|
+
- count += len;
|
2064
|
+
- }
|
2065
|
+
-
|
2066
|
+
- qemu_iovec_init(qiov, nr_iov);
|
2067
|
+
-
|
2068
|
+
- buf = p = qemu_io_alloc(bs, count, pattern);
|
2069
|
+
-
|
2070
|
+
- for (i = 0; i < nr_iov; i++) {
|
2071
|
+
- qemu_iovec_add(qiov, p, sizes[i]);
|
2072
|
+
- p += sizes[i];
|
2073
|
+
- }
|
2074
|
+
-
|
2075
|
+
-fail:
|
2076
|
+
- g_free(sizes);
|
2077
|
+
- return buf;
|
2078
|
+
-}
|
2079
|
+
-
|
2080
|
+
-static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
2081
|
+
- int *total)
|
2082
|
+
-{
|
2083
|
+
- int ret;
|
2084
|
+
-
|
2085
|
+
- ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
|
2086
|
+
- if (ret < 0) {
|
2087
|
+
- return ret;
|
2088
|
+
- }
|
2089
|
+
- *total = count;
|
2090
|
+
- return 1;
|
2091
|
+
-}
|
2092
|
+
-
|
2093
|
+
-static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
2094
|
+
- int *total)
|
2095
|
+
-{
|
2096
|
+
- int ret;
|
2097
|
+
-
|
2098
|
+
- ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
|
2099
|
+
- if (ret < 0) {
|
2100
|
+
- return ret;
|
2101
|
+
- }
|
2102
|
+
- *total = count;
|
2103
|
+
- return 1;
|
2104
|
+
-}
|
2105
|
+
-
|
2106
|
+
-static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
2107
|
+
- int *total)
|
2108
|
+
-{
|
2109
|
+
- *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
|
2110
|
+
- if (*total < 0) {
|
2111
|
+
- return *total;
|
2112
|
+
- }
|
2113
|
+
- return 1;
|
2114
|
+
-}
|
2115
|
+
-
|
2116
|
+
-static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
2117
|
+
- int *total)
|
2118
|
+
-{
|
2119
|
+
- *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
|
2120
|
+
- if (*total < 0) {
|
2121
|
+
- return *total;
|
2122
|
+
- }
|
2123
|
+
- return 1;
|
2124
|
+
-}
|
2125
|
+
-
|
2126
|
+
-typedef struct {
|
2127
|
+
- BlockDriverState *bs;
|
2128
|
+
- int64_t offset;
|
2129
|
+
- int count;
|
2130
|
+
- int *total;
|
2131
|
+
- int ret;
|
2132
|
+
- bool done;
|
2133
|
+
-} CoWriteZeroes;
|
2134
|
+
-
|
2135
|
+
-static void coroutine_fn co_write_zeroes_entry(void *opaque)
|
2136
|
+
-{
|
2137
|
+
- CoWriteZeroes *data = opaque;
|
2138
|
+
-
|
2139
|
+
- data->ret = bdrv_co_write_zeroes(data->bs, data->offset / BDRV_SECTOR_SIZE,
|
2140
|
+
- data->count / BDRV_SECTOR_SIZE, 0);
|
2141
|
+
- data->done = true;
|
2142
|
+
- if (data->ret < 0) {
|
2143
|
+
- *data->total = data->ret;
|
2144
|
+
- return;
|
2145
|
+
- }
|
2146
|
+
-
|
2147
|
+
- *data->total = data->count;
|
2148
|
+
-}
|
2149
|
+
-
|
2150
|
+
-static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
|
2151
|
+
- int *total)
|
2152
|
+
-{
|
2153
|
+
- Coroutine *co;
|
2154
|
+
- CoWriteZeroes data = {
|
2155
|
+
- .bs = bs,
|
2156
|
+
- .offset = offset,
|
2157
|
+
- .count = count,
|
2158
|
+
- .total = total,
|
2159
|
+
- .done = false,
|
2160
|
+
- };
|
2161
|
+
-
|
2162
|
+
- co = qemu_coroutine_create(co_write_zeroes_entry);
|
2163
|
+
- qemu_coroutine_enter(co, &data);
|
2164
|
+
- while (!data.done) {
|
2165
|
+
- qemu_aio_wait();
|
2166
|
+
- }
|
2167
|
+
- if (data.ret < 0) {
|
2168
|
+
- return data.ret;
|
2169
|
+
- } else {
|
2170
|
+
- return 1;
|
2171
|
+
- }
|
2172
|
+
-}
|
2173
|
+
-
|
2174
|
+
-static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
|
2175
|
+
- int count, int *total)
|
2176
|
+
-{
|
2177
|
+
- int ret;
|
2178
|
+
-
|
2179
|
+
- ret = bdrv_write_compressed(bs, offset >> 9, (uint8_t *)buf, count >> 9);
|
2180
|
+
- if (ret < 0) {
|
2181
|
+
- return ret;
|
2182
|
+
- }
|
2183
|
+
- *total = count;
|
2184
|
+
- return 1;
|
2185
|
+
-}
|
2186
|
+
-
|
2187
|
+
-static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
|
2188
|
+
- int count, int *total)
|
2189
|
+
-{
|
2190
|
+
- *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
|
2191
|
+
- if (*total < 0) {
|
2192
|
+
- return *total;
|
2193
|
+
- }
|
2194
|
+
- return 1;
|
2195
|
+
-}
|
2196
|
+
-
|
2197
|
+
-static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
|
2198
|
+
- int count, int *total)
|
2199
|
+
-{
|
2200
|
+
- *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
|
2201
|
+
- if (*total < 0) {
|
2202
|
+
- return *total;
|
2203
|
+
- }
|
2204
|
+
- return 1;
|
2205
|
+
-}
|
2206
|
+
-
|
2207
|
+
-#define NOT_DONE 0x7fffffff
|
2208
|
+
-static void aio_rw_done(void *opaque, int ret)
|
2209
|
+
-{
|
2210
|
+
- *(int *)opaque = ret;
|
2211
|
+
-}
|
2212
|
+
-
|
2213
|
+
-static int do_aio_readv(BlockDriverState *bs, QEMUIOVector *qiov,
|
2214
|
+
- int64_t offset, int *total)
|
2215
|
+
-{
|
2216
|
+
- int async_ret = NOT_DONE;
|
2217
|
+
-
|
2218
|
+
- bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
|
2219
|
+
- aio_rw_done, &async_ret);
|
2220
|
+
- while (async_ret == NOT_DONE) {
|
2221
|
+
- main_loop_wait(false);
|
2222
|
+
- }
|
2223
|
+
-
|
2224
|
+
- *total = qiov->size;
|
2225
|
+
- return async_ret < 0 ? async_ret : 1;
|
2226
|
+
-}
|
2227
|
+
-
|
2228
|
+
-static int do_aio_writev(BlockDriverState *bs, QEMUIOVector *qiov,
|
2229
|
+
- int64_t offset, int *total)
|
2230
|
+
-{
|
2231
|
+
- int async_ret = NOT_DONE;
|
2232
|
+
-
|
2233
|
+
- bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
|
2234
|
+
- aio_rw_done, &async_ret);
|
2235
|
+
- while (async_ret == NOT_DONE) {
|
2236
|
+
- main_loop_wait(false);
|
2237
|
+
- }
|
2238
|
+
-
|
2239
|
+
- *total = qiov->size;
|
2240
|
+
- return async_ret < 0 ? async_ret : 1;
|
2241
|
+
-}
|
2242
|
+
-
|
2243
|
+
-struct multiwrite_async_ret {
|
2244
|
+
- int num_done;
|
2245
|
+
- int error;
|
2246
|
+
-};
|
2247
|
+
-
|
2248
|
+
-static void multiwrite_cb(void *opaque, int ret)
|
2249
|
+
-{
|
2250
|
+
- struct multiwrite_async_ret *async_ret = opaque;
|
2251
|
+
-
|
2252
|
+
- async_ret->num_done++;
|
2253
|
+
- if (ret < 0) {
|
2254
|
+
- async_ret->error = ret;
|
2255
|
+
- }
|
2256
|
+
-}
|
2257
|
+
-
|
2258
|
+
-static int do_aio_multiwrite(BlockDriverState *bs, BlockRequest* reqs,
|
2259
|
+
- int num_reqs, int *total)
|
2260
|
+
-{
|
2261
|
+
- int i, ret;
|
2262
|
+
- struct multiwrite_async_ret async_ret = {
|
2263
|
+
- .num_done = 0,
|
2264
|
+
- .error = 0,
|
2265
|
+
- };
|
2266
|
+
-
|
2267
|
+
- *total = 0;
|
2268
|
+
- for (i = 0; i < num_reqs; i++) {
|
2269
|
+
- reqs[i].cb = multiwrite_cb;
|
2270
|
+
- reqs[i].opaque = &async_ret;
|
2271
|
+
- *total += reqs[i].qiov->size;
|
2272
|
+
- }
|
2273
|
+
-
|
2274
|
+
- ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
|
2275
|
+
- if (ret < 0) {
|
2276
|
+
- return ret;
|
2277
|
+
- }
|
2278
|
+
-
|
2279
|
+
- while (async_ret.num_done < num_reqs) {
|
2280
|
+
- main_loop_wait(false);
|
2281
|
+
- }
|
2282
|
+
-
|
2283
|
+
- return async_ret.error < 0 ? async_ret.error : 1;
|
2284
|
+
-}
|
2285
|
+
-
|
2286
|
+
-static void read_help(void)
|
2287
|
+
-{
|
2288
|
+
- printf(
|
2289
|
+
-"\n"
|
2290
|
+
-" reads a range of bytes from the given offset\n"
|
2291
|
+
-"\n"
|
2292
|
+
-" Example:\n"
|
2293
|
+
-" 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
|
2294
|
+
-"\n"
|
2295
|
+
-" Reads a segment of the currently open file, optionally dumping it to the\n"
|
2296
|
+
-" standard output stream (with -v option) for subsequent inspection.\n"
|
2297
|
+
-" -b, -- read from the VM state rather than the virtual disk\n"
|
2298
|
+
-" -C, -- report statistics in a machine parsable format\n"
|
2299
|
+
-" -l, -- length for pattern verification (only with -P)\n"
|
2300
|
+
-" -p, -- use bdrv_pread to read the file\n"
|
2301
|
+
-" -P, -- use a pattern to verify read data\n"
|
2302
|
+
-" -q, -- quiet mode, do not show I/O statistics\n"
|
2303
|
+
-" -s, -- start offset for pattern verification (only with -P)\n"
|
2304
|
+
-" -v, -- dump buffer to standard output\n"
|
2305
|
+
-"\n");
|
2306
|
+
-}
|
2307
|
+
-
|
2308
|
+
-static int read_f(BlockDriverState *bs, int argc, char **argv);
|
2309
|
+
-
|
2310
|
+
-static const cmdinfo_t read_cmd = {
|
2311
|
+
- .name = "read",
|
2312
|
+
- .altname = "r",
|
2313
|
+
- .cfunc = read_f,
|
2314
|
+
- .argmin = 2,
|
2315
|
+
- .argmax = -1,
|
2316
|
+
- .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
|
2317
|
+
- .oneline = "reads a number of bytes at a specified offset",
|
2318
|
+
- .help = read_help,
|
2319
|
+
-};
|
2320
|
+
-
|
2321
|
+
-static int read_f(BlockDriverState *bs, int argc, char **argv)
|
2322
|
+
-{
|
2323
|
+
- struct timeval t1, t2;
|
2324
|
+
- int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
|
2325
|
+
- int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
|
2326
|
+
- int c, cnt;
|
2327
|
+
- char *buf;
|
2328
|
+
- int64_t offset;
|
2329
|
+
- int count;
|
2330
|
+
- /* Some compilers get confused and warn if this is not initialized. */
|
2331
|
+
- int total = 0;
|
2332
|
+
- int pattern = 0, pattern_offset = 0, pattern_count = 0;
|
2333
|
+
-
|
2334
|
+
- while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
|
2335
|
+
- switch (c) {
|
2336
|
+
- case 'b':
|
2337
|
+
- bflag = 1;
|
2338
|
+
- break;
|
2339
|
+
- case 'C':
|
2340
|
+
- Cflag = 1;
|
2341
|
+
- break;
|
2342
|
+
- case 'l':
|
2343
|
+
- lflag = 1;
|
2344
|
+
- pattern_count = cvtnum(optarg);
|
2345
|
+
- if (pattern_count < 0) {
|
2346
|
+
- printf("non-numeric length argument -- %s\n", optarg);
|
2347
|
+
- return 0;
|
2348
|
+
- }
|
2349
|
+
- break;
|
2350
|
+
- case 'p':
|
2351
|
+
- pflag = 1;
|
2352
|
+
- break;
|
2353
|
+
- case 'P':
|
2354
|
+
- Pflag = 1;
|
2355
|
+
- pattern = parse_pattern(optarg);
|
2356
|
+
- if (pattern < 0) {
|
2357
|
+
- return 0;
|
2358
|
+
- }
|
2359
|
+
- break;
|
2360
|
+
- case 'q':
|
2361
|
+
- qflag = 1;
|
2362
|
+
- break;
|
2363
|
+
- case 's':
|
2364
|
+
- sflag = 1;
|
2365
|
+
- pattern_offset = cvtnum(optarg);
|
2366
|
+
- if (pattern_offset < 0) {
|
2367
|
+
- printf("non-numeric length argument -- %s\n", optarg);
|
2368
|
+
- return 0;
|
2369
|
+
- }
|
2370
|
+
- break;
|
2371
|
+
- case 'v':
|
2372
|
+
- vflag = 1;
|
2373
|
+
- break;
|
2374
|
+
- default:
|
2375
|
+
- return command_usage(&read_cmd);
|
2376
|
+
- }
|
2377
|
+
- }
|
2378
|
+
-
|
2379
|
+
- if (optind != argc - 2) {
|
2380
|
+
- return command_usage(&read_cmd);
|
2381
|
+
- }
|
2382
|
+
-
|
2383
|
+
- if (bflag && pflag) {
|
2384
|
+
- printf("-b and -p cannot be specified at the same time\n");
|
2385
|
+
- return 0;
|
2386
|
+
- }
|
2387
|
+
-
|
2388
|
+
- offset = cvtnum(argv[optind]);
|
2389
|
+
- if (offset < 0) {
|
2390
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
2391
|
+
- return 0;
|
2392
|
+
- }
|
2393
|
+
-
|
2394
|
+
- optind++;
|
2395
|
+
- count = cvtnum(argv[optind]);
|
2396
|
+
- if (count < 0) {
|
2397
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
2398
|
+
- return 0;
|
2399
|
+
- }
|
2400
|
+
-
|
2401
|
+
- if (!Pflag && (lflag || sflag)) {
|
2402
|
+
- return command_usage(&read_cmd);
|
2403
|
+
- }
|
2404
|
+
-
|
2405
|
+
- if (!lflag) {
|
2406
|
+
- pattern_count = count - pattern_offset;
|
2407
|
+
- }
|
2408
|
+
-
|
2409
|
+
- if ((pattern_count < 0) || (pattern_count + pattern_offset > count)) {
|
2410
|
+
- printf("pattern verification range exceeds end of read data\n");
|
2411
|
+
- return 0;
|
2412
|
+
- }
|
2413
|
+
-
|
2414
|
+
- if (!pflag) {
|
2415
|
+
- if (offset & 0x1ff) {
|
2416
|
+
- printf("offset %" PRId64 " is not sector aligned\n",
|
2417
|
+
- offset);
|
2418
|
+
- return 0;
|
2419
|
+
- }
|
2420
|
+
- if (count & 0x1ff) {
|
2421
|
+
- printf("count %d is not sector aligned\n",
|
2422
|
+
- count);
|
2423
|
+
- return 0;
|
2424
|
+
- }
|
2425
|
+
- }
|
2426
|
+
-
|
2427
|
+
- buf = qemu_io_alloc(bs, count, 0xab);
|
2428
|
+
-
|
2429
|
+
- gettimeofday(&t1, NULL);
|
2430
|
+
- if (pflag) {
|
2431
|
+
- cnt = do_pread(bs, buf, offset, count, &total);
|
2432
|
+
- } else if (bflag) {
|
2433
|
+
- cnt = do_load_vmstate(bs, buf, offset, count, &total);
|
2434
|
+
- } else {
|
2435
|
+
- cnt = do_read(bs, buf, offset, count, &total);
|
2436
|
+
- }
|
2437
|
+
- gettimeofday(&t2, NULL);
|
2438
|
+
-
|
2439
|
+
- if (cnt < 0) {
|
2440
|
+
- printf("read failed: %s\n", strerror(-cnt));
|
2441
|
+
- goto out;
|
2442
|
+
- }
|
2443
|
+
-
|
2444
|
+
- if (Pflag) {
|
2445
|
+
- void *cmp_buf = g_malloc(pattern_count);
|
2446
|
+
- memset(cmp_buf, pattern, pattern_count);
|
2447
|
+
- if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
|
2448
|
+
- printf("Pattern verification failed at offset %"
|
2449
|
+
- PRId64 ", %d bytes\n",
|
2450
|
+
- offset + pattern_offset, pattern_count);
|
2451
|
+
- }
|
2452
|
+
- g_free(cmp_buf);
|
2453
|
+
- }
|
2454
|
+
-
|
2455
|
+
- if (qflag) {
|
2456
|
+
- goto out;
|
2457
|
+
- }
|
2458
|
+
-
|
2459
|
+
- if (vflag) {
|
2460
|
+
- dump_buffer(buf, offset, count);
|
2461
|
+
- }
|
2462
|
+
-
|
2463
|
+
- /* Finally, report back -- -C gives a parsable format */
|
2464
|
+
- t2 = tsub(t2, t1);
|
2465
|
+
- print_report("read", &t2, offset, count, total, cnt, Cflag);
|
2466
|
+
-
|
2467
|
+
-out:
|
2468
|
+
- qemu_io_free(buf);
|
2469
|
+
-
|
2470
|
+
- return 0;
|
2471
|
+
-}
|
2472
|
+
-
|
2473
|
+
-static void readv_help(void)
|
2474
|
+
-{
|
2475
|
+
- printf(
|
2476
|
+
-"\n"
|
2477
|
+
-" reads a range of bytes from the given offset into multiple buffers\n"
|
2478
|
+
-"\n"
|
2479
|
+
-" Example:\n"
|
2480
|
+
-" 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
|
2481
|
+
-"\n"
|
2482
|
+
-" Reads a segment of the currently open file, optionally dumping it to the\n"
|
2483
|
+
-" standard output stream (with -v option) for subsequent inspection.\n"
|
2484
|
+
-" Uses multiple iovec buffers if more than one byte range is specified.\n"
|
2485
|
+
-" -C, -- report statistics in a machine parsable format\n"
|
2486
|
+
-" -P, -- use a pattern to verify read data\n"
|
2487
|
+
-" -v, -- dump buffer to standard output\n"
|
2488
|
+
-" -q, -- quiet mode, do not show I/O statistics\n"
|
2489
|
+
-"\n");
|
2490
|
+
-}
|
2491
|
+
-
|
2492
|
+
-static int readv_f(BlockDriverState *bs, int argc, char **argv);
|
2493
|
+
-
|
2494
|
+
-static const cmdinfo_t readv_cmd = {
|
2495
|
+
- .name = "readv",
|
2496
|
+
- .cfunc = readv_f,
|
2497
|
+
- .argmin = 2,
|
2498
|
+
- .argmax = -1,
|
2499
|
+
- .args = "[-Cqv] [-P pattern ] off len [len..]",
|
2500
|
+
- .oneline = "reads a number of bytes at a specified offset",
|
2501
|
+
- .help = readv_help,
|
2502
|
+
-};
|
2503
|
+
-
|
2504
|
+
-static int readv_f(BlockDriverState *bs, int argc, char **argv)
|
2505
|
+
-{
|
2506
|
+
- struct timeval t1, t2;
|
2507
|
+
- int Cflag = 0, qflag = 0, vflag = 0;
|
2508
|
+
- int c, cnt;
|
2509
|
+
- char *buf;
|
2510
|
+
- int64_t offset;
|
2511
|
+
- /* Some compilers get confused and warn if this is not initialized. */
|
2512
|
+
- int total = 0;
|
2513
|
+
- int nr_iov;
|
2514
|
+
- QEMUIOVector qiov;
|
2515
|
+
- int pattern = 0;
|
2516
|
+
- int Pflag = 0;
|
2517
|
+
-
|
2518
|
+
- while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
|
2519
|
+
- switch (c) {
|
2520
|
+
- case 'C':
|
2521
|
+
- Cflag = 1;
|
2522
|
+
- break;
|
2523
|
+
- case 'P':
|
2524
|
+
- Pflag = 1;
|
2525
|
+
- pattern = parse_pattern(optarg);
|
2526
|
+
- if (pattern < 0) {
|
2527
|
+
- return 0;
|
2528
|
+
- }
|
2529
|
+
- break;
|
2530
|
+
- case 'q':
|
2531
|
+
- qflag = 1;
|
2532
|
+
- break;
|
2533
|
+
- case 'v':
|
2534
|
+
- vflag = 1;
|
2535
|
+
- break;
|
2536
|
+
- default:
|
2537
|
+
- return command_usage(&readv_cmd);
|
2538
|
+
- }
|
2539
|
+
- }
|
2540
|
+
-
|
2541
|
+
- if (optind > argc - 2) {
|
2542
|
+
- return command_usage(&readv_cmd);
|
2543
|
+
- }
|
2544
|
+
-
|
2545
|
+
-
|
2546
|
+
- offset = cvtnum(argv[optind]);
|
2547
|
+
- if (offset < 0) {
|
2548
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
2549
|
+
- return 0;
|
2550
|
+
- }
|
2551
|
+
- optind++;
|
2552
|
+
-
|
2553
|
+
- if (offset & 0x1ff) {
|
2554
|
+
- printf("offset %" PRId64 " is not sector aligned\n",
|
2555
|
+
- offset);
|
2556
|
+
- return 0;
|
2557
|
+
- }
|
2558
|
+
-
|
2559
|
+
- nr_iov = argc - optind;
|
2560
|
+
- buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, 0xab);
|
2561
|
+
- if (buf == NULL) {
|
2562
|
+
- return 0;
|
2563
|
+
- }
|
2564
|
+
-
|
2565
|
+
- gettimeofday(&t1, NULL);
|
2566
|
+
- cnt = do_aio_readv(bs, &qiov, offset, &total);
|
2567
|
+
- gettimeofday(&t2, NULL);
|
2568
|
+
-
|
2569
|
+
- if (cnt < 0) {
|
2570
|
+
- printf("readv failed: %s\n", strerror(-cnt));
|
2571
|
+
- goto out;
|
2572
|
+
- }
|
2573
|
+
-
|
2574
|
+
- if (Pflag) {
|
2575
|
+
- void *cmp_buf = g_malloc(qiov.size);
|
2576
|
+
- memset(cmp_buf, pattern, qiov.size);
|
2577
|
+
- if (memcmp(buf, cmp_buf, qiov.size)) {
|
2578
|
+
- printf("Pattern verification failed at offset %"
|
2579
|
+
- PRId64 ", %zd bytes\n", offset, qiov.size);
|
2580
|
+
- }
|
2581
|
+
- g_free(cmp_buf);
|
2582
|
+
- }
|
2583
|
+
-
|
2584
|
+
- if (qflag) {
|
2585
|
+
- goto out;
|
2586
|
+
- }
|
2587
|
+
-
|
2588
|
+
- if (vflag) {
|
2589
|
+
- dump_buffer(buf, offset, qiov.size);
|
2590
|
+
- }
|
2591
|
+
-
|
2592
|
+
- /* Finally, report back -- -C gives a parsable format */
|
2593
|
+
- t2 = tsub(t2, t1);
|
2594
|
+
- print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
|
2595
|
+
-
|
2596
|
+
-out:
|
2597
|
+
- qemu_iovec_destroy(&qiov);
|
2598
|
+
- qemu_io_free(buf);
|
2599
|
+
- return 0;
|
2600
|
+
-}
|
2601
|
+
-
|
2602
|
+
-static void write_help(void)
|
2603
|
+
-{
|
2604
|
+
- printf(
|
2605
|
+
-"\n"
|
2606
|
+
-" writes a range of bytes from the given offset\n"
|
2607
|
+
-"\n"
|
2608
|
+
-" Example:\n"
|
2609
|
+
-" 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
|
2610
|
+
-"\n"
|
2611
|
+
-" Writes into a segment of the currently open file, using a buffer\n"
|
2612
|
+
-" filled with a set pattern (0xcdcdcdcd).\n"
|
2613
|
+
-" -b, -- write to the VM state rather than the virtual disk\n"
|
2614
|
+
-" -c, -- write compressed data with bdrv_write_compressed\n"
|
2615
|
+
-" -p, -- use bdrv_pwrite to write the file\n"
|
2616
|
+
-" -P, -- use different pattern to fill file\n"
|
2617
|
+
-" -C, -- report statistics in a machine parsable format\n"
|
2618
|
+
-" -q, -- quiet mode, do not show I/O statistics\n"
|
2619
|
+
-" -z, -- write zeroes using bdrv_co_write_zeroes\n"
|
2620
|
+
-"\n");
|
2621
|
+
-}
|
2622
|
+
-
|
2623
|
+
-static int write_f(BlockDriverState *bs, int argc, char **argv);
|
2624
|
+
-
|
2625
|
+
-static const cmdinfo_t write_cmd = {
|
2626
|
+
- .name = "write",
|
2627
|
+
- .altname = "w",
|
2628
|
+
- .cfunc = write_f,
|
2629
|
+
- .argmin = 2,
|
2630
|
+
- .argmax = -1,
|
2631
|
+
- .args = "[-bcCpqz] [-P pattern ] off len",
|
2632
|
+
- .oneline = "writes a number of bytes at a specified offset",
|
2633
|
+
- .help = write_help,
|
2634
|
+
-};
|
2635
|
+
-
|
2636
|
+
-static int write_f(BlockDriverState *bs, int argc, char **argv)
|
2637
|
+
-{
|
2638
|
+
- struct timeval t1, t2;
|
2639
|
+
- int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
|
2640
|
+
- int cflag = 0;
|
2641
|
+
- int c, cnt;
|
2642
|
+
- char *buf = NULL;
|
2643
|
+
- int64_t offset;
|
2644
|
+
- int count;
|
2645
|
+
- /* Some compilers get confused and warn if this is not initialized. */
|
2646
|
+
- int total = 0;
|
2647
|
+
- int pattern = 0xcd;
|
2648
|
+
-
|
2649
|
+
- while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) {
|
2650
|
+
- switch (c) {
|
2651
|
+
- case 'b':
|
2652
|
+
- bflag = 1;
|
2653
|
+
- break;
|
2654
|
+
- case 'c':
|
2655
|
+
- cflag = 1;
|
2656
|
+
- break;
|
2657
|
+
- case 'C':
|
2658
|
+
- Cflag = 1;
|
2659
|
+
- break;
|
2660
|
+
- case 'p':
|
2661
|
+
- pflag = 1;
|
2662
|
+
- break;
|
2663
|
+
- case 'P':
|
2664
|
+
- Pflag = 1;
|
2665
|
+
- pattern = parse_pattern(optarg);
|
2666
|
+
- if (pattern < 0) {
|
2667
|
+
- return 0;
|
2668
|
+
- }
|
2669
|
+
- break;
|
2670
|
+
- case 'q':
|
2671
|
+
- qflag = 1;
|
2672
|
+
- break;
|
2673
|
+
- case 'z':
|
2674
|
+
- zflag = 1;
|
2675
|
+
- break;
|
2676
|
+
- default:
|
2677
|
+
- return command_usage(&write_cmd);
|
2678
|
+
- }
|
2679
|
+
- }
|
2680
|
+
-
|
2681
|
+
- if (optind != argc - 2) {
|
2682
|
+
- return command_usage(&write_cmd);
|
2683
|
+
- }
|
2684
|
+
-
|
2685
|
+
- if (bflag + pflag + zflag > 1) {
|
2686
|
+
- printf("-b, -p, or -z cannot be specified at the same time\n");
|
2687
|
+
- return 0;
|
2688
|
+
- }
|
2689
|
+
-
|
2690
|
+
- if (zflag && Pflag) {
|
2691
|
+
- printf("-z and -P cannot be specified at the same time\n");
|
2692
|
+
- return 0;
|
2693
|
+
- }
|
2694
|
+
-
|
2695
|
+
- offset = cvtnum(argv[optind]);
|
2696
|
+
- if (offset < 0) {
|
2697
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
2698
|
+
- return 0;
|
2699
|
+
- }
|
2700
|
+
-
|
2701
|
+
- optind++;
|
2702
|
+
- count = cvtnum(argv[optind]);
|
2703
|
+
- if (count < 0) {
|
2704
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
2705
|
+
- return 0;
|
2706
|
+
- }
|
2707
|
+
-
|
2708
|
+
- if (!pflag) {
|
2709
|
+
- if (offset & 0x1ff) {
|
2710
|
+
- printf("offset %" PRId64 " is not sector aligned\n",
|
2711
|
+
- offset);
|
2712
|
+
- return 0;
|
2713
|
+
- }
|
2714
|
+
-
|
2715
|
+
- if (count & 0x1ff) {
|
2716
|
+
- printf("count %d is not sector aligned\n",
|
2717
|
+
- count);
|
2718
|
+
- return 0;
|
2719
|
+
- }
|
2720
|
+
- }
|
2721
|
+
-
|
2722
|
+
- if (!zflag) {
|
2723
|
+
- buf = qemu_io_alloc(bs, count, pattern);
|
2724
|
+
- }
|
2725
|
+
-
|
2726
|
+
- gettimeofday(&t1, NULL);
|
2727
|
+
- if (pflag) {
|
2728
|
+
- cnt = do_pwrite(bs, buf, offset, count, &total);
|
2729
|
+
- } else if (bflag) {
|
2730
|
+
- cnt = do_save_vmstate(bs, buf, offset, count, &total);
|
2731
|
+
- } else if (zflag) {
|
2732
|
+
- cnt = do_co_write_zeroes(bs, offset, count, &total);
|
2733
|
+
- } else if (cflag) {
|
2734
|
+
- cnt = do_write_compressed(bs, buf, offset, count, &total);
|
2735
|
+
- } else {
|
2736
|
+
- cnt = do_write(bs, buf, offset, count, &total);
|
2737
|
+
- }
|
2738
|
+
- gettimeofday(&t2, NULL);
|
2739
|
+
-
|
2740
|
+
- if (cnt < 0) {
|
2741
|
+
- printf("write failed: %s\n", strerror(-cnt));
|
2742
|
+
- goto out;
|
2743
|
+
- }
|
2744
|
+
-
|
2745
|
+
- if (qflag) {
|
2746
|
+
- goto out;
|
2747
|
+
- }
|
2748
|
+
-
|
2749
|
+
- /* Finally, report back -- -C gives a parsable format */
|
2750
|
+
- t2 = tsub(t2, t1);
|
2751
|
+
- print_report("wrote", &t2, offset, count, total, cnt, Cflag);
|
2752
|
+
-
|
2753
|
+
-out:
|
2754
|
+
- if (!zflag) {
|
2755
|
+
- qemu_io_free(buf);
|
2756
|
+
- }
|
2757
|
+
-
|
2758
|
+
- return 0;
|
2759
|
+
-}
|
2760
|
+
-
|
2761
|
+
-static void
|
2762
|
+
-writev_help(void)
|
2763
|
+
-{
|
2764
|
+
- printf(
|
2765
|
+
-"\n"
|
2766
|
+
-" writes a range of bytes from the given offset source from multiple buffers\n"
|
2767
|
+
-"\n"
|
2768
|
+
-" Example:\n"
|
2769
|
+
-" 'write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
|
2770
|
+
-"\n"
|
2771
|
+
-" Writes into a segment of the currently open file, using a buffer\n"
|
2772
|
+
-" filled with a set pattern (0xcdcdcdcd).\n"
|
2773
|
+
-" -P, -- use different pattern to fill file\n"
|
2774
|
+
-" -C, -- report statistics in a machine parsable format\n"
|
2775
|
+
-" -q, -- quiet mode, do not show I/O statistics\n"
|
2776
|
+
-"\n");
|
2777
|
+
-}
|
2778
|
+
-
|
2779
|
+
-static int writev_f(BlockDriverState *bs, int argc, char **argv);
|
2780
|
+
-
|
2781
|
+
-static const cmdinfo_t writev_cmd = {
|
2782
|
+
- .name = "writev",
|
2783
|
+
- .cfunc = writev_f,
|
2784
|
+
- .argmin = 2,
|
2785
|
+
- .argmax = -1,
|
2786
|
+
- .args = "[-Cq] [-P pattern ] off len [len..]",
|
2787
|
+
- .oneline = "writes a number of bytes at a specified offset",
|
2788
|
+
- .help = writev_help,
|
2789
|
+
-};
|
2790
|
+
-
|
2791
|
+
-static int writev_f(BlockDriverState *bs, int argc, char **argv)
|
2792
|
+
-{
|
2793
|
+
- struct timeval t1, t2;
|
2794
|
+
- int Cflag = 0, qflag = 0;
|
2795
|
+
- int c, cnt;
|
2796
|
+
- char *buf;
|
2797
|
+
- int64_t offset;
|
2798
|
+
- /* Some compilers get confused and warn if this is not initialized. */
|
2799
|
+
- int total = 0;
|
2800
|
+
- int nr_iov;
|
2801
|
+
- int pattern = 0xcd;
|
2802
|
+
- QEMUIOVector qiov;
|
2803
|
+
-
|
2804
|
+
- while ((c = getopt(argc, argv, "CqP:")) != EOF) {
|
2805
|
+
- switch (c) {
|
2806
|
+
- case 'C':
|
2807
|
+
- Cflag = 1;
|
2808
|
+
- break;
|
2809
|
+
- case 'q':
|
2810
|
+
- qflag = 1;
|
2811
|
+
- break;
|
2812
|
+
- case 'P':
|
2813
|
+
- pattern = parse_pattern(optarg);
|
2814
|
+
- if (pattern < 0) {
|
2815
|
+
- return 0;
|
2816
|
+
- }
|
2817
|
+
- break;
|
2818
|
+
- default:
|
2819
|
+
- return command_usage(&writev_cmd);
|
2820
|
+
- }
|
2821
|
+
- }
|
2822
|
+
-
|
2823
|
+
- if (optind > argc - 2) {
|
2824
|
+
- return command_usage(&writev_cmd);
|
2825
|
+
- }
|
2826
|
+
-
|
2827
|
+
- offset = cvtnum(argv[optind]);
|
2828
|
+
- if (offset < 0) {
|
2829
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
2830
|
+
- return 0;
|
2831
|
+
- }
|
2832
|
+
- optind++;
|
2833
|
+
-
|
2834
|
+
- if (offset & 0x1ff) {
|
2835
|
+
- printf("offset %" PRId64 " is not sector aligned\n",
|
2836
|
+
- offset);
|
2837
|
+
- return 0;
|
2838
|
+
- }
|
2839
|
+
-
|
2840
|
+
- nr_iov = argc - optind;
|
2841
|
+
- buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, pattern);
|
2842
|
+
- if (buf == NULL) {
|
2843
|
+
- return 0;
|
2844
|
+
- }
|
2845
|
+
-
|
2846
|
+
- gettimeofday(&t1, NULL);
|
2847
|
+
- cnt = do_aio_writev(bs, &qiov, offset, &total);
|
2848
|
+
- gettimeofday(&t2, NULL);
|
2849
|
+
-
|
2850
|
+
- if (cnt < 0) {
|
2851
|
+
- printf("writev failed: %s\n", strerror(-cnt));
|
2852
|
+
- goto out;
|
2853
|
+
- }
|
2854
|
+
-
|
2855
|
+
- if (qflag) {
|
2856
|
+
- goto out;
|
2857
|
+
- }
|
2858
|
+
-
|
2859
|
+
- /* Finally, report back -- -C gives a parsable format */
|
2860
|
+
- t2 = tsub(t2, t1);
|
2861
|
+
- print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
|
2862
|
+
-out:
|
2863
|
+
- qemu_iovec_destroy(&qiov);
|
2864
|
+
- qemu_io_free(buf);
|
2865
|
+
- return 0;
|
2866
|
+
-}
|
2867
|
+
-
|
2868
|
+
-static void multiwrite_help(void)
|
2869
|
+
-{
|
2870
|
+
- printf(
|
2871
|
+
-"\n"
|
2872
|
+
-" writes a range of bytes from the given offset source from multiple buffers,\n"
|
2873
|
+
-" in a batch of requests that may be merged by qemu\n"
|
2874
|
+
-"\n"
|
2875
|
+
-" Example:\n"
|
2876
|
+
-" 'multiwrite 512 1k 1k ; 4k 1k'\n"
|
2877
|
+
-" writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
|
2878
|
+
-"\n"
|
2879
|
+
-" Writes into a segment of the currently open file, using a buffer\n"
|
2880
|
+
-" filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
|
2881
|
+
-" by one for each request contained in the multiwrite command.\n"
|
2882
|
+
-" -P, -- use different pattern to fill file\n"
|
2883
|
+
-" -C, -- report statistics in a machine parsable format\n"
|
2884
|
+
-" -q, -- quiet mode, do not show I/O statistics\n"
|
2885
|
+
-"\n");
|
2886
|
+
-}
|
2887
|
+
-
|
2888
|
+
-static int multiwrite_f(BlockDriverState *bs, int argc, char **argv);
|
2889
|
+
-
|
2890
|
+
-static const cmdinfo_t multiwrite_cmd = {
|
2891
|
+
- .name = "multiwrite",
|
2892
|
+
- .cfunc = multiwrite_f,
|
2893
|
+
- .argmin = 2,
|
2894
|
+
- .argmax = -1,
|
2895
|
+
- .args = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
|
2896
|
+
- .oneline = "issues multiple write requests at once",
|
2897
|
+
- .help = multiwrite_help,
|
2898
|
+
-};
|
2899
|
+
-
|
2900
|
+
-static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
|
2901
|
+
-{
|
2902
|
+
- struct timeval t1, t2;
|
2903
|
+
- int Cflag = 0, qflag = 0;
|
2904
|
+
- int c, cnt;
|
2905
|
+
- char **buf;
|
2906
|
+
- int64_t offset, first_offset = 0;
|
2907
|
+
- /* Some compilers get confused and warn if this is not initialized. */
|
2908
|
+
- int total = 0;
|
2909
|
+
- int nr_iov;
|
2910
|
+
- int nr_reqs;
|
2911
|
+
- int pattern = 0xcd;
|
2912
|
+
- QEMUIOVector *qiovs;
|
2913
|
+
- int i;
|
2914
|
+
- BlockRequest *reqs;
|
2915
|
+
-
|
2916
|
+
- while ((c = getopt(argc, argv, "CqP:")) != EOF) {
|
2917
|
+
- switch (c) {
|
2918
|
+
- case 'C':
|
2919
|
+
- Cflag = 1;
|
2920
|
+
- break;
|
2921
|
+
- case 'q':
|
2922
|
+
- qflag = 1;
|
2923
|
+
- break;
|
2924
|
+
- case 'P':
|
2925
|
+
- pattern = parse_pattern(optarg);
|
2926
|
+
- if (pattern < 0) {
|
2927
|
+
- return 0;
|
2928
|
+
- }
|
2929
|
+
- break;
|
2930
|
+
- default:
|
2931
|
+
- return command_usage(&writev_cmd);
|
2932
|
+
- }
|
2933
|
+
- }
|
2934
|
+
-
|
2935
|
+
- if (optind > argc - 2) {
|
2936
|
+
- return command_usage(&writev_cmd);
|
2937
|
+
- }
|
2938
|
+
-
|
2939
|
+
- nr_reqs = 1;
|
2940
|
+
- for (i = optind; i < argc; i++) {
|
2941
|
+
- if (!strcmp(argv[i], ";")) {
|
2942
|
+
- nr_reqs++;
|
2943
|
+
- }
|
2944
|
+
- }
|
2945
|
+
-
|
2946
|
+
- reqs = g_malloc0(nr_reqs * sizeof(*reqs));
|
2947
|
+
- buf = g_malloc0(nr_reqs * sizeof(*buf));
|
2948
|
+
- qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
|
2949
|
+
-
|
2950
|
+
- for (i = 0; i < nr_reqs && optind < argc; i++) {
|
2951
|
+
- int j;
|
2952
|
+
-
|
2953
|
+
- /* Read the offset of the request */
|
2954
|
+
- offset = cvtnum(argv[optind]);
|
2955
|
+
- if (offset < 0) {
|
2956
|
+
- printf("non-numeric offset argument -- %s\n", argv[optind]);
|
2957
|
+
- goto out;
|
2958
|
+
- }
|
2959
|
+
- optind++;
|
2960
|
+
-
|
2961
|
+
- if (offset & 0x1ff) {
|
2962
|
+
- printf("offset %lld is not sector aligned\n",
|
2963
|
+
- (long long)offset);
|
2964
|
+
- goto out;
|
2965
|
+
- }
|
2966
|
+
-
|
2967
|
+
- if (i == 0) {
|
2968
|
+
- first_offset = offset;
|
2969
|
+
- }
|
2970
|
+
-
|
2971
|
+
- /* Read lengths for qiov entries */
|
2972
|
+
- for (j = optind; j < argc; j++) {
|
2973
|
+
- if (!strcmp(argv[j], ";")) {
|
2974
|
+
- break;
|
2975
|
+
- }
|
2976
|
+
- }
|
2977
|
+
-
|
2978
|
+
- nr_iov = j - optind;
|
2979
|
+
-
|
2980
|
+
- /* Build request */
|
2981
|
+
- buf[i] = create_iovec(bs, &qiovs[i], &argv[optind], nr_iov, pattern);
|
2982
|
+
- if (buf[i] == NULL) {
|
2983
|
+
- goto out;
|
2984
|
+
- }
|
2985
|
+
-
|
2986
|
+
- reqs[i].qiov = &qiovs[i];
|
2987
|
+
- reqs[i].sector = offset >> 9;
|
2988
|
+
- reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
|
2989
|
+
-
|
2990
|
+
- optind = j + 1;
|
2991
|
+
-
|
2992
|
+
- pattern++;
|
2993
|
+
- }
|
2994
|
+
-
|
2995
|
+
- /* If there were empty requests at the end, ignore them */
|
2996
|
+
- nr_reqs = i;
|
2997
|
+
-
|
2998
|
+
- gettimeofday(&t1, NULL);
|
2999
|
+
- cnt = do_aio_multiwrite(bs, reqs, nr_reqs, &total);
|
3000
|
+
- gettimeofday(&t2, NULL);
|
3001
|
+
-
|
3002
|
+
- if (cnt < 0) {
|
3003
|
+
- printf("aio_multiwrite failed: %s\n", strerror(-cnt));
|
3004
|
+
- goto out;
|
3005
|
+
- }
|
3006
|
+
-
|
3007
|
+
- if (qflag) {
|
3008
|
+
- goto out;
|
3009
|
+
- }
|
3010
|
+
-
|
3011
|
+
- /* Finally, report back -- -C gives a parsable format */
|
3012
|
+
- t2 = tsub(t2, t1);
|
3013
|
+
- print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
|
3014
|
+
-out:
|
3015
|
+
- for (i = 0; i < nr_reqs; i++) {
|
3016
|
+
- qemu_io_free(buf[i]);
|
3017
|
+
- if (reqs[i].qiov != NULL) {
|
3018
|
+
- qemu_iovec_destroy(&qiovs[i]);
|
3019
|
+
- }
|
3020
|
+
- }
|
3021
|
+
- g_free(buf);
|
3022
|
+
- g_free(reqs);
|
3023
|
+
- g_free(qiovs);
|
3024
|
+
- return 0;
|
3025
|
+
-}
|
3026
|
+
-
|
3027
|
+
-struct aio_ctx {
|
3028
|
+
- QEMUIOVector qiov;
|
3029
|
+
- int64_t offset;
|
3030
|
+
- char *buf;
|
3031
|
+
- int qflag;
|
3032
|
+
- int vflag;
|
3033
|
+
- int Cflag;
|
3034
|
+
- int Pflag;
|
3035
|
+
- int pattern;
|
3036
|
+
- struct timeval t1;
|
3037
|
+
-};
|
3038
|
+
-
|
3039
|
+
-static void aio_write_done(void *opaque, int ret)
|
3040
|
+
-{
|
3041
|
+
- struct aio_ctx *ctx = opaque;
|
3042
|
+
- struct timeval t2;
|
3043
|
+
-
|
3044
|
+
- gettimeofday(&t2, NULL);
|
3045
|
+
-
|
3046
|
+
-
|
3047
|
+
- if (ret < 0) {
|
3048
|
+
- printf("aio_write failed: %s\n", strerror(-ret));
|
3049
|
+
- goto out;
|
3050
|
+
- }
|
3051
|
+
-
|
3052
|
+
- if (ctx->qflag) {
|
3053
|
+
- goto out;
|
3054
|
+
- }
|
3055
|
+
-
|
3056
|
+
- /* Finally, report back -- -C gives a parsable format */
|
3057
|
+
- t2 = tsub(t2, ctx->t1);
|
3058
|
+
- print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
|
3059
|
+
- ctx->qiov.size, 1, ctx->Cflag);
|
3060
|
+
-out:
|
3061
|
+
- qemu_io_free(ctx->buf);
|
3062
|
+
- qemu_iovec_destroy(&ctx->qiov);
|
3063
|
+
- g_free(ctx);
|
3064
|
+
-}
|
3065
|
+
-
|
3066
|
+
-static void aio_read_done(void *opaque, int ret)
|
3067
|
+
-{
|
3068
|
+
- struct aio_ctx *ctx = opaque;
|
3069
|
+
- struct timeval t2;
|
3070
|
+
-
|
3071
|
+
- gettimeofday(&t2, NULL);
|
3072
|
+
-
|
3073
|
+
- if (ret < 0) {
|
3074
|
+
- printf("readv failed: %s\n", strerror(-ret));
|
3075
|
+
- goto out;
|
3076
|
+
- }
|
3077
|
+
-
|
3078
|
+
- if (ctx->Pflag) {
|
3079
|
+
- void *cmp_buf = g_malloc(ctx->qiov.size);
|
3080
|
+
-
|
3081
|
+
- memset(cmp_buf, ctx->pattern, ctx->qiov.size);
|
3082
|
+
- if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
|
3083
|
+
- printf("Pattern verification failed at offset %"
|
3084
|
+
- PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
|
3085
|
+
- }
|
3086
|
+
- g_free(cmp_buf);
|
3087
|
+
- }
|
3088
|
+
-
|
3089
|
+
- if (ctx->qflag) {
|
3090
|
+
- goto out;
|
3091
|
+
- }
|
3092
|
+
-
|
3093
|
+
- if (ctx->vflag) {
|
3094
|
+
- dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
|
3095
|
+
- }
|
3096
|
+
-
|
3097
|
+
- /* Finally, report back -- -C gives a parsable format */
|
3098
|
+
- t2 = tsub(t2, ctx->t1);
|
3099
|
+
- print_report("read", &t2, ctx->offset, ctx->qiov.size,
|
3100
|
+
- ctx->qiov.size, 1, ctx->Cflag);
|
3101
|
+
-out:
|
3102
|
+
- qemu_io_free(ctx->buf);
|
3103
|
+
- qemu_iovec_destroy(&ctx->qiov);
|
3104
|
+
- g_free(ctx);
|
3105
|
+
-}
|
3106
|
+
-
|
3107
|
+
-static void aio_read_help(void)
|
3108
|
+
-{
|
3109
|
+
- printf(
|
3110
|
+
-"\n"
|
3111
|
+
-" asynchronously reads a range of bytes from the given offset\n"
|
3112
|
+
-"\n"
|
3113
|
+
-" Example:\n"
|
3114
|
+
-" 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
|
3115
|
+
-"\n"
|
3116
|
+
-" Reads a segment of the currently open file, optionally dumping it to the\n"
|
3117
|
+
-" standard output stream (with -v option) for subsequent inspection.\n"
|
3118
|
+
-" The read is performed asynchronously and the aio_flush command must be\n"
|
3119
|
+
-" used to ensure all outstanding aio requests have been completed.\n"
|
3120
|
+
-" -C, -- report statistics in a machine parsable format\n"
|
3121
|
+
-" -P, -- use a pattern to verify read data\n"
|
3122
|
+
-" -v, -- dump buffer to standard output\n"
|
3123
|
+
-" -q, -- quiet mode, do not show I/O statistics\n"
|
3124
|
+
-"\n");
|
3125
|
+
-}
|
3126
|
+
-
|
3127
|
+
-static int aio_read_f(BlockDriverState *bs, int argc, char **argv);
|
3128
|
+
-
|
3129
|
+
-static const cmdinfo_t aio_read_cmd = {
|
3130
|
+
- .name = "aio_read",
|
3131
|
+
- .cfunc = aio_read_f,
|
3132
|
+
- .argmin = 2,
|
3133
|
+
- .argmax = -1,
|
3134
|
+
- .args = "[-Cqv] [-P pattern ] off len [len..]",
|
3135
|
+
- .oneline = "asynchronously reads a number of bytes",
|
3136
|
+
- .help = aio_read_help,
|
3137
|
+
-};
|
3138
|
+
-
|
3139
|
+
-static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
|
3140
|
+
-{
|
3141
|
+
- int nr_iov, c;
|
3142
|
+
- struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
|
3143
|
+
-
|
3144
|
+
- while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
|
3145
|
+
- switch (c) {
|
3146
|
+
- case 'C':
|
3147
|
+
- ctx->Cflag = 1;
|
3148
|
+
- break;
|
3149
|
+
- case 'P':
|
3150
|
+
- ctx->Pflag = 1;
|
3151
|
+
- ctx->pattern = parse_pattern(optarg);
|
3152
|
+
- if (ctx->pattern < 0) {
|
3153
|
+
- g_free(ctx);
|
3154
|
+
- return 0;
|
3155
|
+
- }
|
3156
|
+
- break;
|
3157
|
+
- case 'q':
|
3158
|
+
- ctx->qflag = 1;
|
3159
|
+
- break;
|
3160
|
+
- case 'v':
|
3161
|
+
- ctx->vflag = 1;
|
3162
|
+
- break;
|
3163
|
+
- default:
|
3164
|
+
- g_free(ctx);
|
3165
|
+
- return command_usage(&aio_read_cmd);
|
3166
|
+
- }
|
3167
|
+
- }
|
3168
|
+
-
|
3169
|
+
- if (optind > argc - 2) {
|
3170
|
+
- g_free(ctx);
|
3171
|
+
- return command_usage(&aio_read_cmd);
|
3172
|
+
- }
|
3173
|
+
-
|
3174
|
+
- ctx->offset = cvtnum(argv[optind]);
|
3175
|
+
- if (ctx->offset < 0) {
|
3176
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
3177
|
+
- g_free(ctx);
|
3178
|
+
- return 0;
|
3179
|
+
- }
|
3180
|
+
- optind++;
|
3181
|
+
-
|
3182
|
+
- if (ctx->offset & 0x1ff) {
|
3183
|
+
- printf("offset %" PRId64 " is not sector aligned\n",
|
3184
|
+
- ctx->offset);
|
3185
|
+
- g_free(ctx);
|
3186
|
+
- return 0;
|
3187
|
+
- }
|
3188
|
+
-
|
3189
|
+
- nr_iov = argc - optind;
|
3190
|
+
- ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, 0xab);
|
3191
|
+
- if (ctx->buf == NULL) {
|
3192
|
+
- g_free(ctx);
|
3193
|
+
- return 0;
|
3194
|
+
- }
|
3195
|
+
-
|
3196
|
+
- gettimeofday(&ctx->t1, NULL);
|
3197
|
+
- bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
|
3198
|
+
- ctx->qiov.size >> 9, aio_read_done, ctx);
|
3199
|
+
- return 0;
|
3200
|
+
-}
|
3201
|
+
-
|
3202
|
+
-static void aio_write_help(void)
|
3203
|
+
-{
|
3204
|
+
- printf(
|
3205
|
+
-"\n"
|
3206
|
+
-" asynchronously writes a range of bytes from the given offset source\n"
|
3207
|
+
-" from multiple buffers\n"
|
3208
|
+
-"\n"
|
3209
|
+
-" Example:\n"
|
3210
|
+
-" 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
|
3211
|
+
-"\n"
|
3212
|
+
-" Writes into a segment of the currently open file, using a buffer\n"
|
3213
|
+
-" filled with a set pattern (0xcdcdcdcd).\n"
|
3214
|
+
-" The write is performed asynchronously and the aio_flush command must be\n"
|
3215
|
+
-" used to ensure all outstanding aio requests have been completed.\n"
|
3216
|
+
-" -P, -- use different pattern to fill file\n"
|
3217
|
+
-" -C, -- report statistics in a machine parsable format\n"
|
3218
|
+
-" -q, -- quiet mode, do not show I/O statistics\n"
|
3219
|
+
-"\n");
|
3220
|
+
-}
|
3221
|
+
-
|
3222
|
+
-static int aio_write_f(BlockDriverState *bs, int argc, char **argv);
|
3223
|
+
-
|
3224
|
+
-static const cmdinfo_t aio_write_cmd = {
|
3225
|
+
- .name = "aio_write",
|
3226
|
+
- .cfunc = aio_write_f,
|
3227
|
+
- .argmin = 2,
|
3228
|
+
- .argmax = -1,
|
3229
|
+
- .args = "[-Cq] [-P pattern ] off len [len..]",
|
3230
|
+
- .oneline = "asynchronously writes a number of bytes",
|
3231
|
+
- .help = aio_write_help,
|
3232
|
+
-};
|
3233
|
+
-
|
3234
|
+
-static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
|
3235
|
+
-{
|
3236
|
+
- int nr_iov, c;
|
3237
|
+
- int pattern = 0xcd;
|
3238
|
+
- struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
|
3239
|
+
-
|
3240
|
+
- while ((c = getopt(argc, argv, "CqP:")) != EOF) {
|
3241
|
+
- switch (c) {
|
3242
|
+
- case 'C':
|
3243
|
+
- ctx->Cflag = 1;
|
3244
|
+
- break;
|
3245
|
+
- case 'q':
|
3246
|
+
- ctx->qflag = 1;
|
3247
|
+
- break;
|
3248
|
+
- case 'P':
|
3249
|
+
- pattern = parse_pattern(optarg);
|
3250
|
+
- if (pattern < 0) {
|
3251
|
+
- g_free(ctx);
|
3252
|
+
- return 0;
|
3253
|
+
- }
|
3254
|
+
- break;
|
3255
|
+
- default:
|
3256
|
+
- g_free(ctx);
|
3257
|
+
- return command_usage(&aio_write_cmd);
|
3258
|
+
- }
|
3259
|
+
- }
|
3260
|
+
-
|
3261
|
+
- if (optind > argc - 2) {
|
3262
|
+
- g_free(ctx);
|
3263
|
+
- return command_usage(&aio_write_cmd);
|
3264
|
+
- }
|
3265
|
+
-
|
3266
|
+
- ctx->offset = cvtnum(argv[optind]);
|
3267
|
+
- if (ctx->offset < 0) {
|
3268
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
3269
|
+
- g_free(ctx);
|
3270
|
+
- return 0;
|
3271
|
+
- }
|
3272
|
+
- optind++;
|
3273
|
+
-
|
3274
|
+
- if (ctx->offset & 0x1ff) {
|
3275
|
+
- printf("offset %" PRId64 " is not sector aligned\n",
|
3276
|
+
- ctx->offset);
|
3277
|
+
- g_free(ctx);
|
3278
|
+
- return 0;
|
3279
|
+
- }
|
3280
|
+
-
|
3281
|
+
- nr_iov = argc - optind;
|
3282
|
+
- ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, pattern);
|
3283
|
+
- if (ctx->buf == NULL) {
|
3284
|
+
- g_free(ctx);
|
3285
|
+
- return 0;
|
3286
|
+
- }
|
3287
|
+
-
|
3288
|
+
- gettimeofday(&ctx->t1, NULL);
|
3289
|
+
- bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
|
3290
|
+
- ctx->qiov.size >> 9, aio_write_done, ctx);
|
3291
|
+
- return 0;
|
3292
|
+
-}
|
3293
|
+
-
|
3294
|
+
-static int aio_flush_f(BlockDriverState *bs, int argc, char **argv)
|
3295
|
+
-{
|
3296
|
+
- bdrv_drain_all();
|
3297
|
+
- return 0;
|
3298
|
+
-}
|
3299
|
+
-
|
3300
|
+
-static const cmdinfo_t aio_flush_cmd = {
|
3301
|
+
- .name = "aio_flush",
|
3302
|
+
- .cfunc = aio_flush_f,
|
3303
|
+
- .oneline = "completes all outstanding aio requests"
|
3304
|
+
-};
|
3305
|
+
-
|
3306
|
+
-static int flush_f(BlockDriverState *bs, int argc, char **argv)
|
3307
|
+
-{
|
3308
|
+
- bdrv_flush(bs);
|
3309
|
+
- return 0;
|
3310
|
+
-}
|
3311
|
+
-
|
3312
|
+
-static const cmdinfo_t flush_cmd = {
|
3313
|
+
- .name = "flush",
|
3314
|
+
- .altname = "f",
|
3315
|
+
- .cfunc = flush_f,
|
3316
|
+
- .oneline = "flush all in-core file state to disk",
|
3317
|
+
-};
|
3318
|
+
-
|
3319
|
+
-static int truncate_f(BlockDriverState *bs, int argc, char **argv)
|
3320
|
+
-{
|
3321
|
+
- int64_t offset;
|
3322
|
+
- int ret;
|
3323
|
+
-
|
3324
|
+
- offset = cvtnum(argv[1]);
|
3325
|
+
- if (offset < 0) {
|
3326
|
+
- printf("non-numeric truncate argument -- %s\n", argv[1]);
|
3327
|
+
- return 0;
|
3328
|
+
- }
|
3329
|
+
-
|
3330
|
+
- ret = bdrv_truncate(bs, offset);
|
3331
|
+
- if (ret < 0) {
|
3332
|
+
- printf("truncate: %s\n", strerror(-ret));
|
3333
|
+
- return 0;
|
3334
|
+
- }
|
3335
|
+
-
|
3336
|
+
- return 0;
|
3337
|
+
-}
|
3338
|
+
-
|
3339
|
+
-static const cmdinfo_t truncate_cmd = {
|
3340
|
+
- .name = "truncate",
|
3341
|
+
- .altname = "t",
|
3342
|
+
- .cfunc = truncate_f,
|
3343
|
+
- .argmin = 1,
|
3344
|
+
- .argmax = 1,
|
3345
|
+
- .args = "off",
|
3346
|
+
- .oneline = "truncates the current file at the given offset",
|
3347
|
+
-};
|
3348
|
+
-
|
3349
|
+
-static int length_f(BlockDriverState *bs, int argc, char **argv)
|
3350
|
+
-{
|
3351
|
+
- int64_t size;
|
3352
|
+
- char s1[64];
|
3353
|
+
-
|
3354
|
+
- size = bdrv_getlength(bs);
|
3355
|
+
- if (size < 0) {
|
3356
|
+
- printf("getlength: %s\n", strerror(-size));
|
3357
|
+
- return 0;
|
3358
|
+
- }
|
3359
|
+
-
|
3360
|
+
- cvtstr(size, s1, sizeof(s1));
|
3361
|
+
- printf("%s\n", s1);
|
3362
|
+
- return 0;
|
3363
|
+
-}
|
3364
|
+
-
|
3365
|
+
-
|
3366
|
+
-static const cmdinfo_t length_cmd = {
|
3367
|
+
- .name = "length",
|
3368
|
+
- .altname = "l",
|
3369
|
+
- .cfunc = length_f,
|
3370
|
+
- .oneline = "gets the length of the current file",
|
3371
|
+
-};
|
3372
|
+
-
|
3373
|
+
-
|
3374
|
+
-static int info_f(BlockDriverState *bs, int argc, char **argv)
|
3375
|
+
-{
|
3376
|
+
- BlockDriverInfo bdi;
|
3377
|
+
- ImageInfoSpecific *spec_info;
|
3378
|
+
- char s1[64], s2[64];
|
3379
|
+
- int ret;
|
3380
|
+
-
|
3381
|
+
- if (bs->drv && bs->drv->format_name) {
|
3382
|
+
- printf("format name: %s\n", bs->drv->format_name);
|
3383
|
+
- }
|
3384
|
+
- if (bs->drv && bs->drv->protocol_name) {
|
3385
|
+
- printf("format name: %s\n", bs->drv->protocol_name);
|
3386
|
+
- }
|
3387
|
+
-
|
3388
|
+
- ret = bdrv_get_info(bs, &bdi);
|
3389
|
+
- if (ret) {
|
3390
|
+
- return 0;
|
3391
|
+
- }
|
3392
|
+
-
|
3393
|
+
- cvtstr(bdi.cluster_size, s1, sizeof(s1));
|
3394
|
+
- cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
|
3395
|
+
-
|
3396
|
+
- printf("cluster size: %s\n", s1);
|
3397
|
+
- printf("vm state offset: %s\n", s2);
|
3398
|
+
-
|
3399
|
+
- spec_info = bdrv_get_specific_info(bs);
|
3400
|
+
- if (spec_info) {
|
3401
|
+
- printf("Format specific information:\n");
|
3402
|
+
- bdrv_image_info_specific_dump(fprintf, stdout, spec_info);
|
3403
|
+
- qapi_free_ImageInfoSpecific(spec_info);
|
3404
|
+
- }
|
3405
|
+
-
|
3406
|
+
- return 0;
|
3407
|
+
-}
|
3408
|
+
-
|
3409
|
+
-
|
3410
|
+
-
|
3411
|
+
-static const cmdinfo_t info_cmd = {
|
3412
|
+
- .name = "info",
|
3413
|
+
- .altname = "i",
|
3414
|
+
- .cfunc = info_f,
|
3415
|
+
- .oneline = "prints information about the current file",
|
3416
|
+
-};
|
3417
|
+
-
|
3418
|
+
-static void discard_help(void)
|
3419
|
+
-{
|
3420
|
+
- printf(
|
3421
|
+
-"\n"
|
3422
|
+
-" discards a range of bytes from the given offset\n"
|
3423
|
+
-"\n"
|
3424
|
+
-" Example:\n"
|
3425
|
+
-" 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
|
3426
|
+
-"\n"
|
3427
|
+
-" Discards a segment of the currently open file.\n"
|
3428
|
+
-" -C, -- report statistics in a machine parsable format\n"
|
3429
|
+
-" -q, -- quiet mode, do not show I/O statistics\n"
|
3430
|
+
-"\n");
|
3431
|
+
-}
|
3432
|
+
-
|
3433
|
+
-static int discard_f(BlockDriverState *bs, int argc, char **argv);
|
3434
|
+
-
|
3435
|
+
-static const cmdinfo_t discard_cmd = {
|
3436
|
+
- .name = "discard",
|
3437
|
+
- .altname = "d",
|
3438
|
+
- .cfunc = discard_f,
|
3439
|
+
- .argmin = 2,
|
3440
|
+
- .argmax = -1,
|
3441
|
+
- .args = "[-Cq] off len",
|
3442
|
+
- .oneline = "discards a number of bytes at a specified offset",
|
3443
|
+
- .help = discard_help,
|
3444
|
+
-};
|
3445
|
+
-
|
3446
|
+
-static int discard_f(BlockDriverState *bs, int argc, char **argv)
|
3447
|
+
-{
|
3448
|
+
- struct timeval t1, t2;
|
3449
|
+
- int Cflag = 0, qflag = 0;
|
3450
|
+
- int c, ret;
|
3451
|
+
- int64_t offset;
|
3452
|
+
- int count;
|
3453
|
+
-
|
3454
|
+
- while ((c = getopt(argc, argv, "Cq")) != EOF) {
|
3455
|
+
- switch (c) {
|
3456
|
+
- case 'C':
|
3457
|
+
- Cflag = 1;
|
3458
|
+
- break;
|
3459
|
+
- case 'q':
|
3460
|
+
- qflag = 1;
|
3461
|
+
- break;
|
3462
|
+
- default:
|
3463
|
+
- return command_usage(&discard_cmd);
|
3464
|
+
- }
|
3465
|
+
- }
|
3466
|
+
-
|
3467
|
+
- if (optind != argc - 2) {
|
3468
|
+
- return command_usage(&discard_cmd);
|
3469
|
+
- }
|
3470
|
+
-
|
3471
|
+
- offset = cvtnum(argv[optind]);
|
3472
|
+
- if (offset < 0) {
|
3473
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
3474
|
+
- return 0;
|
3475
|
+
- }
|
3476
|
+
-
|
3477
|
+
- optind++;
|
3478
|
+
- count = cvtnum(argv[optind]);
|
3479
|
+
- if (count < 0) {
|
3480
|
+
- printf("non-numeric length argument -- %s\n", argv[optind]);
|
3481
|
+
- return 0;
|
3482
|
+
- }
|
3483
|
+
-
|
3484
|
+
- gettimeofday(&t1, NULL);
|
3485
|
+
- ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
|
3486
|
+
- count >> BDRV_SECTOR_BITS);
|
3487
|
+
- gettimeofday(&t2, NULL);
|
3488
|
+
-
|
3489
|
+
- if (ret < 0) {
|
3490
|
+
- printf("discard failed: %s\n", strerror(-ret));
|
3491
|
+
- goto out;
|
3492
|
+
- }
|
3493
|
+
-
|
3494
|
+
- /* Finally, report back -- -C gives a parsable format */
|
3495
|
+
- if (!qflag) {
|
3496
|
+
- t2 = tsub(t2, t1);
|
3497
|
+
- print_report("discard", &t2, offset, count, count, 1, Cflag);
|
3498
|
+
- }
|
3499
|
+
-
|
3500
|
+
-out:
|
3501
|
+
- return 0;
|
3502
|
+
-}
|
3503
|
+
-
|
3504
|
+
-static int alloc_f(BlockDriverState *bs, int argc, char **argv)
|
3505
|
+
-{
|
3506
|
+
- int64_t offset, sector_num;
|
3507
|
+
- int nb_sectors, remaining;
|
3508
|
+
- char s1[64];
|
3509
|
+
- int num, sum_alloc;
|
3510
|
+
- int ret;
|
3511
|
+
-
|
3512
|
+
- offset = cvtnum(argv[1]);
|
3513
|
+
- if (offset < 0) {
|
3514
|
+
- printf("non-numeric offset argument -- %s\n", argv[1]);
|
3515
|
+
- return 0;
|
3516
|
+
- } else if (offset & 0x1ff) {
|
3517
|
+
- printf("offset %" PRId64 " is not sector aligned\n",
|
3518
|
+
- offset);
|
3519
|
+
- return 0;
|
3520
|
+
- }
|
3521
|
+
-
|
3522
|
+
- if (argc == 3) {
|
3523
|
+
- nb_sectors = cvtnum(argv[2]);
|
3524
|
+
- if (nb_sectors < 0) {
|
3525
|
+
- printf("non-numeric length argument -- %s\n", argv[2]);
|
3526
|
+
- return 0;
|
3527
|
+
- }
|
3528
|
+
- } else {
|
3529
|
+
- nb_sectors = 1;
|
3530
|
+
- }
|
3531
|
+
-
|
3532
|
+
- remaining = nb_sectors;
|
3533
|
+
- sum_alloc = 0;
|
3534
|
+
- sector_num = offset >> 9;
|
3535
|
+
- while (remaining) {
|
3536
|
+
- ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
|
3537
|
+
- if (ret < 0) {
|
3538
|
+
- printf("is_allocated failed: %s\n", strerror(-ret));
|
3539
|
+
- return 0;
|
3540
|
+
- }
|
3541
|
+
- sector_num += num;
|
3542
|
+
- remaining -= num;
|
3543
|
+
- if (ret) {
|
3544
|
+
- sum_alloc += num;
|
3545
|
+
- }
|
3546
|
+
- if (num == 0) {
|
3547
|
+
- nb_sectors -= remaining;
|
3548
|
+
- remaining = 0;
|
3549
|
+
- }
|
3550
|
+
- }
|
3551
|
+
-
|
3552
|
+
- cvtstr(offset, s1, sizeof(s1));
|
3553
|
+
-
|
3554
|
+
- printf("%d/%d sectors allocated at offset %s\n",
|
3555
|
+
- sum_alloc, nb_sectors, s1);
|
3556
|
+
- return 0;
|
3557
|
+
-}
|
3558
|
+
-
|
3559
|
+
-static const cmdinfo_t alloc_cmd = {
|
3560
|
+
- .name = "alloc",
|
3561
|
+
- .altname = "a",
|
3562
|
+
- .argmin = 1,
|
3563
|
+
- .argmax = 2,
|
3564
|
+
- .cfunc = alloc_f,
|
3565
|
+
- .args = "off [sectors]",
|
3566
|
+
- .oneline = "checks if a sector is present in the file",
|
3567
|
+
-};
|
3568
|
+
-
|
3569
|
+
-static int map_f(BlockDriverState *bs, int argc, char **argv)
|
3570
|
+
-{
|
3571
|
+
- int64_t offset;
|
3572
|
+
- int64_t nb_sectors;
|
3573
|
+
- char s1[64];
|
3574
|
+
- int num, num_checked;
|
3575
|
+
- int ret;
|
3576
|
+
- const char *retstr;
|
3577
|
+
-
|
3578
|
+
- offset = 0;
|
3579
|
+
- nb_sectors = bs->total_sectors;
|
3580
|
+
-
|
3581
|
+
- do {
|
3582
|
+
- num_checked = MIN(nb_sectors, INT_MAX);
|
3583
|
+
- ret = bdrv_is_allocated(bs, offset, num_checked, &num);
|
3584
|
+
- retstr = ret ? " allocated" : "not allocated";
|
3585
|
+
- cvtstr(offset << 9ULL, s1, sizeof(s1));
|
3586
|
+
- printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
|
3587
|
+
- offset << 9ULL, num, num_checked, retstr, s1, ret);
|
3588
|
+
-
|
3589
|
+
- offset += num;
|
3590
|
+
- nb_sectors -= num;
|
3591
|
+
- } while (offset < bs->total_sectors);
|
3592
|
+
-
|
3593
|
+
- return 0;
|
3594
|
+
-}
|
3595
|
+
-
|
3596
|
+
-static const cmdinfo_t map_cmd = {
|
3597
|
+
- .name = "map",
|
3598
|
+
- .argmin = 0,
|
3599
|
+
- .argmax = 0,
|
3600
|
+
- .cfunc = map_f,
|
3601
|
+
- .args = "",
|
3602
|
+
- .oneline = "prints the allocated areas of a file",
|
3603
|
+
-};
|
3604
|
+
-
|
3605
|
+
-static int break_f(BlockDriverState *bs, int argc, char **argv)
|
3606
|
+
-{
|
3607
|
+
- int ret;
|
3608
|
+
-
|
3609
|
+
- ret = bdrv_debug_breakpoint(bs, argv[1], argv[2]);
|
3610
|
+
- if (ret < 0) {
|
3611
|
+
- printf("Could not set breakpoint: %s\n", strerror(-ret));
|
3612
|
+
- }
|
3613
|
+
-
|
3614
|
+
- return 0;
|
3615
|
+
-}
|
3616
|
+
-
|
3617
|
+
-static const cmdinfo_t break_cmd = {
|
3618
|
+
- .name = "break",
|
3619
|
+
- .argmin = 2,
|
3620
|
+
- .argmax = 2,
|
3621
|
+
- .cfunc = break_f,
|
3622
|
+
- .args = "event tag",
|
3623
|
+
- .oneline = "sets a breakpoint on event and tags the stopped "
|
3624
|
+
- "request as tag",
|
3625
|
+
-};
|
3626
|
+
-
|
3627
|
+
-static int resume_f(BlockDriverState *bs, int argc, char **argv)
|
3628
|
+
-{
|
3629
|
+
- int ret;
|
3630
|
+
-
|
3631
|
+
- ret = bdrv_debug_resume(bs, argv[1]);
|
3632
|
+
- if (ret < 0) {
|
3633
|
+
- printf("Could not resume request: %s\n", strerror(-ret));
|
3634
|
+
- }
|
3635
|
+
-
|
3636
|
+
- return 0;
|
3637
|
+
-}
|
3638
|
+
-
|
3639
|
+
-static const cmdinfo_t resume_cmd = {
|
3640
|
+
- .name = "resume",
|
3641
|
+
- .argmin = 1,
|
3642
|
+
- .argmax = 1,
|
3643
|
+
- .cfunc = resume_f,
|
3644
|
+
- .args = "tag",
|
3645
|
+
- .oneline = "resumes the request tagged as tag",
|
3646
|
+
-};
|
3647
|
+
-
|
3648
|
+
-static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
|
3649
|
+
-{
|
3650
|
+
- while (!bdrv_debug_is_suspended(bs, argv[1])) {
|
3651
|
+
- qemu_aio_wait();
|
3652
|
+
- }
|
3653
|
+
-
|
3654
|
+
- return 0;
|
3655
|
+
-}
|
3656
|
+
-
|
3657
|
+
-static const cmdinfo_t wait_break_cmd = {
|
3658
|
+
- .name = "wait_break",
|
3659
|
+
- .argmin = 1,
|
3660
|
+
- .argmax = 1,
|
3661
|
+
- .cfunc = wait_break_f,
|
3662
|
+
- .args = "tag",
|
3663
|
+
- .oneline = "waits for the suspension of a request",
|
3664
|
+
-};
|
3665
|
+
-
|
3666
|
+
-static int abort_f(BlockDriverState *bs, int argc, char **argv)
|
3667
|
+
-{
|
3668
|
+
- abort();
|
3669
|
+
-}
|
3670
|
+
-
|
3671
|
+
-static const cmdinfo_t abort_cmd = {
|
3672
|
+
- .name = "abort",
|
3673
|
+
- .cfunc = abort_f,
|
3674
|
+
- .flags = CMD_NOFILE_OK,
|
3675
|
+
- .oneline = "simulate a program crash using abort(3)",
|
3676
|
+
-};
|
3677
|
+
+extern int qemuio_misalign;
|
3678
|
+
|
3679
|
+
static int close_f(BlockDriverState *bs, int argc, char **argv)
|
3680
|
+
{
|
3681
|
+
@@ -1801,45 +48,6 @@ static const cmdinfo_t close_cmd = {
|
3682
|
+
.oneline = "close the current open file",
|
3683
|
+
};
|
3684
|
+
|
3685
|
+
-static void sleep_cb(void *opaque)
|
3686
|
+
-{
|
3687
|
+
- bool *expired = opaque;
|
3688
|
+
- *expired = true;
|
3689
|
+
-}
|
3690
|
+
-
|
3691
|
+
-static int sleep_f(BlockDriverState *bs, int argc, char **argv)
|
3692
|
+
-{
|
3693
|
+
- char *endptr;
|
3694
|
+
- long ms;
|
3695
|
+
- struct QEMUTimer *timer;
|
3696
|
+
- bool expired = false;
|
3697
|
+
-
|
3698
|
+
- ms = strtol(argv[1], &endptr, 0);
|
3699
|
+
- if (ms < 0 || *endptr != '\0') {
|
3700
|
+
- printf("%s is not a valid number\n", argv[1]);
|
3701
|
+
- return 0;
|
3702
|
+
- }
|
3703
|
+
-
|
3704
|
+
- timer = qemu_new_timer_ns(host_clock, sleep_cb, &expired);
|
3705
|
+
- qemu_mod_timer(timer, qemu_get_clock_ns(host_clock) + SCALE_MS * ms);
|
3706
|
+
-
|
3707
|
+
- while (!expired) {
|
3708
|
+
- main_loop_wait(false);
|
3709
|
+
- }
|
3710
|
+
-
|
3711
|
+
- qemu_free_timer(timer);
|
3712
|
+
-
|
3713
|
+
- return 0;
|
3714
|
+
-}
|
3715
|
+
-
|
3716
|
+
-static const cmdinfo_t sleep_cmd = {
|
3717
|
+
- .name = "sleep",
|
3718
|
+
- .argmin = 1,
|
3719
|
+
- .argmax = 1,
|
3720
|
+
- .cfunc = sleep_f,
|
3721
|
+
- .flags = CMD_NOFILE_OK,
|
3722
|
+
- .oneline = "waits for the given value in milliseconds",
|
3723
|
+
-};
|
3724
|
+
|
3725
|
+
static int openfile(char *name, int flags, int growable, QDict *opts)
|
3726
|
+
{
|
3727
|
+
@@ -1962,18 +170,6 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
|
3728
|
+
return openfile(argv[optind], flags, growable, opts);
|
3729
|
+
}
|
3730
|
+
|
3731
|
+
-static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
|
3732
|
+
-{
|
3733
|
+
- if (ct->flags & CMD_FLAG_GLOBAL) {
|
3734
|
+
- return 1;
|
3735
|
+
- }
|
3736
|
+
- if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
|
3737
|
+
- fprintf(stderr, "no file open, try 'help open'\n");
|
3738
|
+
- return 0;
|
3739
|
+
- }
|
3740
|
+
- return 1;
|
3741
|
+
-}
|
3742
|
+
-
|
3743
|
+
static void usage(const char *name)
|
3744
|
+
{
|
3745
|
+
printf(
|
3746
|
+
@@ -2049,7 +245,7 @@ int main(int argc, char **argv)
|
3747
|
+
readonly = 1;
|
3748
|
+
break;
|
3749
|
+
case 'm':
|
3750
|
+
- misalign = 1;
|
3751
|
+
+ qemuio_misalign = 1;
|
3752
|
+
break;
|
3753
|
+
case 'g':
|
3754
|
+
growable = 1;
|
3755
|
+
@@ -2090,31 +286,8 @@ int main(int argc, char **argv)
|
3756
|
+
|
3757
|
+
/* initialize commands */
|
3758
|
+
quit_init();
|
3759
|
+
- help_init();
|
3760
|
+
add_command(&open_cmd);
|
3761
|
+
add_command(&close_cmd);
|
3762
|
+
- add_command(&read_cmd);
|
3763
|
+
- add_command(&readv_cmd);
|
3764
|
+
- add_command(&write_cmd);
|
3765
|
+
- add_command(&writev_cmd);
|
3766
|
+
- add_command(&multiwrite_cmd);
|
3767
|
+
- add_command(&aio_read_cmd);
|
3768
|
+
- add_command(&aio_write_cmd);
|
3769
|
+
- add_command(&aio_flush_cmd);
|
3770
|
+
- add_command(&flush_cmd);
|
3771
|
+
- add_command(&truncate_cmd);
|
3772
|
+
- add_command(&length_cmd);
|
3773
|
+
- add_command(&info_cmd);
|
3774
|
+
- add_command(&discard_cmd);
|
3775
|
+
- add_command(&alloc_cmd);
|
3776
|
+
- add_command(&map_cmd);
|
3777
|
+
- add_command(&break_cmd);
|
3778
|
+
- add_command(&resume_cmd);
|
3779
|
+
- add_command(&wait_break_cmd);
|
3780
|
+
- add_command(&abort_cmd);
|
3781
|
+
- add_command(&sleep_cmd);
|
3782
|
+
-
|
3783
|
+
- add_check_command(init_check_command);
|
3784
|
+
|
3785
|
+
/* open the device */
|
3786
|
+
if (!readonly) {
|
3787
|
+
--
|
3788
|
+
1.8.3.1
|
3789
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
From 883449501b5d87002bb01c2a060cf650acf45d9a Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:34 +0100
|
4
|
+
Subject: [PATCH 15/27] qemu-io: Use the qemu version for -V
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-16-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68442
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 15/21] qemu-io: Use the qemu version for -V
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
From: Kevin Wolf <kwolf@redhat.com>
|
16
|
+
|
17
|
+
Always printing 0.0.1 and never updating the version number wasn't very
|
18
|
+
useful. qemu-io is released with qemu, so using the same version number
|
19
|
+
makes most sense.
|
20
|
+
|
21
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
22
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
23
|
+
(cherry picked from commit 02da386a2d7a020e80b0aed64769efa9dd42072a)
|
24
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
qemu-io.c | 4 +---
|
28
|
+
1 file changed, 1 insertion(+), 3 deletions(-)
|
29
|
+
|
30
|
+
diff --git a/qemu-io.c b/qemu-io.c
|
31
|
+
index e685808..16b2d8a 100644
|
32
|
+
--- a/qemu-io.c
|
33
|
+
+++ b/qemu-io.c
|
34
|
+
|
35
|
+
#include "trace/control.h"
|
36
|
+
#include "qemu/timer.h"
|
37
|
+
|
38
|
+
-#define VERSION "0.0.1"
|
39
|
+
-
|
40
|
+
#define CMD_NOFILE_OK 0x01
|
41
|
+
|
42
|
+
char *progname;
|
43
|
+
@@ -418,7 +416,7 @@ int main(int argc, char **argv)
|
44
|
+
}
|
45
|
+
break;
|
46
|
+
case 'V':
|
47
|
+
- printf("%s version %s\n", progname, VERSION);
|
48
|
+
+ printf("%s version %s\n", progname, QEMU_VERSION);
|
49
|
+
exit(0);
|
50
|
+
case 'h':
|
51
|
+
usage(progname);
|
52
|
+
--
|
53
|
+
1.8.3.1
|
54
|
+
|
@@ -0,0 +1,360 @@
|
|
1
|
+
From a5226789eaaedf06f50f2faf14b506c17deb5435 Mon Sep 17 00:00:00 2001
|
2
|
+
From: John Snow <jsnow@redhat.com>
|
3
|
+
Date: Mon, 23 Nov 2015 17:38:37 +0100
|
4
|
+
Subject: [PATCH 18/27] qemu-io: fix cvtnum lval types
|
5
|
+
|
6
|
+
RH-Author: John Snow <jsnow@redhat.com>
|
7
|
+
Message-id: <1448300320-7772-19-git-send-email-jsnow@redhat.com>
|
8
|
+
Patchwork-id: 68445
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 18/21] qemu-io: fix cvtnum lval types
|
10
|
+
Bugzilla: 1272523
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
|
15
|
+
cvtnum() returns int64_t: we should not be storing this
|
16
|
+
result inside of an int.
|
17
|
+
|
18
|
+
In a few cases, we need an extra sprinkling of error handling
|
19
|
+
where we expect to pass this number on towards a function that
|
20
|
+
expects something smaller than int64_t.
|
21
|
+
|
22
|
+
Reported-by: Max Reitz <mreitz@redhat.com>
|
23
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
24
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
25
|
+
(cherry picked from commit 9b0beaf3de1396a23d5c287283e6f36c4b5d4385)
|
26
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
27
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
28
|
+
|
29
|
+
Conflicts:
|
30
|
+
qemu-io-cmds.c:
|
31
|
+
- Upstream uses blk_xxx commands, while downstream uses bdrv_xxx
|
32
|
+
- Fixes to sigraise are not backported.
|
33
|
+
|
34
|
+
Signed-off-by: John Snow <jsnow@redhat.com>
|
35
|
+
---
|
36
|
+
qemu-io-cmds.c | 119 ++++++++++++++++++++++++++++++++++++++++-----------------
|
37
|
+
1 file changed, 84 insertions(+), 35 deletions(-)
|
38
|
+
|
39
|
+
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
40
|
+
index 1f21ce9..95345fe 100644
|
41
|
+
--- a/qemu-io-cmds.c
|
42
|
+
+++ b/qemu-io-cmds.c
|
43
|
+
@@ -282,9 +282,10 @@ static void qemu_io_free(void *p)
|
44
|
+
qemu_vfree(p);
|
45
|
+
}
|
46
|
+
|
47
|
+
-static void dump_buffer(const void *buffer, int64_t offset, int len)
|
48
|
+
+static void dump_buffer(const void *buffer, int64_t offset, int64_t len)
|
49
|
+
{
|
50
|
+
- int i, j;
|
51
|
+
+ uint64_t i;
|
52
|
+
+ int j;
|
53
|
+
const uint8_t *p;
|
54
|
+
|
55
|
+
for (i = 0, p = buffer; i < len; i += 16) {
|
56
|
+
@@ -307,7 +308,7 @@ static void dump_buffer(const void *buffer, int64_t offset, int len)
|
57
|
+
}
|
58
|
+
|
59
|
+
static void print_report(const char *op, struct timeval *t, int64_t offset,
|
60
|
+
- int count, int total, int cnt, int Cflag)
|
61
|
+
+ int64_t count, int64_t total, int cnt, int Cflag)
|
62
|
+
{
|
63
|
+
char s1[64], s2[64], ts[64];
|
64
|
+
|
65
|
+
@@ -315,12 +316,12 @@ static void print_report(const char *op, struct timeval *t, int64_t offset,
|
66
|
+
if (!Cflag) {
|
67
|
+
cvtstr((double)total, s1, sizeof(s1));
|
68
|
+
cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
|
69
|
+
- printf("%s %d/%d bytes at offset %" PRId64 "\n",
|
70
|
+
+ printf("%s %"PRId64"/%"PRId64" bytes at offset %" PRId64 "\n",
|
71
|
+
op, total, count, offset);
|
72
|
+
printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
|
73
|
+
s1, cnt, ts, s2, tdiv((double)cnt, *t));
|
74
|
+
} else {/* bytes,ops,time,bytes/sec,ops/sec */
|
75
|
+
- printf("%d,%d,%s,%.3f,%.3f\n",
|
76
|
+
+ printf("%"PRId64",%d,%s,%.3f,%.3f\n",
|
77
|
+
total, cnt, ts,
|
78
|
+
tdiv((double)total, *t),
|
79
|
+
tdiv((double)cnt, *t));
|
80
|
+
@@ -381,11 +382,15 @@ fail:
|
81
|
+
return buf;
|
82
|
+
}
|
83
|
+
|
84
|
+
-static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
85
|
+
- int *total)
|
86
|
+
+static int do_read(BlockDriverState *bs, char *buf, int64_t offset,
|
87
|
+
+ int64_t count, int64_t *total)
|
88
|
+
{
|
89
|
+
int ret;
|
90
|
+
|
91
|
+
+ if (count >> 9 > INT_MAX) {
|
92
|
+
+ return -ERANGE;
|
93
|
+
+ }
|
94
|
+
+
|
95
|
+
ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
|
96
|
+
if (ret < 0) {
|
97
|
+
return ret;
|
98
|
+
@@ -394,11 +399,15 @@ static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
99
|
+
return 1;
|
100
|
+
}
|
101
|
+
|
102
|
+
-static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
103
|
+
- int *total)
|
104
|
+
+static int do_write(BlockDriverState *bs, char *buf, int64_t offset,
|
105
|
+
+ int64_t count, int64_t *total)
|
106
|
+
{
|
107
|
+
int ret;
|
108
|
+
|
109
|
+
+ if (count >> 9 > INT_MAX) {
|
110
|
+
+ return -ERANGE;
|
111
|
+
+ }
|
112
|
+
+
|
113
|
+
ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
|
114
|
+
if (ret < 0) {
|
115
|
+
return ret;
|
116
|
+
@@ -407,9 +416,13 @@ static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
117
|
+
return 1;
|
118
|
+
}
|
119
|
+
|
120
|
+
-static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
121
|
+
- int *total)
|
122
|
+
+static int do_pread(BlockDriverState *bs, char *buf, int64_t offset,
|
123
|
+
+ int64_t count, int64_t *total)
|
124
|
+
{
|
125
|
+
+ if (count > INT_MAX) {
|
126
|
+
+ return -ERANGE;
|
127
|
+
+ }
|
128
|
+
+
|
129
|
+
*total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
|
130
|
+
if (*total < 0) {
|
131
|
+
return *total;
|
132
|
+
@@ -417,9 +430,13 @@ static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
133
|
+
return 1;
|
134
|
+
}
|
135
|
+
|
136
|
+
-static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
137
|
+
- int *total)
|
138
|
+
+static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset,
|
139
|
+
+ int64_t count, int64_t *total)
|
140
|
+
{
|
141
|
+
+ if (count > INT_MAX) {
|
142
|
+
+ return -ERANGE;
|
143
|
+
+ }
|
144
|
+
+
|
145
|
+
*total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
|
146
|
+
if (*total < 0) {
|
147
|
+
return *total;
|
148
|
+
@@ -430,8 +447,8 @@ static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
|
149
|
+
typedef struct {
|
150
|
+
BlockDriverState *bs;
|
151
|
+
int64_t offset;
|
152
|
+
- int count;
|
153
|
+
- int *total;
|
154
|
+
+ int64_t count;
|
155
|
+
+ int64_t *total;
|
156
|
+
int ret;
|
157
|
+
bool done;
|
158
|
+
} CoWriteZeroes;
|
159
|
+
@@ -451,8 +468,8 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque)
|
160
|
+
*data->total = data->count;
|
161
|
+
}
|
162
|
+
|
163
|
+
-static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
|
164
|
+
- int *total)
|
165
|
+
+static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset,
|
166
|
+
+ int64_t count, int64_t *total)
|
167
|
+
{
|
168
|
+
Coroutine *co;
|
169
|
+
CoWriteZeroes data = {
|
170
|
+
@@ -463,6 +480,10 @@ static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
|
171
|
+
.done = false,
|
172
|
+
};
|
173
|
+
|
174
|
+
+ if (count >> BDRV_SECTOR_BITS > INT_MAX) {
|
175
|
+
+ return -ERANGE;
|
176
|
+
+ }
|
177
|
+
+
|
178
|
+
co = qemu_coroutine_create(co_write_zeroes_entry);
|
179
|
+
qemu_coroutine_enter(co, &data);
|
180
|
+
while (!data.done) {
|
181
|
+
@@ -476,10 +497,14 @@ static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
|
182
|
+
}
|
183
|
+
|
184
|
+
static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
|
185
|
+
- int count, int *total)
|
186
|
+
+ int64_t count, int64_t *total)
|
187
|
+
{
|
188
|
+
int ret;
|
189
|
+
|
190
|
+
+ if (count >> 9 > INT_MAX) {
|
191
|
+
+ return -ERANGE;
|
192
|
+
+ }
|
193
|
+
+
|
194
|
+
ret = bdrv_write_compressed(bs, offset >> 9, (uint8_t *)buf, count >> 9);
|
195
|
+
if (ret < 0) {
|
196
|
+
return ret;
|
197
|
+
@@ -489,8 +514,12 @@ static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
|
198
|
+
}
|
199
|
+
|
200
|
+
static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
|
201
|
+
- int count, int *total)
|
202
|
+
+ int64_t count, int64_t *total)
|
203
|
+
{
|
204
|
+
+ if (count > INT_MAX) {
|
205
|
+
+ return -ERANGE;
|
206
|
+
+ }
|
207
|
+
+
|
208
|
+
*total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
|
209
|
+
if (*total < 0) {
|
210
|
+
return *total;
|
211
|
+
@@ -499,8 +528,12 @@ static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
|
212
|
+
}
|
213
|
+
|
214
|
+
static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
|
215
|
+
- int count, int *total)
|
216
|
+
+ int64_t count, int64_t *total)
|
217
|
+
{
|
218
|
+
+ if (count > INT_MAX) {
|
219
|
+
+ return -ERANGE;
|
220
|
+
+ }
|
221
|
+
+
|
222
|
+
*total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
|
223
|
+
if (*total < 0) {
|
224
|
+
return *total;
|
225
|
+
@@ -630,10 +663,11 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
|
226
|
+
int c, cnt;
|
227
|
+
char *buf;
|
228
|
+
int64_t offset;
|
229
|
+
- int count;
|
230
|
+
+ int64_t count;
|
231
|
+
/* Some compilers get confused and warn if this is not initialized. */
|
232
|
+
- int total = 0;
|
233
|
+
- int pattern = 0, pattern_offset = 0, pattern_count = 0;
|
234
|
+
+ int64_t total = 0;
|
235
|
+
+ int pattern = 0;
|
236
|
+
+ int64_t pattern_offset = 0, pattern_count = 0;
|
237
|
+
|
238
|
+
while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
|
239
|
+
switch (c) {
|
240
|
+
@@ -700,6 +734,10 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
|
241
|
+
if (count < 0) {
|
242
|
+
printf("non-numeric length argument -- %s\n", argv[optind]);
|
243
|
+
return 0;
|
244
|
+
+ } else if (count > SIZE_MAX) {
|
245
|
+
+ printf("length cannot exceed %" PRIu64 ", given %s\n",
|
246
|
+
+ (uint64_t) SIZE_MAX, argv[optind]);
|
247
|
+
+ return 0;
|
248
|
+
}
|
249
|
+
|
250
|
+
if (!Pflag && (lflag || sflag)) {
|
251
|
+
@@ -722,7 +760,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
|
252
|
+
return 0;
|
253
|
+
}
|
254
|
+
if (count & 0x1ff) {
|
255
|
+
- printf("count %d is not sector aligned\n",
|
256
|
+
+ printf("count %"PRId64" is not sector aligned\n",
|
257
|
+
count);
|
258
|
+
return 0;
|
259
|
+
}
|
260
|
+
@@ -750,7 +788,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
|
261
|
+
memset(cmp_buf, pattern, pattern_count);
|
262
|
+
if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
|
263
|
+
printf("Pattern verification failed at offset %"
|
264
|
+
- PRId64 ", %d bytes\n",
|
265
|
+
+ PRId64 ", %"PRId64" bytes\n",
|
266
|
+
offset + pattern_offset, pattern_count);
|
267
|
+
}
|
268
|
+
g_free(cmp_buf);
|
269
|
+
@@ -945,9 +983,9 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
|
270
|
+
int c, cnt;
|
271
|
+
char *buf = NULL;
|
272
|
+
int64_t offset;
|
273
|
+
- int count;
|
274
|
+
+ int64_t count;
|
275
|
+
/* Some compilers get confused and warn if this is not initialized. */
|
276
|
+
- int total = 0;
|
277
|
+
+ int64_t total = 0;
|
278
|
+
int pattern = 0xcd;
|
279
|
+
|
280
|
+
while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) {
|
281
|
+
@@ -1007,6 +1045,10 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
|
282
|
+
if (count < 0) {
|
283
|
+
printf("non-numeric length argument -- %s\n", argv[optind]);
|
284
|
+
return 0;
|
285
|
+
+ } else if (count > SIZE_MAX) {
|
286
|
+
+ printf("length cannot exceed %" PRIu64 ", given %s\n",
|
287
|
+
+ (uint64_t) SIZE_MAX, argv[optind]);
|
288
|
+
+ return 0;
|
289
|
+
}
|
290
|
+
|
291
|
+
if (!pflag) {
|
292
|
+
@@ -1017,7 +1059,7 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
|
293
|
+
}
|
294
|
+
|
295
|
+
if (count & 0x1ff) {
|
296
|
+
- printf("count %d is not sector aligned\n",
|
297
|
+
+ printf("count %"PRId64" is not sector aligned\n",
|
298
|
+
count);
|
299
|
+
return 0;
|
300
|
+
}
|
301
|
+
@@ -1752,8 +1794,7 @@ static int discard_f(BlockDriverState *bs, int argc, char **argv)
|
302
|
+
struct timeval t1, t2;
|
303
|
+
int Cflag = 0, qflag = 0;
|
304
|
+
int c, ret;
|
305
|
+
- int64_t offset;
|
306
|
+
- int count;
|
307
|
+
+ int64_t offset, count;
|
308
|
+
|
309
|
+
while ((c = getopt(argc, argv, "Cq")) != EOF) {
|
310
|
+
switch (c) {
|
311
|
+
@@ -1783,6 +1824,11 @@ static int discard_f(BlockDriverState *bs, int argc, char **argv)
|
312
|
+
if (count < 0) {
|
313
|
+
printf("non-numeric length argument -- %s\n", argv[optind]);
|
314
|
+
return 0;
|
315
|
+
+ } else if (count >> BDRV_SECTOR_BITS > INT_MAX) {
|
316
|
+
+ printf("length cannot exceed %"PRIu64", given %s\n",
|
317
|
+
+ (uint64_t)INT_MAX << BDRV_SECTOR_BITS,
|
318
|
+
+ argv[optind]);
|
319
|
+
+ return 0;
|
320
|
+
}
|
321
|
+
|
322
|
+
gettimeofday(&t1, NULL);
|
323
|
+
@@ -1807,11 +1853,10 @@ out:
|
324
|
+
|
325
|
+
static int alloc_f(BlockDriverState *bs, int argc, char **argv)
|
326
|
+
{
|
327
|
+
- int64_t offset, sector_num;
|
328
|
+
- int nb_sectors, remaining;
|
329
|
+
+ int64_t offset, sector_num, nb_sectors, remaining;
|
330
|
+
char s1[64];
|
331
|
+
- int num, sum_alloc;
|
332
|
+
- int ret;
|
333
|
+
+ int num, ret;
|
334
|
+
+ int64_t sum_alloc;
|
335
|
+
|
336
|
+
offset = cvtnum(argv[1]);
|
337
|
+
if (offset < 0) {
|
338
|
+
@@ -1828,6 +1873,10 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
|
339
|
+
if (nb_sectors < 0) {
|
340
|
+
printf("non-numeric length argument -- %s\n", argv[2]);
|
341
|
+
return 0;
|
342
|
+
+ } else if (nb_sectors > INT_MAX) {
|
343
|
+
+ printf("length argument cannot exceed %d, given %s\n",
|
344
|
+
+ INT_MAX, argv[2]);
|
345
|
+
+ return 0;
|
346
|
+
}
|
347
|
+
} else {
|
348
|
+
nb_sectors = 1;
|
349
|
+
@@ -1855,7 +1904,7 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
|
350
|
+
|
351
|
+
cvtstr(offset, s1, sizeof(s1));
|
352
|
+
|
353
|
+
- printf("%d/%d sectors allocated at offset %s\n",
|
354
|
+
+ printf("%"PRId64"/%"PRId64" sectors allocated at offset %s\n",
|
355
|
+
sum_alloc, nb_sectors, s1);
|
356
|
+
return 0;
|
357
|
+
}
|
358
|
+
--
|
359
|
+
1.8.3.1
|
360
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
From 1f08301adf98c235ccc4e978f809c3f60833452c Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:00 +0200
|
4
|
+
Subject: [PATCH 02/16] qjson: Apply nesting limit more sanely
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-4-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71468
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 02/15] qjson: Apply nesting limit more sanely
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
The nesting limit from commit 29c75dd "json-streamer: limit the
|
16
|
+
maximum recursion depth and maximum token count" applies separately to
|
17
|
+
braces and brackets. This makes no sense. Apply it to their sum,
|
18
|
+
because that's actually a measure of recursion depth.
|
19
|
+
|
20
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
21
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
22
|
+
Message-Id: <1448486613-17634-2-git-send-email-armbru@redhat.com>
|
23
|
+
(cherry picked from commit 4f2d31fbc0bfdf41feea7d1be49f4f7ffa005534)
|
24
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
qobject/json-streamer.c | 3 +--
|
28
|
+
1 file changed, 1 insertion(+), 2 deletions(-)
|
29
|
+
|
30
|
+
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
|
31
|
+
index 1b2f9b1..dced2c7 100644
|
32
|
+
--- a/qobject/json-streamer.c
|
33
|
+
+++ b/qobject/json-streamer.c
|
34
|
+
@@ -64,8 +64,7 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
|
35
|
+
parser->bracket_count == 0)) {
|
36
|
+
goto out_emit;
|
37
|
+
} else if (parser->token_size > MAX_TOKEN_SIZE ||
|
38
|
+
- parser->bracket_count > MAX_NESTING ||
|
39
|
+
- parser->brace_count > MAX_NESTING) {
|
40
|
+
+ parser->bracket_count + parser->brace_count > MAX_NESTING) {
|
41
|
+
/* Security consideration, we limit total memory allocated per object
|
42
|
+
* and the maximum recursion depth that a message can force.
|
43
|
+
*/
|
44
|
+
--
|
45
|
+
1.8.3.1
|
46
|
+
|
@@ -0,0 +1,328 @@
|
|
1
|
+
From 2975abb487a54b49246646db9aa40ee6d1beaa97 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:08 +0200
|
4
|
+
Subject: [PATCH 10/16] qjson: Convert to parser to recursive descent
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-12-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71474
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 10/15] qjson: Convert to parser to recursive descent
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
We backtrack in parse_value(), even though JSON is LL(1) and thus can
|
16
|
+
be parsed by straightforward recursive descent. Do exactly that.
|
17
|
+
|
18
|
+
Based on an almost-correct patch from Paolo Bonzini.
|
19
|
+
|
20
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
21
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
22
|
+
Message-Id: <1448486613-17634-10-git-send-email-armbru@redhat.com>
|
23
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
24
|
+
(cherry picked from commit d538b25543f4db026bb435066e2403a542522c40)
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
|
27
|
+
Conflicts:
|
28
|
+
qobject/json-parser.c
|
29
|
+
|
30
|
+
Straighforward conflicts because lacking commit fc48ffc "qobject: Use
|
31
|
+
'bool' for qbool", we still use qbool_from_int(), and we lack commit
|
32
|
+
e549e71 "json-parser: Accept 'null' in QMP".
|
33
|
+
|
34
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
35
|
+
---
|
36
|
+
qobject/json-parser.c | 163 ++++++++++++++------------------------------------
|
37
|
+
1 file changed, 46 insertions(+), 117 deletions(-)
|
38
|
+
|
39
|
+
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
|
40
|
+
index 79f4173..b242fba 100644
|
41
|
+
--- a/qobject/json-parser.c
|
42
|
+
+++ b/qobject/json-parser.c
|
43
|
+
@@ -266,23 +266,6 @@ static QObject *parser_context_peek_token(JSONParserContext *ctxt)
|
44
|
+
return token;
|
45
|
+
}
|
46
|
+
|
47
|
+
-static JSONParserContext parser_context_save(JSONParserContext *ctxt)
|
48
|
+
-{
|
49
|
+
- JSONParserContext saved_ctxt = {0};
|
50
|
+
- saved_ctxt.tokens.pos = ctxt->tokens.pos;
|
51
|
+
- saved_ctxt.tokens.count = ctxt->tokens.count;
|
52
|
+
- saved_ctxt.tokens.buf = ctxt->tokens.buf;
|
53
|
+
- return saved_ctxt;
|
54
|
+
-}
|
55
|
+
-
|
56
|
+
-static void parser_context_restore(JSONParserContext *ctxt,
|
57
|
+
- JSONParserContext saved_ctxt)
|
58
|
+
-{
|
59
|
+
- ctxt->tokens.pos = saved_ctxt.tokens.pos;
|
60
|
+
- ctxt->tokens.count = saved_ctxt.tokens.count;
|
61
|
+
- ctxt->tokens.buf = saved_ctxt.tokens.buf;
|
62
|
+
-}
|
63
|
+
-
|
64
|
+
static void tokens_append_from_iter(QObject *obj, void *opaque)
|
65
|
+
{
|
66
|
+
JSONParserContext *ctxt = opaque;
|
67
|
+
@@ -334,7 +317,6 @@ static void parser_context_free(JSONParserContext *ctxt)
|
68
|
+
static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
|
69
|
+
{
|
70
|
+
QObject *key = NULL, *token = NULL, *value, *peek;
|
71
|
+
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
|
72
|
+
|
73
|
+
peek = parser_context_peek_token(ctxt);
|
74
|
+
if (peek == NULL) {
|
75
|
+
@@ -372,7 +354,6 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
|
76
|
+
return 0;
|
77
|
+
|
78
|
+
out:
|
79
|
+
- parser_context_restore(ctxt, saved_ctxt);
|
80
|
+
qobject_decref(key);
|
81
|
+
|
82
|
+
return -1;
|
83
|
+
@@ -382,16 +363,9 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
84
|
+
{
|
85
|
+
QDict *dict = NULL;
|
86
|
+
QObject *token, *peek;
|
87
|
+
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
|
88
|
+
|
89
|
+
token = parser_context_pop_token(ctxt);
|
90
|
+
- if (token == NULL) {
|
91
|
+
- goto out;
|
92
|
+
- }
|
93
|
+
-
|
94
|
+
- if (token_get_type(token) != JSON_LCURLY) {
|
95
|
+
- goto out;
|
96
|
+
- }
|
97
|
+
+ assert(token && token_get_type(token) == JSON_LCURLY);
|
98
|
+
|
99
|
+
dict = qdict_new();
|
100
|
+
|
101
|
+
@@ -435,7 +409,6 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
102
|
+
return QOBJECT(dict);
|
103
|
+
|
104
|
+
out:
|
105
|
+
- parser_context_restore(ctxt, saved_ctxt);
|
106
|
+
QDECREF(dict);
|
107
|
+
return NULL;
|
108
|
+
}
|
109
|
+
@@ -444,16 +417,9 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
110
|
+
{
|
111
|
+
QList *list = NULL;
|
112
|
+
QObject *token, *peek;
|
113
|
+
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
|
114
|
+
|
115
|
+
token = parser_context_pop_token(ctxt);
|
116
|
+
- if (token == NULL) {
|
117
|
+
- goto out;
|
118
|
+
- }
|
119
|
+
-
|
120
|
+
- if (token_get_type(token) != JSON_LSQUARE) {
|
121
|
+
- goto out;
|
122
|
+
- }
|
123
|
+
+ assert(token && token_get_type(token) == JSON_LSQUARE);
|
124
|
+
|
125
|
+
list = qlist_new();
|
126
|
+
|
127
|
+
@@ -507,107 +473,70 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
128
|
+
return QOBJECT(list);
|
129
|
+
|
130
|
+
out:
|
131
|
+
- parser_context_restore(ctxt, saved_ctxt);
|
132
|
+
QDECREF(list);
|
133
|
+
return NULL;
|
134
|
+
}
|
135
|
+
|
136
|
+
static QObject *parse_keyword(JSONParserContext *ctxt)
|
137
|
+
{
|
138
|
+
- QObject *token, *ret;
|
139
|
+
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
|
140
|
+
+ QObject *token;
|
141
|
+
const char *val;
|
142
|
+
|
143
|
+
token = parser_context_pop_token(ctxt);
|
144
|
+
- if (token == NULL) {
|
145
|
+
- goto out;
|
146
|
+
- }
|
147
|
+
-
|
148
|
+
- if (token_get_type(token) != JSON_KEYWORD) {
|
149
|
+
- goto out;
|
150
|
+
- }
|
151
|
+
-
|
152
|
+
+ assert(token && token_get_type(token) == JSON_KEYWORD);
|
153
|
+
val = token_get_value(token);
|
154
|
+
|
155
|
+
if (!strcmp(val, "true")) {
|
156
|
+
- ret = QOBJECT(qbool_from_int(true));
|
157
|
+
+ return QOBJECT(qbool_from_int(true));
|
158
|
+
} else if (!strcmp(val, "false")) {
|
159
|
+
- ret = QOBJECT(qbool_from_int(false));
|
160
|
+
- } else {
|
161
|
+
- parse_error(ctxt, token, "invalid keyword '%s'", val);
|
162
|
+
- goto out;
|
163
|
+
+ return QOBJECT(qbool_from_int(false));
|
164
|
+
}
|
165
|
+
-
|
166
|
+
- return ret;
|
167
|
+
-
|
168
|
+
-out:
|
169
|
+
- parser_context_restore(ctxt, saved_ctxt);
|
170
|
+
-
|
171
|
+
+ parse_error(ctxt, token, "invalid keyword '%s'", val);
|
172
|
+
return NULL;
|
173
|
+
}
|
174
|
+
|
175
|
+
static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
|
176
|
+
{
|
177
|
+
- QObject *token = NULL, *obj;
|
178
|
+
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
|
179
|
+
+ QObject *token;
|
180
|
+
const char *val;
|
181
|
+
|
182
|
+
if (ap == NULL) {
|
183
|
+
- goto out;
|
184
|
+
+ return NULL;
|
185
|
+
}
|
186
|
+
|
187
|
+
token = parser_context_pop_token(ctxt);
|
188
|
+
- if (token == NULL) {
|
189
|
+
- goto out;
|
190
|
+
- }
|
191
|
+
-
|
192
|
+
- if (token_get_type(token) != JSON_ESCAPE) {
|
193
|
+
- goto out;
|
194
|
+
- }
|
195
|
+
-
|
196
|
+
+ assert(token && token_get_type(token) == JSON_ESCAPE);
|
197
|
+
val = token_get_value(token);
|
198
|
+
|
199
|
+
if (!strcmp(val, "%p")) {
|
200
|
+
- obj = va_arg(*ap, QObject *);
|
201
|
+
+ return va_arg(*ap, QObject *);
|
202
|
+
} else if (!strcmp(val, "%i")) {
|
203
|
+
- obj = QOBJECT(qbool_from_int(va_arg(*ap, int)));
|
204
|
+
+ return QOBJECT(qbool_from_int(va_arg(*ap, int)));
|
205
|
+
} else if (!strcmp(val, "%d")) {
|
206
|
+
- obj = QOBJECT(qint_from_int(va_arg(*ap, int)));
|
207
|
+
+ return QOBJECT(qint_from_int(va_arg(*ap, int)));
|
208
|
+
} else if (!strcmp(val, "%ld")) {
|
209
|
+
- obj = QOBJECT(qint_from_int(va_arg(*ap, long)));
|
210
|
+
+ return QOBJECT(qint_from_int(va_arg(*ap, long)));
|
211
|
+
} else if (!strcmp(val, "%lld") ||
|
212
|
+
!strcmp(val, "%I64d")) {
|
213
|
+
- obj = QOBJECT(qint_from_int(va_arg(*ap, long long)));
|
214
|
+
+ return QOBJECT(qint_from_int(va_arg(*ap, long long)));
|
215
|
+
} else if (!strcmp(val, "%s")) {
|
216
|
+
- obj = QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
|
217
|
+
+ return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
|
218
|
+
} else if (!strcmp(val, "%f")) {
|
219
|
+
- obj = QOBJECT(qfloat_from_double(va_arg(*ap, double)));
|
220
|
+
- } else {
|
221
|
+
- goto out;
|
222
|
+
+ return QOBJECT(qfloat_from_double(va_arg(*ap, double)));
|
223
|
+
}
|
224
|
+
-
|
225
|
+
- return obj;
|
226
|
+
-
|
227
|
+
-out:
|
228
|
+
- parser_context_restore(ctxt, saved_ctxt);
|
229
|
+
-
|
230
|
+
return NULL;
|
231
|
+
}
|
232
|
+
|
233
|
+
static QObject *parse_literal(JSONParserContext *ctxt)
|
234
|
+
{
|
235
|
+
- QObject *token, *obj;
|
236
|
+
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
|
237
|
+
+ QObject *token;
|
238
|
+
|
239
|
+
token = parser_context_pop_token(ctxt);
|
240
|
+
- if (token == NULL) {
|
241
|
+
- goto out;
|
242
|
+
- }
|
243
|
+
+ assert(token);
|
244
|
+
|
245
|
+
switch (token_get_type(token)) {
|
246
|
+
case JSON_STRING:
|
247
|
+
- obj = QOBJECT(qstring_from_escaped_str(ctxt, token));
|
248
|
+
- break;
|
249
|
+
+ return QOBJECT(qstring_from_escaped_str(ctxt, token));
|
250
|
+
case JSON_INTEGER: {
|
251
|
+
/* A possibility exists that this is a whole-valued float where the
|
252
|
+
* fractional part was left out due to being 0 (.0). It's not a big
|
253
|
+
@@ -626,46 +555,46 @@ static QObject *parse_literal(JSONParserContext *ctxt)
|
254
|
+
errno = 0; /* strtoll doesn't set errno on success */
|
255
|
+
value = strtoll(token_get_value(token), NULL, 10);
|
256
|
+
if (errno != ERANGE) {
|
257
|
+
- obj = QOBJECT(qint_from_int(value));
|
258
|
+
- break;
|
259
|
+
+ return QOBJECT(qint_from_int(value));
|
260
|
+
}
|
261
|
+
/* fall through to JSON_FLOAT */
|
262
|
+
}
|
263
|
+
case JSON_FLOAT:
|
264
|
+
/* FIXME dependent on locale */
|
265
|
+
- obj = QOBJECT(qfloat_from_double(strtod(token_get_value(token), NULL)));
|
266
|
+
- break;
|
267
|
+
+ return QOBJECT(qfloat_from_double(strtod(token_get_value(token),
|
268
|
+
+ NULL)));
|
269
|
+
default:
|
270
|
+
- goto out;
|
271
|
+
+ abort();
|
272
|
+
}
|
273
|
+
-
|
274
|
+
- return obj;
|
275
|
+
-
|
276
|
+
-out:
|
277
|
+
- parser_context_restore(ctxt, saved_ctxt);
|
278
|
+
-
|
279
|
+
- return NULL;
|
280
|
+
}
|
281
|
+
|
282
|
+
static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
|
283
|
+
{
|
284
|
+
- QObject *obj;
|
285
|
+
+ QObject *token;
|
286
|
+
|
287
|
+
- obj = parse_object(ctxt, ap);
|
288
|
+
- if (obj == NULL) {
|
289
|
+
- obj = parse_array(ctxt, ap);
|
290
|
+
- }
|
291
|
+
- if (obj == NULL) {
|
292
|
+
- obj = parse_escape(ctxt, ap);
|
293
|
+
- }
|
294
|
+
- if (obj == NULL) {
|
295
|
+
- obj = parse_keyword(ctxt);
|
296
|
+
- }
|
297
|
+
- if (obj == NULL) {
|
298
|
+
- obj = parse_literal(ctxt);
|
299
|
+
+ token = parser_context_peek_token(ctxt);
|
300
|
+
+ if (token == NULL) {
|
301
|
+
+ parse_error(ctxt, NULL, "premature EOI");
|
302
|
+
+ return NULL;
|
303
|
+
}
|
304
|
+
|
305
|
+
- return obj;
|
306
|
+
+ switch (token_get_type(token)) {
|
307
|
+
+ case JSON_LCURLY:
|
308
|
+
+ return parse_object(ctxt, ap);
|
309
|
+
+ case JSON_LSQUARE:
|
310
|
+
+ return parse_array(ctxt, ap);
|
311
|
+
+ case JSON_ESCAPE:
|
312
|
+
+ return parse_escape(ctxt, ap);
|
313
|
+
+ case JSON_INTEGER:
|
314
|
+
+ case JSON_FLOAT:
|
315
|
+
+ case JSON_STRING:
|
316
|
+
+ return parse_literal(ctxt);
|
317
|
+
+ case JSON_KEYWORD:
|
318
|
+
+ return parse_keyword(ctxt);
|
319
|
+
+ default:
|
320
|
+
+ parse_error(ctxt, token, "expecting value");
|
321
|
+
+ return NULL;
|
322
|
+
+ }
|
323
|
+
}
|
324
|
+
|
325
|
+
QObject *json_parser_parse(QList *tokens, va_list *ap)
|
326
|
+
--
|
327
|
+
1.8.3.1
|
328
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
From ba9229d280e035872ac2258873c1b9f34cc8c4a9 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:01 +0200
|
4
|
+
Subject: [PATCH 03/16] qjson: Don't crash when input exceeds nesting limit
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-5-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71472
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 03/15] qjson: Don't crash when input exceeds nesting limit
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
We limit nesting depth and input size to defend against input
|
16
|
+
triggering excessive heap or stack memory use (commit 29c75dd
|
17
|
+
json-streamer: limit the maximum recursion depth and maximum token
|
18
|
+
count). However, when the nesting limit is exceeded,
|
19
|
+
parser_context_peek_token()'s assertion fails.
|
20
|
+
|
21
|
+
Broken in commit 65c0f1e "json-parser: don't replicate tokens at each
|
22
|
+
level of recursion".
|
23
|
+
|
24
|
+
To reproduce stuff 1025 open braces or brackets into QMP.
|
25
|
+
|
26
|
+
Fix by taking the error exit instead of the normal one.
|
27
|
+
|
28
|
+
Reported-by: Eric Blake <eblake@redhat.com>
|
29
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
30
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
31
|
+
Message-Id: <1448486613-17634-3-git-send-email-armbru@redhat.com>
|
32
|
+
(cherry picked from commit 0753113a26bb8c77f951b1ea91fd4f36d099c37a)
|
33
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
34
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
35
|
+
---
|
36
|
+
qobject/json-streamer.c | 5 +++--
|
37
|
+
1 file changed, 3 insertions(+), 2 deletions(-)
|
38
|
+
|
39
|
+
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
|
40
|
+
index dced2c7..2bd22a7 100644
|
41
|
+
--- a/qobject/json-streamer.c
|
42
|
+
+++ b/qobject/json-streamer.c
|
43
|
+
@@ -68,13 +68,14 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
|
44
|
+
/* Security consideration, we limit total memory allocated per object
|
45
|
+
* and the maximum recursion depth that a message can force.
|
46
|
+
*/
|
47
|
+
- goto out_emit;
|
48
|
+
+ goto out_emit_bad;
|
49
|
+
}
|
50
|
+
|
51
|
+
return;
|
52
|
+
|
53
|
+
out_emit_bad:
|
54
|
+
- /* clear out token list and tell the parser to emit and error
|
55
|
+
+ /*
|
56
|
+
+ * Clear out token list and tell the parser to emit an error
|
57
|
+
* indication by passing it a NULL list
|
58
|
+
*/
|
59
|
+
QDECREF(parser->tokens);
|
60
|
+
--
|
61
|
+
1.8.3.1
|
62
|
+
|
@@ -0,0 +1,222 @@
|
|
1
|
+
From 95aeff93da762bf7f69317eb674d3eccce672038 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:04 +0200
|
4
|
+
Subject: [PATCH 06/16] qjson: Give each of the six structural chars its own
|
5
|
+
token type
|
6
|
+
|
7
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
8
|
+
Message-id: <1469604913-12442-8-git-send-email-armbru@redhat.com>
|
9
|
+
Patchwork-id: 71482
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 06/15] qjson: Give each of the six structural chars its own token type
|
11
|
+
Bugzilla: 1276036
|
12
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
13
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
14
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
15
|
+
|
16
|
+
Simplifies things, because we always check for a specific one.
|
17
|
+
|
18
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
19
|
+
Message-Id: <1448486613-17634-6-git-send-email-armbru@redhat.com>
|
20
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
21
|
+
(cherry picked from commit c54616608af442edf4cfb7397a1909c2653efba0)
|
22
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
23
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
24
|
+
---
|
25
|
+
include/qapi/qmp/json-lexer.h | 7 ++++++-
|
26
|
+
qobject/json-lexer.c | 19 ++++++++++++-------
|
27
|
+
qobject/json-parser.c | 31 +++++++++----------------------
|
28
|
+
qobject/json-streamer.c | 32 +++++++++++++++-----------------
|
29
|
+
4 files changed, 42 insertions(+), 47 deletions(-)
|
30
|
+
|
31
|
+
diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h
|
32
|
+
index 61a143f..f3e8dc7 100644
|
33
|
+
--- a/include/qapi/qmp/json-lexer.h
|
34
|
+
+++ b/include/qapi/qmp/json-lexer.h
|
35
|
+
|
36
|
+
|
37
|
+
typedef enum json_token_type {
|
38
|
+
JSON_MIN = 100,
|
39
|
+
- JSON_OPERATOR = JSON_MIN,
|
40
|
+
+ JSON_LCURLY = JSON_MIN,
|
41
|
+
+ JSON_RCURLY,
|
42
|
+
+ JSON_LSQUARE,
|
43
|
+
+ JSON_RSQUARE,
|
44
|
+
+ JSON_COLON,
|
45
|
+
+ JSON_COMMA,
|
46
|
+
JSON_INTEGER,
|
47
|
+
JSON_FLOAT,
|
48
|
+
JSON_KEYWORD,
|
49
|
+
diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
|
50
|
+
index f106ffb..1bfff02 100644
|
51
|
+
--- a/qobject/json-lexer.c
|
52
|
+
+++ b/qobject/json-lexer.c
|
53
|
+
@@ -257,12 +257,12 @@ static const uint8_t json_lexer[][256] = {
|
54
|
+
['0'] = IN_ZERO,
|
55
|
+
['1' ... '9'] = IN_NONZERO_NUMBER,
|
56
|
+
['-'] = IN_NEG_NONZERO_NUMBER,
|
57
|
+
- ['{'] = JSON_OPERATOR,
|
58
|
+
- ['}'] = JSON_OPERATOR,
|
59
|
+
- ['['] = JSON_OPERATOR,
|
60
|
+
- [']'] = JSON_OPERATOR,
|
61
|
+
- [','] = JSON_OPERATOR,
|
62
|
+
- [':'] = JSON_OPERATOR,
|
63
|
+
+ ['{'] = JSON_LCURLY,
|
64
|
+
+ ['}'] = JSON_RCURLY,
|
65
|
+
+ ['['] = JSON_LSQUARE,
|
66
|
+
+ [']'] = JSON_RSQUARE,
|
67
|
+
+ [','] = JSON_COMMA,
|
68
|
+
+ [':'] = JSON_COLON,
|
69
|
+
['a' ... 'z'] = IN_KEYWORD,
|
70
|
+
['%'] = IN_ESCAPE,
|
71
|
+
[' '] = IN_WHITESPACE,
|
72
|
+
@@ -299,7 +299,12 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
|
73
|
+
}
|
74
|
+
|
75
|
+
switch (new_state) {
|
76
|
+
- case JSON_OPERATOR:
|
77
|
+
+ case JSON_LCURLY:
|
78
|
+
+ case JSON_RCURLY:
|
79
|
+
+ case JSON_LSQUARE:
|
80
|
+
+ case JSON_RSQUARE:
|
81
|
+
+ case JSON_COLON:
|
82
|
+
+ case JSON_COMMA:
|
83
|
+
case JSON_ESCAPE:
|
84
|
+
case JSON_INTEGER:
|
85
|
+
case JSON_FLOAT:
|
86
|
+
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
|
87
|
+
index fa09769..50bf30c 100644
|
88
|
+
--- a/qobject/json-parser.c
|
89
|
+
+++ b/qobject/json-parser.c
|
90
|
+
@@ -64,19 +64,6 @@ static JSONTokenType token_get_type(QObject *obj)
|
91
|
+
return qdict_get_int(qobject_to_qdict(obj), "type");
|
92
|
+
}
|
93
|
+
|
94
|
+
-static int token_is_operator(QObject *obj, char op)
|
95
|
+
-{
|
96
|
+
- const char *val;
|
97
|
+
-
|
98
|
+
- if (token_get_type(obj) != JSON_OPERATOR) {
|
99
|
+
- return 0;
|
100
|
+
- }
|
101
|
+
-
|
102
|
+
- val = token_get_value(obj);
|
103
|
+
-
|
104
|
+
- return (val[0] == op) && (val[1] == 0);
|
105
|
+
-}
|
106
|
+
-
|
107
|
+
static int token_is_keyword(QObject *obj, const char *value)
|
108
|
+
{
|
109
|
+
if (token_get_type(obj) != JSON_KEYWORD) {
|
110
|
+
@@ -385,7 +372,7 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
|
111
|
+
goto out;
|
112
|
+
}
|
113
|
+
|
114
|
+
- if (!token_is_operator(token, ':')) {
|
115
|
+
+ if (token_get_type(token) != JSON_COLON) {
|
116
|
+
parse_error(ctxt, token, "missing : in object pair");
|
117
|
+
goto out;
|
118
|
+
}
|
119
|
+
@@ -420,7 +407,7 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
120
|
+
goto out;
|
121
|
+
}
|
122
|
+
|
123
|
+
- if (!token_is_operator(token, '{')) {
|
124
|
+
+ if (token_get_type(token) != JSON_LCURLY) {
|
125
|
+
goto out;
|
126
|
+
}
|
127
|
+
|
128
|
+
@@ -432,7 +419,7 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
129
|
+
goto out;
|
130
|
+
}
|
131
|
+
|
132
|
+
- if (!token_is_operator(peek, '}')) {
|
133
|
+
+ if (token_get_type(peek) != JSON_RCURLY) {
|
134
|
+
if (parse_pair(ctxt, dict, ap) == -1) {
|
135
|
+
goto out;
|
136
|
+
}
|
137
|
+
@@ -443,8 +430,8 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
138
|
+
goto out;
|
139
|
+
}
|
140
|
+
|
141
|
+
- while (!token_is_operator(token, '}')) {
|
142
|
+
- if (!token_is_operator(token, ',')) {
|
143
|
+
+ while (token_get_type(token) != JSON_RCURLY) {
|
144
|
+
+ if (token_get_type(token) != JSON_COMMA) {
|
145
|
+
parse_error(ctxt, token, "expected separator in dict");
|
146
|
+
goto out;
|
147
|
+
}
|
148
|
+
@@ -482,7 +469,7 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
149
|
+
goto out;
|
150
|
+
}
|
151
|
+
|
152
|
+
- if (!token_is_operator(token, '[')) {
|
153
|
+
+ if (token_get_type(token) != JSON_LSQUARE) {
|
154
|
+
goto out;
|
155
|
+
}
|
156
|
+
|
157
|
+
@@ -494,7 +481,7 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
158
|
+
goto out;
|
159
|
+
}
|
160
|
+
|
161
|
+
- if (!token_is_operator(peek, ']')) {
|
162
|
+
+ if (token_get_type(peek) != JSON_RSQUARE) {
|
163
|
+
QObject *obj;
|
164
|
+
|
165
|
+
obj = parse_value(ctxt, ap);
|
166
|
+
@@ -511,8 +498,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
167
|
+
goto out;
|
168
|
+
}
|
169
|
+
|
170
|
+
- while (!token_is_operator(token, ']')) {
|
171
|
+
- if (!token_is_operator(token, ',')) {
|
172
|
+
+ while (token_get_type(token) != JSON_RSQUARE) {
|
173
|
+
+ if (token_get_type(token) != JSON_COMMA) {
|
174
|
+
parse_error(ctxt, token, "expected separator in list");
|
175
|
+
goto out;
|
176
|
+
}
|
177
|
+
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
|
178
|
+
index 2bd22a7..4a161a1 100644
|
179
|
+
--- a/qobject/json-streamer.c
|
180
|
+
+++ b/qobject/json-streamer.c
|
181
|
+
@@ -26,23 +26,21 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
|
182
|
+
JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
|
183
|
+
QDict *dict;
|
184
|
+
|
185
|
+
- if (type == JSON_OPERATOR) {
|
186
|
+
- switch (qstring_get_str(token)[0]) {
|
187
|
+
- case '{':
|
188
|
+
- parser->brace_count++;
|
189
|
+
- break;
|
190
|
+
- case '}':
|
191
|
+
- parser->brace_count--;
|
192
|
+
- break;
|
193
|
+
- case '[':
|
194
|
+
- parser->bracket_count++;
|
195
|
+
- break;
|
196
|
+
- case ']':
|
197
|
+
- parser->bracket_count--;
|
198
|
+
- break;
|
199
|
+
- default:
|
200
|
+
- break;
|
201
|
+
- }
|
202
|
+
+ switch (type) {
|
203
|
+
+ case JSON_LCURLY:
|
204
|
+
+ parser->brace_count++;
|
205
|
+
+ break;
|
206
|
+
+ case JSON_RCURLY:
|
207
|
+
+ parser->brace_count--;
|
208
|
+
+ break;
|
209
|
+
+ case JSON_LSQUARE:
|
210
|
+
+ parser->bracket_count++;
|
211
|
+
+ break;
|
212
|
+
+ case JSON_RSQUARE:
|
213
|
+
+ parser->bracket_count--;
|
214
|
+
+ break;
|
215
|
+
+ default:
|
216
|
+
+ break;
|
217
|
+
}
|
218
|
+
|
219
|
+
dict = qdict_new();
|
220
|
+
--
|
221
|
+
1.8.3.1
|
222
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
From 225cb3d48dd4dcbc7bf845c0b4b06a90030874f3 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:06 +0200
|
4
|
+
Subject: [PATCH 08/16] qjson: Inline token_is_escape() and simplify
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-10-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71479
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 08/15] qjson: Inline token_is_escape() and simplify
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
16
|
+
Message-Id: <1448486613-17634-8-git-send-email-armbru@redhat.com>
|
17
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
18
|
+
(cherry picked from commit 6b9606f68ec589def27bd2a9cea97ec63cffd581)
|
19
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
20
|
+
|
21
|
+
Conflicts:
|
22
|
+
qobject/json-parser.c
|
23
|
+
|
24
|
+
Straighforward conflict because lacking commit fc48ffc "qobject: Use
|
25
|
+
'bool' for qbool", we still use qbool_from_int().
|
26
|
+
|
27
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
28
|
+
---
|
29
|
+
qobject/json-parser.c | 32 +++++++++++++++-----------------
|
30
|
+
1 file changed, 15 insertions(+), 17 deletions(-)
|
31
|
+
|
32
|
+
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
|
33
|
+
index e3690de..79f4173 100644
|
34
|
+
--- a/qobject/json-parser.c
|
35
|
+
+++ b/qobject/json-parser.c
|
36
|
+
@@ -64,15 +64,6 @@ static JSONTokenType token_get_type(QObject *obj)
|
37
|
+
return qdict_get_int(qobject_to_qdict(obj), "type");
|
38
|
+
}
|
39
|
+
|
40
|
+
-static int token_is_escape(QObject *obj, const char *value)
|
41
|
+
-{
|
42
|
+
- if (token_get_type(obj) != JSON_ESCAPE) {
|
43
|
+
- return 0;
|
44
|
+
- }
|
45
|
+
-
|
46
|
+
- return (strcmp(token_get_value(obj), value) == 0);
|
47
|
+
-}
|
48
|
+
-
|
49
|
+
/**
|
50
|
+
* Error handler
|
51
|
+
*/
|
52
|
+
@@ -559,6 +550,7 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
|
53
|
+
{
|
54
|
+
QObject *token = NULL, *obj;
|
55
|
+
JSONParserContext saved_ctxt = parser_context_save(ctxt);
|
56
|
+
+ const char *val;
|
57
|
+
|
58
|
+
if (ap == NULL) {
|
59
|
+
goto out;
|
60
|
+
@@ -569,20 +561,26 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
|
61
|
+
goto out;
|
62
|
+
}
|
63
|
+
|
64
|
+
- if (token_is_escape(token, "%p")) {
|
65
|
+
+ if (token_get_type(token) != JSON_ESCAPE) {
|
66
|
+
+ goto out;
|
67
|
+
+ }
|
68
|
+
+
|
69
|
+
+ val = token_get_value(token);
|
70
|
+
+
|
71
|
+
+ if (!strcmp(val, "%p")) {
|
72
|
+
obj = va_arg(*ap, QObject *);
|
73
|
+
- } else if (token_is_escape(token, "%i")) {
|
74
|
+
+ } else if (!strcmp(val, "%i")) {
|
75
|
+
obj = QOBJECT(qbool_from_int(va_arg(*ap, int)));
|
76
|
+
- } else if (token_is_escape(token, "%d")) {
|
77
|
+
+ } else if (!strcmp(val, "%d")) {
|
78
|
+
obj = QOBJECT(qint_from_int(va_arg(*ap, int)));
|
79
|
+
- } else if (token_is_escape(token, "%ld")) {
|
80
|
+
+ } else if (!strcmp(val, "%ld")) {
|
81
|
+
obj = QOBJECT(qint_from_int(va_arg(*ap, long)));
|
82
|
+
- } else if (token_is_escape(token, "%lld") ||
|
83
|
+
- token_is_escape(token, "%I64d")) {
|
84
|
+
+ } else if (!strcmp(val, "%lld") ||
|
85
|
+
+ !strcmp(val, "%I64d")) {
|
86
|
+
obj = QOBJECT(qint_from_int(va_arg(*ap, long long)));
|
87
|
+
- } else if (token_is_escape(token, "%s")) {
|
88
|
+
+ } else if (!strcmp(val, "%s")) {
|
89
|
+
obj = QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
|
90
|
+
- } else if (token_is_escape(token, "%f")) {
|
91
|
+
+ } else if (!strcmp(val, "%f")) {
|
92
|
+
obj = QOBJECT(qfloat_from_double(va_arg(*ap, double)));
|
93
|
+
} else {
|
94
|
+
goto out;
|
95
|
+
--
|
96
|
+
1.8.3.1
|
97
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
From 3cf8ec8ff0ad3920ce23166b2576655bcd886c5a Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:05 +0200
|
4
|
+
Subject: [PATCH 07/16] qjson: Inline token_is_keyword() and simplify
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-9-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71483
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 07/15] qjson: Inline token_is_keyword() and simplify
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
16
|
+
Message-Id: <1448486613-17634-7-git-send-email-armbru@redhat.com>
|
17
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
18
|
+
(cherry picked from commit 50e2a467f5315fa36c547fb6330659ba45f6bb83)
|
19
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
20
|
+
|
21
|
+
Conflicts:
|
22
|
+
qobject/json-parser.c
|
23
|
+
|
24
|
+
Straighforward conflict because lacking commit fc48ffc "qobject: Use
|
25
|
+
'bool' for qbool", we still use qbool_from_int(), and we lack commit
|
26
|
+
e549e71 "json-parser: Accept 'null' in QMP".
|
27
|
+
|
28
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
29
|
+
---
|
30
|
+
qobject/json-parser.c | 18 ++++++------------
|
31
|
+
1 file changed, 6 insertions(+), 12 deletions(-)
|
32
|
+
|
33
|
+
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
|
34
|
+
index 50bf30c..e3690de 100644
|
35
|
+
--- a/qobject/json-parser.c
|
36
|
+
+++ b/qobject/json-parser.c
|
37
|
+
@@ -64,15 +64,6 @@ static JSONTokenType token_get_type(QObject *obj)
|
38
|
+
return qdict_get_int(qobject_to_qdict(obj), "type");
|
39
|
+
}
|
40
|
+
|
41
|
+
-static int token_is_keyword(QObject *obj, const char *value)
|
42
|
+
-{
|
43
|
+
- if (token_get_type(obj) != JSON_KEYWORD) {
|
44
|
+
- return 0;
|
45
|
+
- }
|
46
|
+
-
|
47
|
+
- return strcmp(token_get_value(obj), value) == 0;
|
48
|
+
-}
|
49
|
+
-
|
50
|
+
static int token_is_escape(QObject *obj, const char *value)
|
51
|
+
{
|
52
|
+
if (token_get_type(obj) != JSON_ESCAPE) {
|
53
|
+
@@ -534,6 +525,7 @@ static QObject *parse_keyword(JSONParserContext *ctxt)
|
54
|
+
{
|
55
|
+
QObject *token, *ret;
|
56
|
+
JSONParserContext saved_ctxt = parser_context_save(ctxt);
|
57
|
+
+ const char *val;
|
58
|
+
|
59
|
+
token = parser_context_pop_token(ctxt);
|
60
|
+
if (token == NULL) {
|
61
|
+
@@ -544,12 +536,14 @@ static QObject *parse_keyword(JSONParserContext *ctxt)
|
62
|
+
goto out;
|
63
|
+
}
|
64
|
+
|
65
|
+
- if (token_is_keyword(token, "true")) {
|
66
|
+
+ val = token_get_value(token);
|
67
|
+
+
|
68
|
+
+ if (!strcmp(val, "true")) {
|
69
|
+
ret = QOBJECT(qbool_from_int(true));
|
70
|
+
- } else if (token_is_keyword(token, "false")) {
|
71
|
+
+ } else if (!strcmp(val, "false")) {
|
72
|
+
ret = QOBJECT(qbool_from_int(false));
|
73
|
+
} else {
|
74
|
+
- parse_error(ctxt, token, "invalid keyword `%s'", token_get_value(token));
|
75
|
+
+ parse_error(ctxt, token, "invalid keyword '%s'", val);
|
76
|
+
goto out;
|
77
|
+
}
|
78
|
+
|
79
|
+
--
|
80
|
+
1.8.3.1
|
81
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
From 60ad1bad25ea99c538b745ff95e6e0a877d37d1f Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:11 +0200
|
4
|
+
Subject: [PATCH 13/16] qjson: Limit number of tokens in addition to total size
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-15-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71476
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 13/15] qjson: Limit number of tokens in addition to total size
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
Commit 29c75dd "json-streamer: limit the maximum recursion depth and
|
16
|
+
maximum token count" attempts to guard against excessive heap usage by
|
17
|
+
limiting total token size (it says "token count", but that's a lie).
|
18
|
+
|
19
|
+
Total token size is a rather imprecise predictor of heap usage: many
|
20
|
+
small tokens use more space than few large tokens with the same input
|
21
|
+
size, because there's a constant per-token overhead: 37 bytes on my
|
22
|
+
system.
|
23
|
+
|
24
|
+
Tighten this up: limit the token count to 2Mi. Chosen to roughly
|
25
|
+
match the 64MiB total token size limit.
|
26
|
+
|
27
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
28
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
29
|
+
Message-Id: <1448486613-17634-13-git-send-email-armbru@redhat.com>
|
30
|
+
(cherry picked from commit df649835fe48f635a93316fdefe96ced7189316e)
|
31
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
32
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
33
|
+
---
|
34
|
+
qobject/json-streamer.c | 2 ++
|
35
|
+
1 file changed, 2 insertions(+)
|
36
|
+
|
37
|
+
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
|
38
|
+
index e87230d..a4db4b8 100644
|
39
|
+
--- a/qobject/json-streamer.c
|
40
|
+
+++ b/qobject/json-streamer.c
|
41
|
+
|
42
|
+
#include "qapi/qmp/json-streamer.h"
|
43
|
+
|
44
|
+
#define MAX_TOKEN_SIZE (64ULL << 20)
|
45
|
+
+#define MAX_TOKEN_COUNT (2ULL << 20)
|
46
|
+
#define MAX_NESTING (1ULL << 10)
|
47
|
+
|
48
|
+
static void json_message_free_tokens(JSONMessageParser *parser)
|
49
|
+
@@ -68,6 +69,7 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
|
50
|
+
parser->bracket_count == 0)) {
|
51
|
+
goto out_emit;
|
52
|
+
} else if (parser->token_size > MAX_TOKEN_SIZE ||
|
53
|
+
+ g_queue_get_length(parser->tokens) > MAX_TOKEN_COUNT ||
|
54
|
+
parser->bracket_count + parser->brace_count > MAX_NESTING) {
|
55
|
+
/* Security consideration, we limit total memory allocated per object
|
56
|
+
* and the maximum recursion depth that a message can force.
|
57
|
+
--
|
58
|
+
1.8.3.1
|
59
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
From c4c2e01b3fa861de40f809785a0643d56e2b311e Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:03 +0200
|
4
|
+
Subject: [PATCH 05/16] qjson: Spell out some silent assumptions
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-7-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71473
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 05/15] qjson: Spell out some silent assumptions
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
16
|
+
Message-Id: <1448486613-17634-5-git-send-email-armbru@redhat.com>
|
17
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
18
|
+
(cherry picked from commit b8d3b1da3cdbb02e180618d6be346c564723015d)
|
19
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
20
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
21
|
+
---
|
22
|
+
include/qapi/qmp/json-lexer.h | 3 ++-
|
23
|
+
qobject/json-lexer.c | 7 ++++++-
|
24
|
+
2 files changed, 8 insertions(+), 2 deletions(-)
|
25
|
+
|
26
|
+
diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h
|
27
|
+
index cdff046..61a143f 100644
|
28
|
+
--- a/include/qapi/qmp/json-lexer.h
|
29
|
+
+++ b/include/qapi/qmp/json-lexer.h
|
30
|
+
|
31
|
+
#include "qapi/qmp/qlist.h"
|
32
|
+
|
33
|
+
typedef enum json_token_type {
|
34
|
+
- JSON_OPERATOR = 100,
|
35
|
+
+ JSON_MIN = 100,
|
36
|
+
+ JSON_OPERATOR = JSON_MIN,
|
37
|
+
JSON_INTEGER,
|
38
|
+
JSON_FLOAT,
|
39
|
+
JSON_KEYWORD,
|
40
|
+
diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
|
41
|
+
index 440df60..f106ffb 100644
|
42
|
+
--- a/qobject/json-lexer.c
|
43
|
+
+++ b/qobject/json-lexer.c
|
44
|
+
|
45
|
+
*/
|
46
|
+
|
47
|
+
enum json_lexer_state {
|
48
|
+
- IN_ERROR = 0,
|
49
|
+
+ IN_ERROR = 0, /* must really be 0, see json_lexer[] */
|
50
|
+
IN_DQ_UCODE3,
|
51
|
+
IN_DQ_UCODE2,
|
52
|
+
IN_DQ_UCODE1,
|
53
|
+
@@ -62,6 +62,8 @@ enum json_lexer_state {
|
54
|
+
IN_START,
|
55
|
+
};
|
56
|
+
|
57
|
+
+QEMU_BUILD_BUG_ON((int)JSON_MIN <= (int)IN_START);
|
58
|
+
+
|
59
|
+
#define TERMINAL(state) [0 ... 0x7F] = (state)
|
60
|
+
|
61
|
+
/* Return whether TERMINAL is a terminal state and the transition to it
|
62
|
+
@@ -71,6 +73,8 @@ enum json_lexer_state {
|
63
|
+
(json_lexer[(old_state)][0] == (terminal))
|
64
|
+
|
65
|
+
static const uint8_t json_lexer[][256] = {
|
66
|
+
+ /* Relies on default initialization to IN_ERROR! */
|
67
|
+
+
|
68
|
+
/* double quote string */
|
69
|
+
[IN_DQ_UCODE3] = {
|
70
|
+
['0' ... '9'] = IN_DQ_STRING,
|
71
|
+
@@ -287,6 +291,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
|
72
|
+
}
|
73
|
+
|
74
|
+
do {
|
75
|
+
+ assert(lexer->state <= ARRAY_SIZE(json_lexer));
|
76
|
+
new_state = json_lexer[lexer->state][(uint8_t)ch];
|
77
|
+
char_consumed = !TERMINAL_NEEDED_LOOKAHEAD(lexer->state, new_state);
|
78
|
+
if (char_consumed) {
|
79
|
+
--
|
80
|
+
1.8.3.1
|
81
|
+
|
@@ -0,0 +1,195 @@
|
|
1
|
+
From 39da81cf143ccc400263362a5319803063ad14cf Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:07 +0200
|
4
|
+
Subject: [PATCH 09/16] qjson: replace QString in JSONLexer with GString
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-11-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71480
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 09/15] qjson: replace QString in JSONLexer with GString
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Paolo Bonzini <pbonzini@redhat.com>
|
16
|
+
|
17
|
+
JSONLexer only needs a simple resizable buffer. json-streamer.c
|
18
|
+
can allocate memory for each token instead of relying on reference
|
19
|
+
counting of QStrings.
|
20
|
+
|
21
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
22
|
+
Message-Id: <1448300659-23559-2-git-send-email-pbonzini@redhat.com>
|
23
|
+
[Straightforwardly rebased on my patches, checkpatch made happy]
|
24
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
25
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
26
|
+
(cherry picked from commit d2ca7c0b0d876cf0e219ae7a92252626b0913a28)
|
27
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
28
|
+
|
29
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
30
|
+
---
|
31
|
+
include/qapi/qmp/json-lexer.h | 8 ++++----
|
32
|
+
include/qapi/qmp/json-streamer.h | 1 +
|
33
|
+
qobject/json-lexer.c | 22 ++++++++--------------
|
34
|
+
qobject/json-streamer.c | 9 +++++----
|
35
|
+
4 files changed, 18 insertions(+), 22 deletions(-)
|
36
|
+
|
37
|
+
diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h
|
38
|
+
index f3e8dc7..cb456d5 100644
|
39
|
+
--- a/include/qapi/qmp/json-lexer.h
|
40
|
+
+++ b/include/qapi/qmp/json-lexer.h
|
41
|
+
|
42
|
+
#ifndef QEMU_JSON_LEXER_H
|
43
|
+
#define QEMU_JSON_LEXER_H
|
44
|
+
|
45
|
+
-#include "qapi/qmp/qstring.h"
|
46
|
+
-#include "qapi/qmp/qlist.h"
|
47
|
+
+#include "glib-compat.h"
|
48
|
+
|
49
|
+
typedef enum json_token_type {
|
50
|
+
JSON_MIN = 100,
|
51
|
+
@@ -36,13 +35,14 @@ typedef enum json_token_type {
|
52
|
+
|
53
|
+
typedef struct JSONLexer JSONLexer;
|
54
|
+
|
55
|
+
-typedef void (JSONLexerEmitter)(JSONLexer *, QString *, JSONTokenType, int x, int y);
|
56
|
+
+typedef void (JSONLexerEmitter)(JSONLexer *, GString *,
|
57
|
+
+ JSONTokenType, int x, int y);
|
58
|
+
|
59
|
+
struct JSONLexer
|
60
|
+
{
|
61
|
+
JSONLexerEmitter *emit;
|
62
|
+
int state;
|
63
|
+
- QString *token;
|
64
|
+
+ GString *token;
|
65
|
+
int x, y;
|
66
|
+
};
|
67
|
+
|
68
|
+
diff --git a/include/qapi/qmp/json-streamer.h b/include/qapi/qmp/json-streamer.h
|
69
|
+
index 823f7d7..e901144 100644
|
70
|
+
--- a/include/qapi/qmp/json-streamer.h
|
71
|
+
+++ b/include/qapi/qmp/json-streamer.h
|
72
|
+
|
73
|
+
#ifndef QEMU_JSON_STREAMER_H
|
74
|
+
#define QEMU_JSON_STREAMER_H
|
75
|
+
|
76
|
+
+#include <stdint.h>
|
77
|
+
#include "qapi/qmp/qlist.h"
|
78
|
+
#include "qapi/qmp/json-lexer.h"
|
79
|
+
|
80
|
+
diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
|
81
|
+
index 1bfff02..b89e24f 100644
|
82
|
+
--- a/qobject/json-lexer.c
|
83
|
+
+++ b/qobject/json-lexer.c
|
84
|
+
|
85
|
+
*
|
86
|
+
*/
|
87
|
+
|
88
|
+
-#include "qapi/qmp/qstring.h"
|
89
|
+
-#include "qapi/qmp/qlist.h"
|
90
|
+
-#include "qapi/qmp/qdict.h"
|
91
|
+
-#include "qapi/qmp/qint.h"
|
92
|
+
#include "qemu-common.h"
|
93
|
+
#include "qapi/qmp/json-lexer.h"
|
94
|
+
+#include <stdint.h>
|
95
|
+
|
96
|
+
#define MAX_TOKEN_SIZE (64ULL << 20)
|
97
|
+
|
98
|
+
@@ -276,7 +273,7 @@ void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func)
|
99
|
+
{
|
100
|
+
lexer->emit = func;
|
101
|
+
lexer->state = IN_START;
|
102
|
+
- lexer->token = qstring_new();
|
103
|
+
+ lexer->token = g_string_sized_new(3);
|
104
|
+
lexer->x = lexer->y = 0;
|
105
|
+
}
|
106
|
+
|
107
|
+
@@ -295,7 +292,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
|
108
|
+
new_state = json_lexer[lexer->state][(uint8_t)ch];
|
109
|
+
char_consumed = !TERMINAL_NEEDED_LOOKAHEAD(lexer->state, new_state);
|
110
|
+
if (char_consumed) {
|
111
|
+
- qstring_append_chr(lexer->token, ch);
|
112
|
+
+ g_string_append_c(lexer->token, ch);
|
113
|
+
}
|
114
|
+
|
115
|
+
switch (new_state) {
|
116
|
+
@@ -313,8 +310,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
|
117
|
+
lexer->emit(lexer, lexer->token, new_state, lexer->x, lexer->y);
|
118
|
+
/* fall through */
|
119
|
+
case JSON_SKIP:
|
120
|
+
- QDECREF(lexer->token);
|
121
|
+
- lexer->token = qstring_new();
|
122
|
+
+ g_string_truncate(lexer->token, 0);
|
123
|
+
new_state = IN_START;
|
124
|
+
break;
|
125
|
+
case IN_ERROR:
|
126
|
+
@@ -332,8 +328,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
|
127
|
+
* induce an error/flush state.
|
128
|
+
*/
|
129
|
+
lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y);
|
130
|
+
- QDECREF(lexer->token);
|
131
|
+
- lexer->token = qstring_new();
|
132
|
+
+ g_string_truncate(lexer->token, 0);
|
133
|
+
new_state = IN_START;
|
134
|
+
lexer->state = new_state;
|
135
|
+
return 0;
|
136
|
+
@@ -346,10 +341,9 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
|
137
|
+
/* Do not let a single token grow to an arbitrarily large size,
|
138
|
+
* this is a security consideration.
|
139
|
+
*/
|
140
|
+
- if (lexer->token->length > MAX_TOKEN_SIZE) {
|
141
|
+
+ if (lexer->token->len > MAX_TOKEN_SIZE) {
|
142
|
+
lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y);
|
143
|
+
- QDECREF(lexer->token);
|
144
|
+
- lexer->token = qstring_new();
|
145
|
+
+ g_string_truncate(lexer->token, 0);
|
146
|
+
lexer->state = IN_START;
|
147
|
+
}
|
148
|
+
|
149
|
+
@@ -379,5 +373,5 @@ int json_lexer_flush(JSONLexer *lexer)
|
150
|
+
|
151
|
+
void json_lexer_destroy(JSONLexer *lexer)
|
152
|
+
{
|
153
|
+
- QDECREF(lexer->token);
|
154
|
+
+ g_string_free(lexer->token, true);
|
155
|
+
}
|
156
|
+
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
|
157
|
+
index 4a161a1..7292f3a 100644
|
158
|
+
--- a/qobject/json-streamer.c
|
159
|
+
+++ b/qobject/json-streamer.c
|
160
|
+
|
161
|
+
*/
|
162
|
+
|
163
|
+
#include "qapi/qmp/qlist.h"
|
164
|
+
+#include "qapi/qmp/qstring.h"
|
165
|
+
#include "qapi/qmp/qint.h"
|
166
|
+
#include "qapi/qmp/qdict.h"
|
167
|
+
#include "qemu-common.h"
|
168
|
+
|
169
|
+
#define MAX_TOKEN_SIZE (64ULL << 20)
|
170
|
+
#define MAX_NESTING (1ULL << 10)
|
171
|
+
|
172
|
+
-static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y)
|
173
|
+
+static void json_message_process_token(JSONLexer *lexer, GString *input,
|
174
|
+
+ JSONTokenType type, int x, int y)
|
175
|
+
{
|
176
|
+
JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
|
177
|
+
QDict *dict;
|
178
|
+
@@ -45,12 +47,11 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok
|
179
|
+
|
180
|
+
dict = qdict_new();
|
181
|
+
qdict_put(dict, "type", qint_from_int(type));
|
182
|
+
- QINCREF(token);
|
183
|
+
- qdict_put(dict, "token", token);
|
184
|
+
+ qdict_put(dict, "token", qstring_from_str(input->str));
|
185
|
+
qdict_put(dict, "x", qint_from_int(x));
|
186
|
+
qdict_put(dict, "y", qint_from_int(y));
|
187
|
+
|
188
|
+
- parser->token_size += token->length;
|
189
|
+
+ parser->token_size += input->len;
|
190
|
+
|
191
|
+
qlist_append(parser->tokens, dict);
|
192
|
+
|
193
|
+
--
|
194
|
+
1.8.3.1
|
195
|
+
|
@@ -0,0 +1,332 @@
|
|
1
|
+
From 88ee76fed6344de6cede3bfbb3873423e9a90333 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:09 +0200
|
4
|
+
Subject: [PATCH 11/16] qjson: store tokens in a GQueue
|
5
|
+
|
6
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
7
|
+
Message-id: <1469604913-12442-13-git-send-email-armbru@redhat.com>
|
8
|
+
Patchwork-id: 71478
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 11/15] qjson: store tokens in a GQueue
|
10
|
+
Bugzilla: 1276036
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Paolo Bonzini <pbonzini@redhat.com>
|
16
|
+
|
17
|
+
Even though we still have the "streamer" concept, the tokens can now
|
18
|
+
be deleted as they are read. While doing so convert from QList to
|
19
|
+
GQueue, since the next step will make tokens not a QObject and we
|
20
|
+
will have to do the conversion anyway.
|
21
|
+
|
22
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
23
|
+
Message-Id: <1448300659-23559-4-git-send-email-pbonzini@redhat.com>
|
24
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
25
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
26
|
+
(cherry picked from commit 95385fe9ace7db156b924da6b6f5c9082b68ba68)
|
27
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
28
|
+
|
29
|
+
Conflicts:
|
30
|
+
monitor.c
|
31
|
+
|
32
|
+
Trivial context difference because we lack a small cleanup part of the
|
33
|
+
(fairly invasive) series b821cbe..489653b.
|
34
|
+
|
35
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
36
|
+
---
|
37
|
+
include/qapi/qmp/json-parser.h | 4 +--
|
38
|
+
include/qapi/qmp/json-streamer.h | 8 ++---
|
39
|
+
monitor.c | 2 +-
|
40
|
+
qga/main.c | 2 +-
|
41
|
+
qobject/json-parser.c | 65 +++++++++++++---------------------------
|
42
|
+
qobject/json-streamer.c | 25 +++++++++-------
|
43
|
+
qobject/qjson.c | 2 +-
|
44
|
+
tests/libqtest.c | 2 +-
|
45
|
+
8 files changed, 45 insertions(+), 65 deletions(-)
|
46
|
+
|
47
|
+
diff --git a/include/qapi/qmp/json-parser.h b/include/qapi/qmp/json-parser.h
|
48
|
+
index 44d88f3..fea89f8 100644
|
49
|
+
--- a/include/qapi/qmp/json-parser.h
|
50
|
+
+++ b/include/qapi/qmp/json-parser.h
|
51
|
+
|
52
|
+
#include "qapi/qmp/qlist.h"
|
53
|
+
#include "qapi/error.h"
|
54
|
+
|
55
|
+
-QObject *json_parser_parse(QList *tokens, va_list *ap);
|
56
|
+
-QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp);
|
57
|
+
+QObject *json_parser_parse(GQueue *tokens, va_list *ap);
|
58
|
+
+QObject *json_parser_parse_err(GQueue *tokens, va_list *ap, Error **errp);
|
59
|
+
|
60
|
+
#endif
|
61
|
+
diff --git a/include/qapi/qmp/json-streamer.h b/include/qapi/qmp/json-streamer.h
|
62
|
+
index e901144..e9f2937 100644
|
63
|
+
--- a/include/qapi/qmp/json-streamer.h
|
64
|
+
+++ b/include/qapi/qmp/json-streamer.h
|
65
|
+
|
66
|
+
#define QEMU_JSON_STREAMER_H
|
67
|
+
|
68
|
+
#include <stdint.h>
|
69
|
+
-#include "qapi/qmp/qlist.h"
|
70
|
+
+#include "glib-compat.h"
|
71
|
+
#include "qapi/qmp/json-lexer.h"
|
72
|
+
|
73
|
+
typedef struct JSONMessageParser
|
74
|
+
{
|
75
|
+
- void (*emit)(struct JSONMessageParser *parser, QList *tokens);
|
76
|
+
+ void (*emit)(struct JSONMessageParser *parser, GQueue *tokens);
|
77
|
+
JSONLexer lexer;
|
78
|
+
int brace_count;
|
79
|
+
int bracket_count;
|
80
|
+
- QList *tokens;
|
81
|
+
+ GQueue *tokens;
|
82
|
+
uint64_t token_size;
|
83
|
+
} JSONMessageParser;
|
84
|
+
|
85
|
+
void json_message_parser_init(JSONMessageParser *parser,
|
86
|
+
- void (*func)(JSONMessageParser *, QList *));
|
87
|
+
+ void (*func)(JSONMessageParser *, GQueue *));
|
88
|
+
|
89
|
+
int json_message_parser_feed(JSONMessageParser *parser,
|
90
|
+
const char *buffer, size_t size);
|
91
|
+
diff --git a/monitor.c b/monitor.c
|
92
|
+
index 33c5bc8..1b28ff3 100644
|
93
|
+
--- a/monitor.c
|
94
|
+
+++ b/monitor.c
|
95
|
+
@@ -4514,7 +4514,7 @@ static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd,
|
96
|
+
qobject_decref(data);
|
97
|
+
}
|
98
|
+
|
99
|
+
-static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
|
100
|
+
+static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
|
101
|
+
{
|
102
|
+
int err;
|
103
|
+
QObject *obj;
|
104
|
+
diff --git a/qga/main.c b/qga/main.c
|
105
|
+
index 0e04e73..7e8f9a0 100644
|
106
|
+
--- a/qga/main.c
|
107
|
+
+++ b/qga/main.c
|
108
|
+
@@ -569,7 +569,7 @@ static void process_command(GAState *s, QDict *req)
|
109
|
+
}
|
110
|
+
|
111
|
+
/* handle requests/control events coming in over the channel */
|
112
|
+
-static void process_event(JSONMessageParser *parser, QList *tokens)
|
113
|
+
+static void process_event(JSONMessageParser *parser, GQueue *tokens)
|
114
|
+
{
|
115
|
+
GAState *s = container_of(parser, GAState, parser);
|
116
|
+
QObject *obj;
|
117
|
+
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
|
118
|
+
index b242fba..6e5e257 100644
|
119
|
+
--- a/qobject/json-parser.c
|
120
|
+
+++ b/qobject/json-parser.c
|
121
|
+
|
122
|
+
typedef struct JSONParserContext
|
123
|
+
{
|
124
|
+
Error *err;
|
125
|
+
- struct {
|
126
|
+
- QObject **buf;
|
127
|
+
- size_t pos;
|
128
|
+
- size_t count;
|
129
|
+
- } tokens;
|
130
|
+
+ QObject *current;
|
131
|
+
+ GQueue *buf;
|
132
|
+
} JSONParserContext;
|
133
|
+
|
134
|
+
#define BUG_ON(cond) assert(!(cond))
|
135
|
+
@@ -244,56 +241,34 @@ out:
|
136
|
+
return NULL;
|
137
|
+
}
|
138
|
+
|
139
|
+
+/* Note: unless the token object returned by parser_context_peek_token
|
140
|
+
+ * or parser_context_pop_token is explicitly incref'd, it will be
|
141
|
+
+ * deleted as soon as parser_context_pop_token is called again.
|
142
|
+
+ */
|
143
|
+
static QObject *parser_context_pop_token(JSONParserContext *ctxt)
|
144
|
+
{
|
145
|
+
- QObject *token;
|
146
|
+
- g_assert(ctxt->tokens.pos < ctxt->tokens.count);
|
147
|
+
- token = ctxt->tokens.buf[ctxt->tokens.pos];
|
148
|
+
- ctxt->tokens.pos++;
|
149
|
+
- return token;
|
150
|
+
+ qobject_decref(ctxt->current);
|
151
|
+
+ assert(!g_queue_is_empty(ctxt->buf));
|
152
|
+
+ ctxt->current = g_queue_pop_head(ctxt->buf);
|
153
|
+
+ return ctxt->current;
|
154
|
+
}
|
155
|
+
|
156
|
+
-/* Note: parser_context_{peek|pop}_token do not increment the
|
157
|
+
- * token object's refcount. In both cases the references will continue
|
158
|
+
- * to be tracked and cleaned up in parser_context_free(), so do not
|
159
|
+
- * attempt to free the token object.
|
160
|
+
- */
|
161
|
+
static QObject *parser_context_peek_token(JSONParserContext *ctxt)
|
162
|
+
{
|
163
|
+
- QObject *token;
|
164
|
+
- g_assert(ctxt->tokens.pos < ctxt->tokens.count);
|
165
|
+
- token = ctxt->tokens.buf[ctxt->tokens.pos];
|
166
|
+
- return token;
|
167
|
+
-}
|
168
|
+
-
|
169
|
+
-static void tokens_append_from_iter(QObject *obj, void *opaque)
|
170
|
+
-{
|
171
|
+
- JSONParserContext *ctxt = opaque;
|
172
|
+
- g_assert(ctxt->tokens.pos < ctxt->tokens.count);
|
173
|
+
- ctxt->tokens.buf[ctxt->tokens.pos++] = obj;
|
174
|
+
- qobject_incref(obj);
|
175
|
+
+ assert(!g_queue_is_empty(ctxt->buf));
|
176
|
+
+ return g_queue_peek_head(ctxt->buf);
|
177
|
+
}
|
178
|
+
|
179
|
+
-static JSONParserContext *parser_context_new(QList *tokens)
|
180
|
+
+static JSONParserContext *parser_context_new(GQueue *tokens)
|
181
|
+
{
|
182
|
+
JSONParserContext *ctxt;
|
183
|
+
- size_t count;
|
184
|
+
|
185
|
+
if (!tokens) {
|
186
|
+
return NULL;
|
187
|
+
}
|
188
|
+
|
189
|
+
- count = qlist_size(tokens);
|
190
|
+
- if (count == 0) {
|
191
|
+
- return NULL;
|
192
|
+
- }
|
193
|
+
-
|
194
|
+
ctxt = g_malloc0(sizeof(JSONParserContext));
|
195
|
+
- ctxt->tokens.pos = 0;
|
196
|
+
- ctxt->tokens.count = count;
|
197
|
+
- ctxt->tokens.buf = g_malloc(count * sizeof(QObject *));
|
198
|
+
- qlist_iter(tokens, tokens_append_from_iter, ctxt);
|
199
|
+
- ctxt->tokens.pos = 0;
|
200
|
+
+ ctxt->buf = tokens;
|
201
|
+
|
202
|
+
return ctxt;
|
203
|
+
}
|
204
|
+
@@ -301,12 +276,12 @@ static JSONParserContext *parser_context_new(QList *tokens)
|
205
|
+
/* to support error propagation, ctxt->err must be freed separately */
|
206
|
+
static void parser_context_free(JSONParserContext *ctxt)
|
207
|
+
{
|
208
|
+
- int i;
|
209
|
+
if (ctxt) {
|
210
|
+
- for (i = 0; i < ctxt->tokens.count; i++) {
|
211
|
+
- qobject_decref(ctxt->tokens.buf[i]);
|
212
|
+
+ while (!g_queue_is_empty(ctxt->buf)) {
|
213
|
+
+ parser_context_pop_token(ctxt);
|
214
|
+
}
|
215
|
+
- g_free(ctxt->tokens.buf);
|
216
|
+
+ qobject_decref(ctxt->current);
|
217
|
+
+ g_queue_free(ctxt->buf);
|
218
|
+
g_free(ctxt);
|
219
|
+
}
|
220
|
+
}
|
221
|
+
@@ -597,12 +572,12 @@ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
-QObject *json_parser_parse(QList *tokens, va_list *ap)
|
226
|
+
+QObject *json_parser_parse(GQueue *tokens, va_list *ap)
|
227
|
+
{
|
228
|
+
return json_parser_parse_err(tokens, ap, NULL);
|
229
|
+
}
|
230
|
+
|
231
|
+
-QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp)
|
232
|
+
+QObject *json_parser_parse_err(GQueue *tokens, va_list *ap, Error **errp)
|
233
|
+
{
|
234
|
+
JSONParserContext *ctxt = parser_context_new(tokens);
|
235
|
+
QObject *result;
|
236
|
+
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
|
237
|
+
index 7292f3a..f7a3e78 100644
|
238
|
+
--- a/qobject/json-streamer.c
|
239
|
+
+++ b/qobject/json-streamer.c
|
240
|
+
|
241
|
+
#define MAX_TOKEN_SIZE (64ULL << 20)
|
242
|
+
#define MAX_NESTING (1ULL << 10)
|
243
|
+
|
244
|
+
+static void json_message_free_tokens(JSONMessageParser *parser)
|
245
|
+
+{
|
246
|
+
+ if (parser->tokens) {
|
247
|
+
+ g_queue_free(parser->tokens);
|
248
|
+
+ parser->tokens = NULL;
|
249
|
+
+ }
|
250
|
+
+}
|
251
|
+
+
|
252
|
+
static void json_message_process_token(JSONLexer *lexer, GString *input,
|
253
|
+
JSONTokenType type, int x, int y)
|
254
|
+
{
|
255
|
+
@@ -53,7 +61,7 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
|
256
|
+
|
257
|
+
parser->token_size += input->len;
|
258
|
+
|
259
|
+
- qlist_append(parser->tokens, dict);
|
260
|
+
+ g_queue_push_tail(parser->tokens, dict);
|
261
|
+
|
262
|
+
if (type == JSON_ERROR) {
|
263
|
+
goto out_emit_bad;
|
264
|
+
@@ -77,27 +85,24 @@ out_emit_bad:
|
265
|
+
* Clear out token list and tell the parser to emit an error
|
266
|
+
* indication by passing it a NULL list
|
267
|
+
*/
|
268
|
+
- QDECREF(parser->tokens);
|
269
|
+
- parser->tokens = NULL;
|
270
|
+
+ json_message_free_tokens(parser);
|
271
|
+
out_emit:
|
272
|
+
/* send current list of tokens to parser and reset tokenizer */
|
273
|
+
parser->brace_count = 0;
|
274
|
+
parser->bracket_count = 0;
|
275
|
+
+ /* parser->emit takes ownership of parser->tokens. */
|
276
|
+
parser->emit(parser, parser->tokens);
|
277
|
+
- if (parser->tokens) {
|
278
|
+
- QDECREF(parser->tokens);
|
279
|
+
- }
|
280
|
+
- parser->tokens = qlist_new();
|
281
|
+
+ parser->tokens = g_queue_new();
|
282
|
+
parser->token_size = 0;
|
283
|
+
}
|
284
|
+
|
285
|
+
void json_message_parser_init(JSONMessageParser *parser,
|
286
|
+
- void (*func)(JSONMessageParser *, QList *))
|
287
|
+
+ void (*func)(JSONMessageParser *, GQueue *))
|
288
|
+
{
|
289
|
+
parser->emit = func;
|
290
|
+
parser->brace_count = 0;
|
291
|
+
parser->bracket_count = 0;
|
292
|
+
- parser->tokens = qlist_new();
|
293
|
+
+ parser->tokens = g_queue_new();
|
294
|
+
parser->token_size = 0;
|
295
|
+
|
296
|
+
json_lexer_init(&parser->lexer, json_message_process_token);
|
297
|
+
@@ -117,5 +122,5 @@ int json_message_parser_flush(JSONMessageParser *parser)
|
298
|
+
void json_message_parser_destroy(JSONMessageParser *parser)
|
299
|
+
{
|
300
|
+
json_lexer_destroy(&parser->lexer);
|
301
|
+
- QDECREF(parser->tokens);
|
302
|
+
+ json_message_free_tokens(parser);
|
303
|
+
}
|
304
|
+
diff --git a/qobject/qjson.c b/qobject/qjson.c
|
305
|
+
index 6cf2511..fdc274a 100644
|
306
|
+
--- a/qobject/qjson.c
|
307
|
+
+++ b/qobject/qjson.c
|
308
|
+
@@ -28,7 +28,7 @@ typedef struct JSONParsingState
|
309
|
+
QObject *result;
|
310
|
+
} JSONParsingState;
|
311
|
+
|
312
|
+
-static void parse_json(JSONMessageParser *parser, QList *tokens)
|
313
|
+
+static void parse_json(JSONMessageParser *parser, GQueue *tokens)
|
314
|
+
{
|
315
|
+
JSONParsingState *s = container_of(parser, JSONParsingState, parser);
|
316
|
+
s->result = json_parser_parse(tokens, s->ap);
|
317
|
+
diff --git a/tests/libqtest.c b/tests/libqtest.c
|
318
|
+
index 359d571..69b7cd6 100644
|
319
|
+
--- a/tests/libqtest.c
|
320
|
+
+++ b/tests/libqtest.c
|
321
|
+
@@ -299,7 +299,7 @@ typedef struct {
|
322
|
+
QDict *response;
|
323
|
+
} QMPResponseParser;
|
324
|
+
|
325
|
+
-static void qmp_response(JSONMessageParser *parser, QList *tokens)
|
326
|
+
+static void qmp_response(JSONMessageParser *parser, GQueue *tokens)
|
327
|
+
{
|
328
|
+
QMPResponseParser *qmp = container_of(parser, QMPResponseParser, parser);
|
329
|
+
QObject *obj;
|
330
|
+
--
|
331
|
+
1.8.3.1
|
332
|
+
|
@@ -0,0 +1,412 @@
|
|
1
|
+
From 7bef5fab7d59aa9a6a1eb6ea747ba04811bc01e2 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Markus Armbruster <armbru@redhat.com>
|
3
|
+
Date: Wed, 27 Jul 2016 07:35:10 +0200
|
4
|
+
Subject: [PATCH 12/16] qjson: surprise, allocating 6 QObjects per token is
|
5
|
+
expensive
|
6
|
+
|
7
|
+
RH-Author: Markus Armbruster <armbru@redhat.com>
|
8
|
+
Message-id: <1469604913-12442-14-git-send-email-armbru@redhat.com>
|
9
|
+
Patchwork-id: 71475
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 12/15] qjson: surprise, allocating 6 QObjects per token is expensive
|
11
|
+
Bugzilla: 1276036
|
12
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
13
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
14
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
15
|
+
|
16
|
+
From: Paolo Bonzini <pbonzini@redhat.com>
|
17
|
+
|
18
|
+
Replace the contents of the tokens GQueue with a simple struct. This cuts
|
19
|
+
the amount of memory allocated by tests/check-qjson from ~500MB to ~20MB,
|
20
|
+
and the execution time from 600ms to 80ms on my laptop. Still a lot (some
|
21
|
+
could be saved by using an intrusive list, such as QSIMPLEQ, instead of
|
22
|
+
the GQueue), but the savings are already massive and the right thing to
|
23
|
+
do would probably be to get rid of json-streamer completely.
|
24
|
+
|
25
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
26
|
+
Message-Id: <1448300659-23559-5-git-send-email-pbonzini@redhat.com>
|
27
|
+
[Straightforwardly rebased on my patches]
|
28
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
29
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
30
|
+
(cherry picked from commit 9bada8971173345ceb37ed1a47b00a01a4dd48cf)
|
31
|
+
|
32
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
33
|
+
|
34
|
+
Conflicts:
|
35
|
+
qobject/json-parser.c
|
36
|
+
|
37
|
+
Straighforward conflicts because lacking commit fc48ffc "qobject: Use
|
38
|
+
'bool' for qbool", we still use qbool_from_int(), and we lack commit
|
39
|
+
e549e71 "json-parser: Accept 'null' in QMP".
|
40
|
+
|
41
|
+
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
42
|
+
---
|
43
|
+
include/qapi/qmp/json-streamer.h | 7 +++
|
44
|
+
qobject/json-parser.c | 113 ++++++++++++++++-----------------------
|
45
|
+
qobject/json-streamer.c | 19 +++----
|
46
|
+
3 files changed, 62 insertions(+), 77 deletions(-)
|
47
|
+
|
48
|
+
diff --git a/include/qapi/qmp/json-streamer.h b/include/qapi/qmp/json-streamer.h
|
49
|
+
index e9f2937..09b3d3e 100644
|
50
|
+
--- a/include/qapi/qmp/json-streamer.h
|
51
|
+
+++ b/include/qapi/qmp/json-streamer.h
|
52
|
+
|
53
|
+
#include "glib-compat.h"
|
54
|
+
#include "qapi/qmp/json-lexer.h"
|
55
|
+
|
56
|
+
+typedef struct JSONToken {
|
57
|
+
+ int type;
|
58
|
+
+ int x;
|
59
|
+
+ int y;
|
60
|
+
+ char str[];
|
61
|
+
+} JSONToken;
|
62
|
+
+
|
63
|
+
typedef struct JSONMessageParser
|
64
|
+
{
|
65
|
+
void (*emit)(struct JSONMessageParser *parser, GQueue *tokens);
|
66
|
+
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
|
67
|
+
index 6e5e257..944e1a1 100644
|
68
|
+
--- a/qobject/json-parser.c
|
69
|
+
+++ b/qobject/json-parser.c
|
70
|
+
|
71
|
+
#include "qapi/qmp/json-parser.h"
|
72
|
+
#include "qapi/qmp/json-lexer.h"
|
73
|
+
#include "qapi/qmp/qerror.h"
|
74
|
+
+#include "qapi/qmp/json-streamer.h"
|
75
|
+
|
76
|
+
typedef struct JSONParserContext
|
77
|
+
{
|
78
|
+
Error *err;
|
79
|
+
- QObject *current;
|
80
|
+
+ JSONToken *current;
|
81
|
+
GQueue *buf;
|
82
|
+
} JSONParserContext;
|
83
|
+
|
84
|
+
@@ -45,27 +46,10 @@ typedef struct JSONParserContext
|
85
|
+
static QObject *parse_value(JSONParserContext *ctxt, va_list *ap);
|
86
|
+
|
87
|
+
/**
|
88
|
+
- * Token manipulators
|
89
|
+
- *
|
90
|
+
- * tokens are dictionaries that contain a type, a string value, and geometry information
|
91
|
+
- * about a token identified by the lexer. These are routines that make working with
|
92
|
+
- * these objects a bit easier.
|
93
|
+
- */
|
94
|
+
-static const char *token_get_value(QObject *obj)
|
95
|
+
-{
|
96
|
+
- return qdict_get_str(qobject_to_qdict(obj), "token");
|
97
|
+
-}
|
98
|
+
-
|
99
|
+
-static JSONTokenType token_get_type(QObject *obj)
|
100
|
+
-{
|
101
|
+
- return qdict_get_int(qobject_to_qdict(obj), "type");
|
102
|
+
-}
|
103
|
+
-
|
104
|
+
-/**
|
105
|
+
* Error handler
|
106
|
+
*/
|
107
|
+
static void GCC_FMT_ATTR(3, 4) parse_error(JSONParserContext *ctxt,
|
108
|
+
- QObject *token, const char *msg, ...)
|
109
|
+
+ JSONToken *token, const char *msg, ...)
|
110
|
+
{
|
111
|
+
va_list ap;
|
112
|
+
char message[1024];
|
113
|
+
@@ -143,9 +127,10 @@ static int hex2decimal(char ch)
|
114
|
+
* \t
|
115
|
+
* \u four-hex-digits
|
116
|
+
*/
|
117
|
+
-static QString *qstring_from_escaped_str(JSONParserContext *ctxt, QObject *token)
|
118
|
+
+static QString *qstring_from_escaped_str(JSONParserContext *ctxt,
|
119
|
+
+ JSONToken *token)
|
120
|
+
{
|
121
|
+
- const char *ptr = token_get_value(token);
|
122
|
+
+ const char *ptr = token->str;
|
123
|
+
QString *str;
|
124
|
+
int double_quote = 1;
|
125
|
+
|
126
|
+
@@ -241,19 +226,19 @@ out:
|
127
|
+
return NULL;
|
128
|
+
}
|
129
|
+
|
130
|
+
-/* Note: unless the token object returned by parser_context_peek_token
|
131
|
+
- * or parser_context_pop_token is explicitly incref'd, it will be
|
132
|
+
- * deleted as soon as parser_context_pop_token is called again.
|
133
|
+
+/* Note: the token object returned by parser_context_peek_token or
|
134
|
+
+ * parser_context_pop_token is deleted as soon as parser_context_pop_token
|
135
|
+
+ * is called again.
|
136
|
+
*/
|
137
|
+
-static QObject *parser_context_pop_token(JSONParserContext *ctxt)
|
138
|
+
+static JSONToken *parser_context_pop_token(JSONParserContext *ctxt)
|
139
|
+
{
|
140
|
+
- qobject_decref(ctxt->current);
|
141
|
+
+ g_free(ctxt->current);
|
142
|
+
assert(!g_queue_is_empty(ctxt->buf));
|
143
|
+
ctxt->current = g_queue_pop_head(ctxt->buf);
|
144
|
+
return ctxt->current;
|
145
|
+
}
|
146
|
+
|
147
|
+
-static QObject *parser_context_peek_token(JSONParserContext *ctxt)
|
148
|
+
+static JSONToken *parser_context_peek_token(JSONParserContext *ctxt)
|
149
|
+
{
|
150
|
+
assert(!g_queue_is_empty(ctxt->buf));
|
151
|
+
return g_queue_peek_head(ctxt->buf);
|
152
|
+
@@ -280,7 +265,7 @@ static void parser_context_free(JSONParserContext *ctxt)
|
153
|
+
while (!g_queue_is_empty(ctxt->buf)) {
|
154
|
+
parser_context_pop_token(ctxt);
|
155
|
+
}
|
156
|
+
- qobject_decref(ctxt->current);
|
157
|
+
+ g_free(ctxt->current);
|
158
|
+
g_queue_free(ctxt->buf);
|
159
|
+
g_free(ctxt);
|
160
|
+
}
|
161
|
+
@@ -291,7 +276,8 @@ static void parser_context_free(JSONParserContext *ctxt)
|
162
|
+
*/
|
163
|
+
static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
|
164
|
+
{
|
165
|
+
- QObject *key = NULL, *token = NULL, *value, *peek;
|
166
|
+
+ QObject *key = NULL, *value;
|
167
|
+
+ JSONToken *peek, *token;
|
168
|
+
|
169
|
+
peek = parser_context_peek_token(ctxt);
|
170
|
+
if (peek == NULL) {
|
171
|
+
@@ -311,7 +297,7 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
|
172
|
+
goto out;
|
173
|
+
}
|
174
|
+
|
175
|
+
- if (token_get_type(token) != JSON_COLON) {
|
176
|
+
+ if (token->type != JSON_COLON) {
|
177
|
+
parse_error(ctxt, token, "missing : in object pair");
|
178
|
+
goto out;
|
179
|
+
}
|
180
|
+
@@ -337,10 +323,10 @@ out:
|
181
|
+
static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
182
|
+
{
|
183
|
+
QDict *dict = NULL;
|
184
|
+
- QObject *token, *peek;
|
185
|
+
+ JSONToken *token, *peek;
|
186
|
+
|
187
|
+
token = parser_context_pop_token(ctxt);
|
188
|
+
- assert(token && token_get_type(token) == JSON_LCURLY);
|
189
|
+
+ assert(token && token->type == JSON_LCURLY);
|
190
|
+
|
191
|
+
dict = qdict_new();
|
192
|
+
|
193
|
+
@@ -350,7 +336,7 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
194
|
+
goto out;
|
195
|
+
}
|
196
|
+
|
197
|
+
- if (token_get_type(peek) != JSON_RCURLY) {
|
198
|
+
+ if (peek->type != JSON_RCURLY) {
|
199
|
+
if (parse_pair(ctxt, dict, ap) == -1) {
|
200
|
+
goto out;
|
201
|
+
}
|
202
|
+
@@ -361,8 +347,8 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
|
203
|
+
goto out;
|
204
|
+
}
|
205
|
+
|
206
|
+
- while (token_get_type(token) != JSON_RCURLY) {
|
207
|
+
- if (token_get_type(token) != JSON_COMMA) {
|
208
|
+
+ while (token->type != JSON_RCURLY) {
|
209
|
+
+ if (token->type != JSON_COMMA) {
|
210
|
+
parse_error(ctxt, token, "expected separator in dict");
|
211
|
+
goto out;
|
212
|
+
}
|
213
|
+
@@ -391,10 +377,10 @@ out:
|
214
|
+
static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
215
|
+
{
|
216
|
+
QList *list = NULL;
|
217
|
+
- QObject *token, *peek;
|
218
|
+
+ JSONToken *token, *peek;
|
219
|
+
|
220
|
+
token = parser_context_pop_token(ctxt);
|
221
|
+
- assert(token && token_get_type(token) == JSON_LSQUARE);
|
222
|
+
+ assert(token && token->type == JSON_LSQUARE);
|
223
|
+
|
224
|
+
list = qlist_new();
|
225
|
+
|
226
|
+
@@ -404,7 +390,7 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
227
|
+
goto out;
|
228
|
+
}
|
229
|
+
|
230
|
+
- if (token_get_type(peek) != JSON_RSQUARE) {
|
231
|
+
+ if (peek->type != JSON_RSQUARE) {
|
232
|
+
QObject *obj;
|
233
|
+
|
234
|
+
obj = parse_value(ctxt, ap);
|
235
|
+
@@ -421,8 +407,8 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
|
236
|
+
goto out;
|
237
|
+
}
|
238
|
+
|
239
|
+
- while (token_get_type(token) != JSON_RSQUARE) {
|
240
|
+
- if (token_get_type(token) != JSON_COMMA) {
|
241
|
+
+ while (token->type != JSON_RSQUARE) {
|
242
|
+
+ if (token->type != JSON_COMMA) {
|
243
|
+
parse_error(ctxt, token, "expected separator in list");
|
244
|
+
goto out;
|
245
|
+
}
|
246
|
+
@@ -454,49 +440,45 @@ out:
|
247
|
+
|
248
|
+
static QObject *parse_keyword(JSONParserContext *ctxt)
|
249
|
+
{
|
250
|
+
- QObject *token;
|
251
|
+
- const char *val;
|
252
|
+
+ JSONToken *token;
|
253
|
+
|
254
|
+
token = parser_context_pop_token(ctxt);
|
255
|
+
- assert(token && token_get_type(token) == JSON_KEYWORD);
|
256
|
+
- val = token_get_value(token);
|
257
|
+
+ assert(token && token->type == JSON_KEYWORD);
|
258
|
+
|
259
|
+
- if (!strcmp(val, "true")) {
|
260
|
+
+ if (!strcmp(token->str, "true")) {
|
261
|
+
return QOBJECT(qbool_from_int(true));
|
262
|
+
- } else if (!strcmp(val, "false")) {
|
263
|
+
+ } else if (!strcmp(token->str, "false")) {
|
264
|
+
return QOBJECT(qbool_from_int(false));
|
265
|
+
}
|
266
|
+
- parse_error(ctxt, token, "invalid keyword '%s'", val);
|
267
|
+
+ parse_error(ctxt, token, "invalid keyword '%s'", token->str);
|
268
|
+
return NULL;
|
269
|
+
}
|
270
|
+
|
271
|
+
static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
|
272
|
+
{
|
273
|
+
- QObject *token;
|
274
|
+
- const char *val;
|
275
|
+
+ JSONToken *token;
|
276
|
+
|
277
|
+
if (ap == NULL) {
|
278
|
+
return NULL;
|
279
|
+
}
|
280
|
+
|
281
|
+
token = parser_context_pop_token(ctxt);
|
282
|
+
- assert(token && token_get_type(token) == JSON_ESCAPE);
|
283
|
+
- val = token_get_value(token);
|
284
|
+
+ assert(token && token->type == JSON_ESCAPE);
|
285
|
+
|
286
|
+
- if (!strcmp(val, "%p")) {
|
287
|
+
+ if (!strcmp(token->str, "%p")) {
|
288
|
+
return va_arg(*ap, QObject *);
|
289
|
+
- } else if (!strcmp(val, "%i")) {
|
290
|
+
+ } else if (!strcmp(token->str, "%i")) {
|
291
|
+
return QOBJECT(qbool_from_int(va_arg(*ap, int)));
|
292
|
+
- } else if (!strcmp(val, "%d")) {
|
293
|
+
+ } else if (!strcmp(token->str, "%d")) {
|
294
|
+
return QOBJECT(qint_from_int(va_arg(*ap, int)));
|
295
|
+
- } else if (!strcmp(val, "%ld")) {
|
296
|
+
+ } else if (!strcmp(token->str, "%ld")) {
|
297
|
+
return QOBJECT(qint_from_int(va_arg(*ap, long)));
|
298
|
+
- } else if (!strcmp(val, "%lld") ||
|
299
|
+
- !strcmp(val, "%I64d")) {
|
300
|
+
+ } else if (!strcmp(token->str, "%lld") ||
|
301
|
+
+ !strcmp(token->str, "%I64d")) {
|
302
|
+
return QOBJECT(qint_from_int(va_arg(*ap, long long)));
|
303
|
+
- } else if (!strcmp(val, "%s")) {
|
304
|
+
+ } else if (!strcmp(token->str, "%s")) {
|
305
|
+
return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
|
306
|
+
- } else if (!strcmp(val, "%f")) {
|
307
|
+
+ } else if (!strcmp(token->str, "%f")) {
|
308
|
+
return QOBJECT(qfloat_from_double(va_arg(*ap, double)));
|
309
|
+
}
|
310
|
+
return NULL;
|
311
|
+
@@ -504,12 +486,12 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
|
312
|
+
|
313
|
+
static QObject *parse_literal(JSONParserContext *ctxt)
|
314
|
+
{
|
315
|
+
- QObject *token;
|
316
|
+
+ JSONToken *token;
|
317
|
+
|
318
|
+
token = parser_context_pop_token(ctxt);
|
319
|
+
assert(token);
|
320
|
+
|
321
|
+
- switch (token_get_type(token)) {
|
322
|
+
+ switch (token->type) {
|
323
|
+
case JSON_STRING:
|
324
|
+
return QOBJECT(qstring_from_escaped_str(ctxt, token));
|
325
|
+
case JSON_INTEGER: {
|
326
|
+
@@ -528,7 +510,7 @@ static QObject *parse_literal(JSONParserContext *ctxt)
|
327
|
+
int64_t value;
|
328
|
+
|
329
|
+
errno = 0; /* strtoll doesn't set errno on success */
|
330
|
+
- value = strtoll(token_get_value(token), NULL, 10);
|
331
|
+
+ value = strtoll(token->str, NULL, 10);
|
332
|
+
if (errno != ERANGE) {
|
333
|
+
return QOBJECT(qint_from_int(value));
|
334
|
+
}
|
335
|
+
@@ -536,8 +518,7 @@ static QObject *parse_literal(JSONParserContext *ctxt)
|
336
|
+
}
|
337
|
+
case JSON_FLOAT:
|
338
|
+
/* FIXME dependent on locale */
|
339
|
+
- return QOBJECT(qfloat_from_double(strtod(token_get_value(token),
|
340
|
+
- NULL)));
|
341
|
+
+ return QOBJECT(qfloat_from_double(strtod(token->str, NULL)));
|
342
|
+
default:
|
343
|
+
abort();
|
344
|
+
}
|
345
|
+
@@ -545,7 +526,7 @@ static QObject *parse_literal(JSONParserContext *ctxt)
|
346
|
+
|
347
|
+
static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
|
348
|
+
{
|
349
|
+
- QObject *token;
|
350
|
+
+ JSONToken *token;
|
351
|
+
|
352
|
+
token = parser_context_peek_token(ctxt);
|
353
|
+
if (token == NULL) {
|
354
|
+
@@ -553,7 +534,7 @@ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
|
355
|
+
return NULL;
|
356
|
+
}
|
357
|
+
|
358
|
+
- switch (token_get_type(token)) {
|
359
|
+
+ switch (token->type) {
|
360
|
+
case JSON_LCURLY:
|
361
|
+
return parse_object(ctxt, ap);
|
362
|
+
case JSON_LSQUARE:
|
363
|
+
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
|
364
|
+
index f7a3e78..e87230d 100644
|
365
|
+
--- a/qobject/json-streamer.c
|
366
|
+
+++ b/qobject/json-streamer.c
|
367
|
+
|
368
|
+
*
|
369
|
+
*/
|
370
|
+
|
371
|
+
-#include "qapi/qmp/qlist.h"
|
372
|
+
-#include "qapi/qmp/qstring.h"
|
373
|
+
-#include "qapi/qmp/qint.h"
|
374
|
+
-#include "qapi/qmp/qdict.h"
|
375
|
+
#include "qemu-common.h"
|
376
|
+
#include "qapi/qmp/json-lexer.h"
|
377
|
+
#include "qapi/qmp/json-streamer.h"
|
378
|
+
@@ -34,7 +30,7 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
|
379
|
+
JSONTokenType type, int x, int y)
|
380
|
+
{
|
381
|
+
JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
|
382
|
+
- QDict *dict;
|
383
|
+
+ JSONToken *token;
|
384
|
+
|
385
|
+
switch (type) {
|
386
|
+
case JSON_LCURLY:
|
387
|
+
@@ -53,15 +49,16 @@ static void json_message_process_token(JSONLexer *lexer, GString *input,
|
388
|
+
break;
|
389
|
+
}
|
390
|
+
|
391
|
+
- dict = qdict_new();
|
392
|
+
- qdict_put(dict, "type", qint_from_int(type));
|
393
|
+
- qdict_put(dict, "token", qstring_from_str(input->str));
|
394
|
+
- qdict_put(dict, "x", qint_from_int(x));
|
395
|
+
- qdict_put(dict, "y", qint_from_int(y));
|
396
|
+
+ token = g_malloc(sizeof(JSONToken) + input->len + 1);
|
397
|
+
+ token->type = type;
|
398
|
+
+ memcpy(token->str, input->str, input->len);
|
399
|
+
+ token->str[input->len] = 0;
|
400
|
+
+ token->x = x;
|
401
|
+
+ token->y = y;
|
402
|
+
|
403
|
+
parser->token_size += input->len;
|
404
|
+
|
405
|
+
- g_queue_push_tail(parser->tokens, dict);
|
406
|
+
+ g_queue_push_tail(parser->tokens, token);
|
407
|
+
|
408
|
+
if (type == JSON_ERROR) {
|
409
|
+
goto out_emit_bad;
|
410
|
+
--
|
411
|
+
1.8.3.1
|
412
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
From ac053d6013f7fab73f66db60462c388bea21b714 Mon Sep 17 00:00:00 2001
|
2
|
+
Message-Id: <ac053d6013f7fab73f66db60462c388bea21b714.1464449390.git.jen@redhat.com>
|
3
|
+
In-Reply-To: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
|
4
|
+
References: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
|
5
|
+
From: Gerd Hoffmann <kraxel@redhat.com>
|
6
|
+
Date: Fri, 13 May 2016 16:09:29 -0400
|
7
|
+
Subject: [CHANGE 2/3] qxl: Fix new function name for spice-server library
|
8
|
+
MIME-Version: 1.0
|
9
|
+
Content-Type: text/plain; charset=UTF-8
|
10
|
+
Content-Transfer-Encoding: 8bit
|
11
|
+
To: rhvirt-patches@redhat.com,
|
12
|
+
jen@redhat.com
|
13
|
+
|
14
|
+
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
15
|
+
Message-id: <1463155769-32352-3-git-send-email-kraxel@redhat.com>
|
16
|
+
Patchwork-id: 70403
|
17
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 2/2] qxl: Fix new function name for spice-server library
|
18
|
+
Bugzilla: 1283198
|
19
|
+
RH-Acked-by: Marc-André Lureau <mlureau@redhat.com>
|
20
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
21
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
22
|
+
|
23
|
+
From: Frediano Ziglio <fziglio@redhat.com>
|
24
|
+
|
25
|
+
The new spice-server function to limit the number of monitors (0.12.6)
|
26
|
+
changed while development from spice_qxl_set_monitors_config_limit to
|
27
|
+
spice_qxl_max_monitors (accepted upstream).
|
28
|
+
By mistake I post patch with former name.
|
29
|
+
This patch fix the function name.
|
30
|
+
|
31
|
+
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
|
32
|
+
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
|
33
|
+
Acked-by: Martin Kletzander <mkletzan@redhat.com>
|
34
|
+
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
35
|
+
(cherry picked from commit a52b2cbf218d52f9e357961acb271a98a2bdff71)
|
36
|
+
Signed-off-by: Jeff E. Nelson <jen@redhat.com>
|
37
|
+
---
|
38
|
+
hw/display/qxl.c | 3 +--
|
39
|
+
1 file changed, 1 insertion(+), 2 deletions(-)
|
40
|
+
|
41
|
+
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
|
42
|
+
index 1f6a303..748dfce 100644
|
43
|
+
--- a/hw/display/qxl.c
|
44
|
+
+++ b/hw/display/qxl.c
|
45
|
+
@@ -268,8 +268,7 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
|
46
|
+
} else {
|
47
|
+
#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
|
48
|
+
if (qxl->max_outputs) {
|
49
|
+
- spice_qxl_set_monitors_config_limit(&qxl->ssd.qxl,
|
50
|
+
- qxl->max_outputs);
|
51
|
+
+ spice_qxl_set_max_monitors(&qxl->ssd.qxl, qxl->max_outputs);
|
52
|
+
}
|
53
|
+
#endif
|
54
|
+
qxl->guest_monitors_config = qxl->ram->monitors_config;
|
55
|
+
--
|
56
|
+
2.5.5
|
57
|
+
|
@@ -0,0 +1,120 @@
|
|
1
|
+
From c7936395ecf322b3de37662c7c6b772e36866cc7 Mon Sep 17 00:00:00 2001
|
2
|
+
Message-Id: <c7936395ecf322b3de37662c7c6b772e36866cc7.1464449390.git.jen@redhat.com>
|
3
|
+
From: Gerd Hoffmann <kraxel@redhat.com>
|
4
|
+
Date: Fri, 13 May 2016 16:09:28 -0400
|
5
|
+
Subject: [CHANGE 1/3] qxl: allow to specify head limit to qxl driver
|
6
|
+
MIME-Version: 1.0
|
7
|
+
Content-Type: text/plain; charset=UTF-8
|
8
|
+
Content-Transfer-Encoding: 8bit
|
9
|
+
To: rhvirt-patches@redhat.com,
|
10
|
+
jen@redhat.com
|
11
|
+
|
12
|
+
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
13
|
+
Message-id: <1463155769-32352-2-git-send-email-kraxel@redhat.com>
|
14
|
+
Patchwork-id: 70404
|
15
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/2] qxl: allow to specify head limit to qxl driver
|
16
|
+
Bugzilla: 1283198
|
17
|
+
RH-Acked-by: Marc-André Lureau <mlureau@redhat.com>
|
18
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
19
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
20
|
+
|
21
|
+
From: Frediano Ziglio <fziglio@redhat.com>
|
22
|
+
|
23
|
+
This patch allow to limit number of heads using qxl driver. By default
|
24
|
+
qxl driver is not limited on any kind on head use so can decide to use
|
25
|
+
as much heads.
|
26
|
+
|
27
|
+
libvirt has this as a video card parameter (actually set to 1 but not
|
28
|
+
used). This parameter will allow to limit setting a use can do (which
|
29
|
+
could be confusing).
|
30
|
+
|
31
|
+
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
|
32
|
+
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
33
|
+
(cherry picked from commit 567161fdd47aeb6987e700702f6bbfef04ae0236)
|
34
|
+
Signed-off-by: Jeff E. Nelson <jen@redhat.com>
|
35
|
+
---
|
36
|
+
hw/display/qxl.c | 26 +++++++++++++++++++++-----
|
37
|
+
hw/display/qxl.h | 3 +++
|
38
|
+
2 files changed, 24 insertions(+), 5 deletions(-)
|
39
|
+
|
40
|
+
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
|
41
|
+
index f11210c..1f6a303 100644
|
42
|
+
--- a/hw/display/qxl.c
|
43
|
+
+++ b/hw/display/qxl.c
|
44
|
+
@@ -266,6 +266,12 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
|
45
|
+
QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
|
46
|
+
0));
|
47
|
+
} else {
|
48
|
+
+#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
|
49
|
+
+ if (qxl->max_outputs) {
|
50
|
+
+ spice_qxl_set_monitors_config_limit(&qxl->ssd.qxl,
|
51
|
+
+ qxl->max_outputs);
|
52
|
+
+ }
|
53
|
+
+#endif
|
54
|
+
qxl->guest_monitors_config = qxl->ram->monitors_config;
|
55
|
+
spice_qxl_monitors_config_async(&qxl->ssd.qxl,
|
56
|
+
qxl->ram->monitors_config,
|
57
|
+
@@ -991,6 +997,7 @@ static int interface_client_monitors_config(QXLInstance *sin,
|
58
|
+
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
59
|
+
QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar);
|
60
|
+
int i;
|
61
|
+
+ unsigned max_outputs = ARRAY_SIZE(rom->client_monitors_config.heads);
|
62
|
+
|
63
|
+
if (qxl->revision < 4) {
|
64
|
+
trace_qxl_client_monitors_config_unsupported_by_device(qxl->id,
|
65
|
+
@@ -1013,17 +1020,23 @@ static int interface_client_monitors_config(QXLInstance *sin,
|
66
|
+
if (!monitors_config) {
|
67
|
+
return 1;
|
68
|
+
}
|
69
|
+
+
|
70
|
+
+#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
|
71
|
+
+ /* limit number of outputs based on setting limit */
|
72
|
+
+ if (qxl->max_outputs && qxl->max_outputs <= max_outputs) {
|
73
|
+
+ max_outputs = qxl->max_outputs;
|
74
|
+
+ }
|
75
|
+
+#endif
|
76
|
+
+
|
77
|
+
memset(&rom->client_monitors_config, 0,
|
78
|
+
sizeof(rom->client_monitors_config));
|
79
|
+
rom->client_monitors_config.count = monitors_config->num_of_monitors;
|
80
|
+
/* monitors_config->flags ignored */
|
81
|
+
- if (rom->client_monitors_config.count >=
|
82
|
+
- ARRAY_SIZE(rom->client_monitors_config.heads)) {
|
83
|
+
+ if (rom->client_monitors_config.count >= max_outputs) {
|
84
|
+
trace_qxl_client_monitors_config_capped(qxl->id,
|
85
|
+
monitors_config->num_of_monitors,
|
86
|
+
- ARRAY_SIZE(rom->client_monitors_config.heads));
|
87
|
+
- rom->client_monitors_config.count =
|
88
|
+
- ARRAY_SIZE(rom->client_monitors_config.heads);
|
89
|
+
+ max_outputs);
|
90
|
+
+ rom->client_monitors_config.count = max_outputs;
|
91
|
+
}
|
92
|
+
for (i = 0 ; i < rom->client_monitors_config.count ; ++i) {
|
93
|
+
VDAgentMonConfig *monitor = &monitors_config->monitors[i];
|
94
|
+
@@ -2294,6 +2307,9 @@ static Property qxl_properties[] = {
|
95
|
+
DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
|
96
|
+
DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16),
|
97
|
+
DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024),
|
98
|
+
+#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
|
99
|
+
+ DEFINE_PROP_UINT16("max_outputs", PCIQXLDevice, max_outputs, 0),
|
100
|
+
+#endif
|
101
|
+
DEFINE_PROP_END_OF_LIST(),
|
102
|
+
};
|
103
|
+
|
104
|
+
diff --git a/hw/display/qxl.h b/hw/display/qxl.h
|
105
|
+
index 5da33e2..5247ce9 100644
|
106
|
+
--- a/hw/display/qxl.h
|
107
|
+
+++ b/hw/display/qxl.h
|
108
|
+
@@ -95,6 +95,9 @@ typedef struct PCIQXLDevice {
|
109
|
+
QXLModes *modes;
|
110
|
+
uint32_t rom_size;
|
111
|
+
MemoryRegion rom_bar;
|
112
|
+
+#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
|
113
|
+
+ uint16_t max_outputs;
|
114
|
+
+#endif
|
115
|
+
|
116
|
+
/* vram pci bar */
|
117
|
+
uint32_t vram_size;
|
118
|
+
--
|
119
|
+
2.5.5
|
120
|
+
|
@@ -0,0 +1,108 @@
|
|
1
|
+
From 24a604e857d2797c3da9852bcbea75f2f9e6961c Mon Sep 17 00:00:00 2001
|
2
|
+
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
+
Date: Fri, 22 Jul 2016 09:34:38 +0200
|
4
|
+
Subject: [PATCH 1/4] qxl: factor out qxl_get_check_slot_offset
|
5
|
+
|
6
|
+
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
+
Message-id: <1469180081-28522-2-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 71317
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 1/4] qxl: factor out qxl_get_check_slot_offset
|
10
|
+
Bugzilla: 1355730
|
11
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
14
|
+
|
15
|
+
New helper function which translates a qxl physical address into
|
16
|
+
memory slot and offset. Also applies sanity checks. Factored out
|
17
|
+
from qxl_phys2virt. No functional change.
|
18
|
+
|
19
|
+
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
20
|
+
Message-id: 1466597244-5938-1-git-send-email-kraxel@redhat.com
|
21
|
+
(cherry picked from commit 726bdf653aca9b87e28c9a56dd94c4667ddfacbc)
|
22
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
23
|
+
---
|
24
|
+
hw/display/qxl.c | 59 ++++++++++++++++++++++++++++++++++++--------------------
|
25
|
+
1 file changed, 38 insertions(+), 21 deletions(-)
|
26
|
+
|
27
|
+
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
|
28
|
+
index 748dfce..5e1ecd8 100644
|
29
|
+
--- a/hw/display/qxl.c
|
30
|
+
+++ b/hw/display/qxl.c
|
31
|
+
@@ -1326,36 +1326,53 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
|
32
|
+
}
|
33
|
+
|
34
|
+
/* can be also called from spice server thread context */
|
35
|
+
-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
|
36
|
+
+static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
|
37
|
+
+ uint32_t *s, uint64_t *o)
|
38
|
+
{
|
39
|
+
uint64_t phys = le64_to_cpu(pqxl);
|
40
|
+
uint32_t slot = (phys >> (64 - 8)) & 0xff;
|
41
|
+
uint64_t offset = phys & 0xffffffffffff;
|
42
|
+
|
43
|
+
- switch (group_id) {
|
44
|
+
- case MEMSLOT_GROUP_HOST:
|
45
|
+
- return (void *)(intptr_t)offset;
|
46
|
+
- case MEMSLOT_GROUP_GUEST:
|
47
|
+
- if (slot >= NUM_MEMSLOTS) {
|
48
|
+
- qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
|
49
|
+
- NUM_MEMSLOTS);
|
50
|
+
- return NULL;
|
51
|
+
- }
|
52
|
+
- if (!qxl->guest_slots[slot].active) {
|
53
|
+
- qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
|
54
|
+
- return NULL;
|
55
|
+
- }
|
56
|
+
- if (offset < qxl->guest_slots[slot].delta) {
|
57
|
+
- qxl_set_guest_bug(qxl,
|
58
|
+
+ if (slot >= NUM_MEMSLOTS) {
|
59
|
+
+ qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
|
60
|
+
+ NUM_MEMSLOTS);
|
61
|
+
+ return false;
|
62
|
+
+ }
|
63
|
+
+ if (!qxl->guest_slots[slot].active) {
|
64
|
+
+ qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
|
65
|
+
+ return false;
|
66
|
+
+ }
|
67
|
+
+ if (offset < qxl->guest_slots[slot].delta) {
|
68
|
+
+ qxl_set_guest_bug(qxl,
|
69
|
+
"slot %d offset %"PRIu64" < delta %"PRIu64"\n",
|
70
|
+
slot, offset, qxl->guest_slots[slot].delta);
|
71
|
+
- return NULL;
|
72
|
+
- }
|
73
|
+
- offset -= qxl->guest_slots[slot].delta;
|
74
|
+
- if (offset > qxl->guest_slots[slot].size) {
|
75
|
+
- qxl_set_guest_bug(qxl,
|
76
|
+
+ return false;
|
77
|
+
+ }
|
78
|
+
+ offset -= qxl->guest_slots[slot].delta;
|
79
|
+
+ if (offset > qxl->guest_slots[slot].size) {
|
80
|
+
+ qxl_set_guest_bug(qxl,
|
81
|
+
"slot %d offset %"PRIu64" > size %"PRIu64"\n",
|
82
|
+
slot, offset, qxl->guest_slots[slot].size);
|
83
|
+
+ return false;
|
84
|
+
+ }
|
85
|
+
+
|
86
|
+
+ *s = slot;
|
87
|
+
+ *o = offset;
|
88
|
+
+ return true;
|
89
|
+
+}
|
90
|
+
+
|
91
|
+
+/* can be also called from spice server thread context */
|
92
|
+
+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
|
93
|
+
+{
|
94
|
+
+ uint64_t offset;
|
95
|
+
+ uint32_t slot;
|
96
|
+
+
|
97
|
+
+ switch (group_id) {
|
98
|
+
+ case MEMSLOT_GROUP_HOST:
|
99
|
+
+ offset = le64_to_cpu(pqxl) & 0xffffffffffff;
|
100
|
+
+ return (void *)(intptr_t)offset;
|
101
|
+
+ case MEMSLOT_GROUP_GUEST:
|
102
|
+
+ if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) {
|
103
|
+
return NULL;
|
104
|
+
}
|
105
|
+
return qxl->guest_slots[slot].ptr + offset;
|
106
|
+
--
|
107
|
+
1.8.3.1
|
108
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
From e7fe5cf70d63552006e8c9eb660db95279f2a3a9 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
+
Date: Fri, 22 Jul 2016 09:34:41 +0200
|
4
|
+
Subject: [PATCH 4/4] qxl: fix qxl_set_dirty call in qxl_dirty_one_surface
|
5
|
+
|
6
|
+
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
+
Message-id: <1469180081-28522-5-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 71316
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 4/4] qxl: fix qxl_set_dirty call in qxl_dirty_one_surface
|
10
|
+
Bugzilla: 1355730
|
11
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
14
|
+
|
15
|
+
qxl_set_dirty() expects start and end as range specification.
|
16
|
+
qxl_dirty_one_surface passes 'size' instead of 'offset + size' as end
|
17
|
+
parameter. Fix that. Also use uint64_t everywhere while being at it.
|
18
|
+
|
19
|
+
Bug was added by "e25139b qxl: set only off-screen surfaces dirty instead
|
20
|
+
of the whole vram" and carried forward unnoticed by "5cdc402 qxl: fix
|
21
|
+
surface migration".
|
22
|
+
|
23
|
+
Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
24
|
+
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
25
|
+
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
26
|
+
Message-id: 1468413187-22071-1-git-send-email-kraxel@redhat.com
|
27
|
+
(cherry picked from commit e0127d2eec9cd5676ea9f3c47c2a7579a02c0466)
|
28
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
29
|
+
|
30
|
+
Conflicts:
|
31
|
+
hw/display/trace-events
|
32
|
+
---
|
33
|
+
hw/display/qxl.c | 11 ++++++-----
|
34
|
+
trace-events | 2 +-
|
35
|
+
2 files changed, 7 insertions(+), 6 deletions(-)
|
36
|
+
|
37
|
+
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
|
38
|
+
index d65c830..f762439 100644
|
39
|
+
--- a/hw/display/qxl.c
|
40
|
+
+++ b/hw/display/qxl.c
|
41
|
+
@@ -1825,16 +1825,17 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
|
42
|
+
static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
|
43
|
+
uint32_t height, int32_t stride)
|
44
|
+
{
|
45
|
+
- uint64_t offset;
|
46
|
+
- uint32_t slot, size;
|
47
|
+
+ uint64_t offset, size;
|
48
|
+
+ uint32_t slot;
|
49
|
+
bool rc;
|
50
|
+
|
51
|
+
rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset);
|
52
|
+
assert(rc == true);
|
53
|
+
- size = height * abs(stride);
|
54
|
+
- trace_qxl_surfaces_dirty(qxl->id, (int)offset, size);
|
55
|
+
+ size = (uint64_t)height * abs(stride);
|
56
|
+
+ trace_qxl_surfaces_dirty(qxl->id, offset, size);
|
57
|
+
qxl_set_dirty(qxl->guest_slots[slot].mr,
|
58
|
+
- qxl->guest_slots[slot].offset + offset, size);
|
59
|
+
+ qxl->guest_slots[slot].offset + offset,
|
60
|
+
+ qxl->guest_slots[slot].offset + offset + size);
|
61
|
+
}
|
62
|
+
|
63
|
+
static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
|
64
|
+
diff --git a/trace-events b/trace-events
|
65
|
+
index 4da84b2..af5147a 100644
|
66
|
+
--- a/trace-events
|
67
|
+
+++ b/trace-events
|
68
|
+
@@ -1078,7 +1078,7 @@ qxl_spice_reset_image_cache(int qid) "%d"
|
69
|
+
qxl_spice_reset_memslots(int qid) "%d"
|
70
|
+
qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
|
71
|
+
qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
|
72
|
+
-qxl_surfaces_dirty(int qid, int offset, int size) "%d offset=%d size=%d"
|
73
|
+
+qxl_surfaces_dirty(int qid, uint64_t offset, uint64_t size) "%d offset=0x%"PRIx64" size=0x%"PRIx64
|
74
|
+
qxl_send_events(int qid, uint32_t events) "%d %d"
|
75
|
+
qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d"
|
76
|
+
qxl_set_guest_bug(int qid) "%d"
|
77
|
+
--
|
78
|
+
1.8.3.1
|
79
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
From 13bf417cd4063f5db2f0a79265745481d4c69d0d Mon Sep 17 00:00:00 2001
|
2
|
+
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
+
Date: Fri, 22 Jul 2016 09:34:40 +0200
|
4
|
+
Subject: [PATCH 3/4] qxl: fix surface migration
|
5
|
+
|
6
|
+
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
+
Message-id: <1469180081-28522-4-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 71315
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 3/4] qxl: fix surface migration
|
10
|
+
Bugzilla: 1355730
|
11
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
14
|
+
|
15
|
+
Create a helper function qxl_dirty_one_surface() to mark a single qxl
|
16
|
+
surface as dirty. Use the new qxl_get_check_slot_offset function and
|
17
|
+
lookup the memory region from the slot instead of assuming the surface
|
18
|
+
is stored in vram.
|
19
|
+
|
20
|
+
Use the new helper function in qxl_dirty_surfaces, for both primary and
|
21
|
+
off-screen surfaces. For off-screen surfaces this is no functional
|
22
|
+
change. For primary surfaces this will dirty only the memory actually
|
23
|
+
used instead of the whole surface0 region. It will also work correctly
|
24
|
+
in case the guest places the primary surface in vram instead of the
|
25
|
+
surface0 region (linux kms driver does that).
|
26
|
+
|
27
|
+
https://bugzilla.redhat.com/show_bug.cgi?id=1235732
|
28
|
+
|
29
|
+
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
30
|
+
Message-id: 1466597244-5938-3-git-send-email-kraxel@redhat.com
|
31
|
+
(cherry picked from commit 1331eab216c9dc4e50a48a34d14926b31a7fd611)
|
32
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
33
|
+
|
34
|
+
Conflicts:
|
35
|
+
hw/display/trace-events
|
36
|
+
---
|
37
|
+
hw/display/qxl.c | 37 +++++++++++++++++++++----------------
|
38
|
+
trace-events | 2 +-
|
39
|
+
2 files changed, 22 insertions(+), 17 deletions(-)
|
40
|
+
|
41
|
+
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
|
42
|
+
index de5770e..d65c830 100644
|
43
|
+
--- a/hw/display/qxl.c
|
44
|
+
+++ b/hw/display/qxl.c
|
45
|
+
@@ -1822,9 +1822,23 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
+static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
|
50
|
+
+ uint32_t height, int32_t stride)
|
51
|
+
+{
|
52
|
+
+ uint64_t offset;
|
53
|
+
+ uint32_t slot, size;
|
54
|
+
+ bool rc;
|
55
|
+
+
|
56
|
+
+ rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset);
|
57
|
+
+ assert(rc == true);
|
58
|
+
+ size = height * abs(stride);
|
59
|
+
+ trace_qxl_surfaces_dirty(qxl->id, (int)offset, size);
|
60
|
+
+ qxl_set_dirty(qxl->guest_slots[slot].mr,
|
61
|
+
+ qxl->guest_slots[slot].offset + offset, size);
|
62
|
+
+}
|
63
|
+
+
|
64
|
+
static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
|
65
|
+
{
|
66
|
+
- uintptr_t vram_start;
|
67
|
+
int i;
|
68
|
+
|
69
|
+
if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
|
70
|
+
@@ -1832,16 +1846,13 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
|
71
|
+
}
|
72
|
+
|
73
|
+
/* dirty the primary surface */
|
74
|
+
- qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
|
75
|
+
- qxl->shadow_rom.surface0_area_size);
|
76
|
+
-
|
77
|
+
- vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
|
78
|
+
+ qxl_dirty_one_surface(qxl, qxl->guest_primary.surface.mem,
|
79
|
+
+ qxl->guest_primary.surface.height,
|
80
|
+
+ qxl->guest_primary.surface.stride);
|
81
|
+
|
82
|
+
/* dirty the off-screen surfaces */
|
83
|
+
for (i = 0; i < qxl->ssd.num_surfaces; i++) {
|
84
|
+
QXLSurfaceCmd *cmd;
|
85
|
+
- intptr_t surface_offset;
|
86
|
+
- int surface_size;
|
87
|
+
|
88
|
+
if (qxl->guest_surfaces.cmds[i] == 0) {
|
89
|
+
continue;
|
90
|
+
@@ -1851,15 +1862,9 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
|
91
|
+
MEMSLOT_GROUP_GUEST);
|
92
|
+
assert(cmd);
|
93
|
+
assert(cmd->type == QXL_SURFACE_CMD_CREATE);
|
94
|
+
- surface_offset = (intptr_t)qxl_phys2virt(qxl,
|
95
|
+
- cmd->u.surface_create.data,
|
96
|
+
- MEMSLOT_GROUP_GUEST);
|
97
|
+
- assert(surface_offset);
|
98
|
+
- surface_offset -= vram_start;
|
99
|
+
- surface_size = cmd->u.surface_create.height *
|
100
|
+
- abs(cmd->u.surface_create.stride);
|
101
|
+
- trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);
|
102
|
+
- qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
|
103
|
+
+ qxl_dirty_one_surface(qxl, cmd->u.surface_create.data,
|
104
|
+
+ cmd->u.surface_create.height,
|
105
|
+
+ cmd->u.surface_create.stride);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
diff --git a/trace-events b/trace-events
|
110
|
+
index b43132c..4da84b2 100644
|
111
|
+
--- a/trace-events
|
112
|
+
+++ b/trace-events
|
113
|
+
@@ -1078,7 +1078,7 @@ qxl_spice_reset_image_cache(int qid) "%d"
|
114
|
+
qxl_spice_reset_memslots(int qid) "%d"
|
115
|
+
qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
|
116
|
+
qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
|
117
|
+
-qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
|
118
|
+
+qxl_surfaces_dirty(int qid, int offset, int size) "%d offset=%d size=%d"
|
119
|
+
qxl_send_events(int qid, uint32_t events) "%d %d"
|
120
|
+
qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d"
|
121
|
+
qxl_set_guest_bug(int qid) "%d"
|
122
|
+
--
|
123
|
+
1.8.3.1
|
124
|
+
|
@@ -0,0 +1,109 @@
|
|
1
|
+
From 8f25ff7e1496ce8a26edacfa01c64f3a98c564a0 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
+
Date: Fri, 22 Jul 2016 09:34:39 +0200
|
4
|
+
Subject: [PATCH 2/4] qxl: store memory region and offset instead of pointer
|
5
|
+
for guest slots
|
6
|
+
|
7
|
+
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
8
|
+
Message-id: <1469180081-28522-3-git-send-email-kraxel@redhat.com>
|
9
|
+
Patchwork-id: 71314
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 2/4] qxl: store memory region and offset instead of pointer for guest slots
|
11
|
+
Bugzilla: 1355730
|
12
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
13
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
14
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
15
|
+
|
16
|
+
Store MemoryRegion and offset instead of a pointer for each qxl memory
|
17
|
+
slot, so we can easily figure in which memory region an qxl object
|
18
|
+
stored.
|
19
|
+
|
20
|
+
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
21
|
+
Message-id: 1466597244-5938-2-git-send-email-kraxel@redhat.com
|
22
|
+
(cherry picked from commit 3cb5158f15604a9f50287f2f06777d5835ff4c15)
|
23
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
24
|
+
---
|
25
|
+
hw/display/qxl.c | 15 +++++++++++----
|
26
|
+
hw/display/qxl.h | 3 ++-
|
27
|
+
2 files changed, 13 insertions(+), 5 deletions(-)
|
28
|
+
|
29
|
+
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
|
30
|
+
index 5e1ecd8..de5770e 100644
|
31
|
+
--- a/hw/display/qxl.c
|
32
|
+
+++ b/hw/display/qxl.c
|
33
|
+
@@ -1232,6 +1232,7 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
|
34
|
+
int pci_region;
|
35
|
+
pcibus_t pci_start;
|
36
|
+
pcibus_t pci_end;
|
37
|
+
+ MemoryRegion *mr;
|
38
|
+
intptr_t virt_start;
|
39
|
+
QXLDevMemSlot memslot;
|
40
|
+
int i;
|
41
|
+
@@ -1278,11 +1279,11 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
|
42
|
+
|
43
|
+
switch (pci_region) {
|
44
|
+
case QXL_RAM_RANGE_INDEX:
|
45
|
+
- virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
|
46
|
+
+ mr = &d->vga.vram;
|
47
|
+
break;
|
48
|
+
case QXL_VRAM_RANGE_INDEX:
|
49
|
+
case 4 /* vram 64bit */:
|
50
|
+
- virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
|
51
|
+
+ mr = &d->vram_bar;
|
52
|
+
break;
|
53
|
+
default:
|
54
|
+
/* should not happen */
|
55
|
+
@@ -1290,6 +1291,7 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
|
56
|
+
return 1;
|
57
|
+
}
|
58
|
+
|
59
|
+
+ virt_start = (intptr_t)memory_region_get_ram_ptr(mr);
|
60
|
+
memslot.slot_id = slot_id;
|
61
|
+
memslot.slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */
|
62
|
+
memslot.virt_start = virt_start + (guest_start - pci_start);
|
63
|
+
@@ -1299,7 +1301,8 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
|
64
|
+
qxl_rom_set_dirty(d);
|
65
|
+
|
66
|
+
qemu_spice_add_memslot(&d->ssd, &memslot, async);
|
67
|
+
- d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
|
68
|
+
+ d->guest_slots[slot_id].mr = mr;
|
69
|
+
+ d->guest_slots[slot_id].offset = memslot.virt_start - virt_start;
|
70
|
+
d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
|
71
|
+
d->guest_slots[slot_id].delta = delta;
|
72
|
+
d->guest_slots[slot_id].active = 1;
|
73
|
+
@@ -1366,6 +1369,7 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
|
74
|
+
{
|
75
|
+
uint64_t offset;
|
76
|
+
uint32_t slot;
|
77
|
+
+ void *ptr;
|
78
|
+
|
79
|
+
switch (group_id) {
|
80
|
+
case MEMSLOT_GROUP_HOST:
|
81
|
+
@@ -1375,7 +1379,10 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
|
82
|
+
if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) {
|
83
|
+
return NULL;
|
84
|
+
}
|
85
|
+
- return qxl->guest_slots[slot].ptr + offset;
|
86
|
+
+ ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr);
|
87
|
+
+ ptr += qxl->guest_slots[slot].offset;
|
88
|
+
+ ptr += offset;
|
89
|
+
+ return ptr;
|
90
|
+
}
|
91
|
+
return NULL;
|
92
|
+
}
|
93
|
+
diff --git a/hw/display/qxl.h b/hw/display/qxl.h
|
94
|
+
index 5247ce9..f3f51e2 100644
|
95
|
+
--- a/hw/display/qxl.h
|
96
|
+
+++ b/hw/display/qxl.h
|
97
|
+
@@ -49,7 +49,8 @@ typedef struct PCIQXLDevice {
|
98
|
+
|
99
|
+
struct guest_slots {
|
100
|
+
QXLMemSlot slot;
|
101
|
+
- void *ptr;
|
102
|
+
+ MemoryRegion *mr;
|
103
|
+
+ uint64_t offset;
|
104
|
+
uint64_t size;
|
105
|
+
uint64_t delta;
|
106
|
+
uint32_t active;
|
107
|
+
--
|
108
|
+
1.8.3.1
|
109
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
From 52288902dd647cbcfa470a11867163a6e5983297 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 11 Jul 2016 05:33:38 +0200
|
4
|
+
Subject: [PATCH 5/7] raw-posix: Fetch max sectors for host block device
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1468215219-30793-6-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 71109
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 5/6] raw-posix: Fetch max sectors for host block device
|
10
|
+
Bugzilla: 1318199
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
This is sometimes a useful value we should count in.
|
16
|
+
|
17
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
18
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
19
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
20
|
+
(cherry picked from commit 6f6071745bd0366221f5a0160ed7d18d0e38b9f7)
|
21
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
22
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
23
|
+
---
|
24
|
+
block/raw-posix.c | 24 ++++++++++++++++++++++++
|
25
|
+
1 file changed, 24 insertions(+)
|
26
|
+
|
27
|
+
diff --git a/block/raw-posix.c b/block/raw-posix.c
|
28
|
+
index 92fcb6c..ed97bd4 100644
|
29
|
+
--- a/block/raw-posix.c
|
30
|
+
+++ b/block/raw-posix.c
|
31
|
+
@@ -587,9 +587,33 @@ static void raw_reopen_abort(BDRVReopenState *state)
|
32
|
+
state->opaque = NULL;
|
33
|
+
}
|
34
|
+
|
35
|
+
+static int hdev_get_max_transfer_length(int fd)
|
36
|
+
+{
|
37
|
+
+#ifdef BLKSECTGET
|
38
|
+
+ int max_sectors = 0;
|
39
|
+
+ if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) {
|
40
|
+
+ return max_sectors;
|
41
|
+
+ } else {
|
42
|
+
+ return -errno;
|
43
|
+
+ }
|
44
|
+
+#else
|
45
|
+
+ return -ENOSYS;
|
46
|
+
+#endif
|
47
|
+
+}
|
48
|
+
+
|
49
|
+
static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
|
50
|
+
{
|
51
|
+
BDRVRawState *s = bs->opaque;
|
52
|
+
+ struct stat st;
|
53
|
+
+
|
54
|
+
+ if (!fstat(s->fd, &st)) {
|
55
|
+
+ if (S_ISBLK(st.st_mode)) {
|
56
|
+
+ int ret = hdev_get_max_transfer_length(s->fd);
|
57
|
+
+ if (ret >= 0) {
|
58
|
+
+ bs->bl.max_transfer_length = ret;
|
59
|
+
+ }
|
60
|
+
+ }
|
61
|
+
+ }
|
62
|
+
|
63
|
+
raw_probe_alignment(bs, s->fd, errp);
|
64
|
+
bs->bl.opt_mem_alignment = s->buf_align;
|
65
|
+
--
|
66
|
+
1.8.3.1
|
67
|
+
|
@@ -1,13 +1,13 @@
|
|
1
|
-
From
|
1
|
+
From 4237964a9f433faaf643166a8ce9c070dc4cf165 Mon Sep 17 00:00:00 2001
|
2
2
|
From: Max Reitz <mreitz@redhat.com>
|
3
|
-
Date:
|
3
|
+
Date: Thu, 14 Jan 2016 15:10:31 +0100
|
4
4
|
Subject: [PATCH] raw-posix: Fix .bdrv_co_get_block_status() for unaligned
|
5
5
|
image size
|
6
6
|
|
7
|
-
Message-id: <
|
8
|
-
Patchwork-id:
|
9
|
-
O-Subject: [RHEL-7.
|
10
|
-
Bugzilla:
|
7
|
+
Message-id: <1452784231-14211-2-git-send-email-mreitz@redhat.com>
|
8
|
+
Patchwork-id: 68756
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] raw-posix: Fix .bdrv_co_get_block_status() for unaligned image size
|
10
|
+
Bugzilla: 1283116
|
11
11
|
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
12
12
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
13
13
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
@@ -1,12 +1,12 @@
|
|
1
|
-
From
|
1
|
+
From 109d7dedc79629f58fd9b685ccd9990b90f374e9 Mon Sep 17 00:00:00 2001
|
2
2
|
From: Stefan Hajnoczi <stefanha@redhat.com>
|
3
3
|
Date: Thu, 5 Nov 2015 15:20:58 +0100
|
4
|
-
Subject: [PATCH
|
4
|
+
Subject: [PATCH 3/6] rbd: fix ceph settings precedence
|
5
5
|
|
6
6
|
Message-id: <1446736858-29005-3-git-send-email-stefanha@redhat.com>
|
7
7
|
Patchwork-id: 68294
|
8
8
|
O-Subject: [RHEL-7.2.z qemu-kvm PATCH 2/2] rbd: fix ceph settings precedence
|
9
|
-
Bugzilla: 1279389
|
9
|
+
Bugzilla: 1277248 1279389
|
10
10
|
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
11
11
|
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
12
12
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
@@ -1,12 +1,12 @@
|
|
1
|
-
From
|
1
|
+
From 23bc583f18eb8ffc28604a4ae42e2f7a55b31c3e Mon Sep 17 00:00:00 2001
|
2
2
|
From: Stefan Hajnoczi <stefanha@redhat.com>
|
3
3
|
Date: Thu, 5 Nov 2015 15:20:57 +0100
|
4
|
-
Subject: [PATCH
|
4
|
+
Subject: [PATCH 2/6] rbd: make qemu's cache setting override any ceph setting
|
5
5
|
|
6
6
|
Message-id: <1446736858-29005-2-git-send-email-stefanha@redhat.com>
|
7
7
|
Patchwork-id: 68293
|
8
8
|
O-Subject: [RHEL-7.2.z qemu-kvm PATCH 1/2] rbd: make qemu's cache setting override any ceph setting
|
9
|
-
Bugzilla:
|
9
|
+
Bugzilla: 1277248
|
10
10
|
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
11
11
|
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
12
12
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
From 9318bd2b84409c6f3810d410c6918fefec072408 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Vlad Yasevich <vyasevic@redhat.com>
|
3
|
+
Date: Wed, 16 Dec 2015 02:58:23 +0100
|
4
|
+
Subject: [PATCH 6/6] rtl8139: Do not consume the packet during overflow in
|
5
|
+
standard mode.
|
6
|
+
|
7
|
+
Message-id: <1450234703-7606-3-git-send-email-vyasevic@redhat.com>
|
8
|
+
Patchwork-id: 68618
|
9
|
+
O-Subject: [RHEL7.3 qemu-kvm PATCH 2/2] rtl8139: Do not consume the packet during overflow in standard mode.
|
10
|
+
Bugzilla: 1252757
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
13
|
+
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
|
14
|
+
|
15
|
+
When operation in standard mode, we currently return the size
|
16
|
+
of packet during buffer overflow. This consumes the overflow
|
17
|
+
packet. Return 0 instead so we can re-process the overflow packet
|
18
|
+
when we have room.
|
19
|
+
|
20
|
+
This fixes issues with lost/dropped fragments of large messages.
|
21
|
+
|
22
|
+
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
|
23
|
+
Reviewed-by: Jason Wang <jasowang@redhat.com>
|
24
|
+
Message-id: 1441121206-6997-3-git-send-email-vyasevic@redhat.com
|
25
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
26
|
+
(cherry picked from commit 26c4e7ca72d970d120f0f51244bc8d37458512a0)
|
27
|
+
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
|
28
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
29
|
+
---
|
30
|
+
hw/net/rtl8139.c | 2 +-
|
31
|
+
1 file changed, 1 insertion(+), 1 deletion(-)
|
32
|
+
|
33
|
+
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
|
34
|
+
index 6a167df..aa2503d 100644
|
35
|
+
--- a/hw/net/rtl8139.c
|
36
|
+
+++ b/hw/net/rtl8139.c
|
37
|
+
@@ -1148,7 +1148,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
|
38
|
+
s->IntrStatus |= RxOverflow;
|
39
|
+
++s->RxMissed;
|
40
|
+
rtl8139_update_irq(s);
|
41
|
+
- return size_;
|
42
|
+
+ return 0;
|
43
|
+
}
|
44
|
+
|
45
|
+
packet_header |= RxStatusOK;
|
46
|
+
--
|
47
|
+
1.8.3.1
|
48
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
From dc546cbfdefb8ddbaf121d3b075ca723df264d1c Mon Sep 17 00:00:00 2001
|
2
|
+
From: Vlad Yasevich <vyasevic@redhat.com>
|
3
|
+
Date: Wed, 16 Dec 2015 02:58:22 +0100
|
4
|
+
Subject: [PATCH 5/6] rtl8139: Fix receive buffer overflow check
|
5
|
+
|
6
|
+
Message-id: <1450234703-7606-2-git-send-email-vyasevic@redhat.com>
|
7
|
+
Patchwork-id: 68617
|
8
|
+
O-Subject: [RHEL7.3 qemu-kvm PATCH 1/2] rtl8139: Fix receive buffer overflow check
|
9
|
+
Bugzilla: 1252757
|
10
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
11
|
+
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
12
|
+
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
|
13
|
+
|
14
|
+
rtl8139_do_receive() tries to check for the overflow condition
|
15
|
+
by making sure that packet_size + 8 does not exceed the
|
16
|
+
available buffer space. The issue here is that RxBuffAddr,
|
17
|
+
used to calculate available buffer space, is aligned to a
|
18
|
+
a 4 byte boundry after every update. So it is possible that
|
19
|
+
every packet ends up being slightly padded when written
|
20
|
+
to the receive buffer. This padding is not taken into
|
21
|
+
account when checking for overflow and we may end up missing
|
22
|
+
the overflow condition can causing buffer overwrite.
|
23
|
+
|
24
|
+
This patch takes alignment into consideration when
|
25
|
+
checking for overflow condition.
|
26
|
+
|
27
|
+
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
|
28
|
+
Reviewed-by: Jason Wang <jasowang@redhat.com>
|
29
|
+
Message-id: 1441121206-6997-2-git-send-email-vyasevic@redhat.com
|
30
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
31
|
+
(cherry picked from commit fabdcd3392f16fc666b1d04fc1bbe5f1dbbf10a4)
|
32
|
+
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
|
33
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
34
|
+
---
|
35
|
+
hw/net/rtl8139.c | 6 ++++--
|
36
|
+
1 file changed, 4 insertions(+), 2 deletions(-)
|
37
|
+
|
38
|
+
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
|
39
|
+
index 4f89328..6a167df 100644
|
40
|
+
--- a/hw/net/rtl8139.c
|
41
|
+
+++ b/hw/net/rtl8139.c
|
42
|
+
@@ -1137,7 +1137,9 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
|
43
|
+
|
44
|
+
/* if receiver buffer is empty then avail == 0 */
|
45
|
+
|
46
|
+
- if (avail != 0 && size + 8 >= avail)
|
47
|
+
+#define RX_ALIGN(x) (((x) + 3) & ~0x3)
|
48
|
+
+
|
49
|
+
+ if (avail != 0 && RX_ALIGN(size + 8) >= avail)
|
50
|
+
{
|
51
|
+
DPRINTF("rx overflow: rx buffer length %d head 0x%04x "
|
52
|
+
"read 0x%04x === available 0x%04x need 0x%04x\n",
|
53
|
+
@@ -1165,7 +1167,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
|
54
|
+
rtl8139_write_buffer(s, (uint8_t *)&val, 4);
|
55
|
+
|
56
|
+
/* correct buffer write pointer */
|
57
|
+
- s->RxBufAddr = MOD2((s->RxBufAddr + 3) & ~0x3, s->RxBufferSize);
|
58
|
+
+ s->RxBufAddr = MOD2(RX_ALIGN(s->RxBufAddr), s->RxBufferSize);
|
59
|
+
|
60
|
+
/* now we can signal we have received something */
|
61
|
+
|
62
|
+
--
|
63
|
+
1.8.3.1
|
64
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
From c8644154fb4b460f00c9d24ed9090edc40fef067 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 11 Jul 2016 05:33:39 +0200
|
4
|
+
Subject: [PATCH 6/7] scsi: Advertise limits by blocksize, not 512
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1468215219-30793-7-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 71110
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 6/6] scsi: Advertise limits by blocksize, not 512
|
10
|
+
Bugzilla: 1318199
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Eric Blake <eblake@redhat.com>
|
16
|
+
|
17
|
+
s->blocksize may be larger than 512, in which case our
|
18
|
+
tweaks to max_xfer_len and opt_xfer_len must be scaled
|
19
|
+
appropriately.
|
20
|
+
|
21
|
+
CC: qemu-stable@nongnu.org
|
22
|
+
Reported-by: Fam Zheng <famz@redhat.com>
|
23
|
+
Signed-off-by: Eric Blake <eblake@redhat.com>
|
24
|
+
Reviewed-by: Fam Zheng <famz@redhat.com>
|
25
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
26
|
+
(cherry picked from commit efaf4781a995aacd22b1dd521b14e4644bafae14)
|
27
|
+
|
28
|
+
Conflicts:
|
29
|
+
hw/scsi/scsi-generic.c
|
30
|
+
Downstream uses bdrv_get_max_transfer_length().
|
31
|
+
|
32
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
33
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
34
|
+
---
|
35
|
+
hw/scsi/scsi-generic.c | 3 ++-
|
36
|
+
1 file changed, 2 insertions(+), 1 deletion(-)
|
37
|
+
|
38
|
+
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
|
39
|
+
index 6b0c1fe..ced92f7 100644
|
40
|
+
--- a/hw/scsi/scsi-generic.c
|
41
|
+
+++ b/hw/scsi/scsi-generic.c
|
42
|
+
@@ -210,7 +210,8 @@ static void scsi_read_complete(void * opaque, int ret)
|
43
|
+
} else if (s->type == TYPE_DISK &&
|
44
|
+
r->req.cmd.buf[0] == INQUIRY &&
|
45
|
+
r->req.cmd.buf[2] == 0xb0) {
|
46
|
+
- uint32_t max_xfer_len = bdrv_get_max_transfer_length(s->conf.bs);
|
47
|
+
+ uint32_t max_xfer_len = bdrv_get_max_transfer_length(s->conf.bs) /
|
48
|
+
+ (s->blocksize / BDRV_SECTOR_SIZE);
|
49
|
+
if (max_xfer_len) {
|
50
|
+
stl_be_p(&r->buf[8], max_xfer_len);
|
51
|
+
/* Also take care of the opt xfer len. */
|
52
|
+
--
|
53
|
+
1.8.3.1
|
54
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
From b3f427e4eb27091ca712f6c18e2e63a414dc4ce2 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 11 Jul 2016 05:33:37 +0200
|
4
|
+
Subject: [PATCH 4/7] scsi-generic: Merge block max xfer len in INQUIRY
|
5
|
+
response
|
6
|
+
|
7
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
8
|
+
Message-id: <1468215219-30793-5-git-send-email-famz@redhat.com>
|
9
|
+
Patchwork-id: 71108
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 4/6] scsi-generic: Merge block max xfer len in INQUIRY response
|
11
|
+
Bugzilla: 1318199
|
12
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
13
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
14
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
15
|
+
|
16
|
+
The rationale is similar to the above mode sense response interception:
|
17
|
+
this is practically the only channel to communicate restraints from
|
18
|
+
elsewhere such as host and block driver.
|
19
|
+
|
20
|
+
The scsi bus we attach onto can have a larger max xfer len than what is
|
21
|
+
accepted by the host file system (guarding between the host scsi LUN and
|
22
|
+
QEMU), in which case the SG_IO we generate would get -EINVAL.
|
23
|
+
|
24
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
25
|
+
Message-Id: <1464243305-10661-3-git-send-email-famz@redhat.com>
|
26
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
27
|
+
(cherry picked from commit 063143d5b1fde0fdcbae30bc7d6d14e76fa607d2)
|
28
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
29
|
+
|
30
|
+
Conflicts:
|
31
|
+
hw/scsi/scsi-generic.c
|
32
|
+
We don't have BlockBackend in downstream, use bdrv_get_max_transfer_length()
|
33
|
+
instead.
|
34
|
+
|
35
|
+
The context is different because we don't have fa0d653b0 (scsi-generic:
|
36
|
+
identify AIO callbacks more clearly).
|
37
|
+
|
38
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
39
|
+
---
|
40
|
+
hw/scsi/scsi-generic.c | 11 +++++++++++
|
41
|
+
1 file changed, 11 insertions(+)
|
42
|
+
|
43
|
+
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
|
44
|
+
index 3733d2c..6b0c1fe 100644
|
45
|
+
--- a/hw/scsi/scsi-generic.c
|
46
|
+
+++ b/hw/scsi/scsi-generic.c
|
47
|
+
@@ -207,6 +207,17 @@ static void scsi_read_complete(void * opaque, int ret)
|
48
|
+
(r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
|
49
|
+
s->blocksize = ldl_be_p(&r->buf[8]);
|
50
|
+
s->max_lba = ldq_be_p(&r->buf[0]);
|
51
|
+
+ } else if (s->type == TYPE_DISK &&
|
52
|
+
+ r->req.cmd.buf[0] == INQUIRY &&
|
53
|
+
+ r->req.cmd.buf[2] == 0xb0) {
|
54
|
+
+ uint32_t max_xfer_len = bdrv_get_max_transfer_length(s->conf.bs);
|
55
|
+
+ if (max_xfer_len) {
|
56
|
+
+ stl_be_p(&r->buf[8], max_xfer_len);
|
57
|
+
+ /* Also take care of the opt xfer len. */
|
58
|
+
+ if (ldl_be_p(&r->buf[12]) > max_xfer_len) {
|
59
|
+
+ stl_be_p(&r->buf[12], max_xfer_len);
|
60
|
+
+ }
|
61
|
+
+ }
|
62
|
+
}
|
63
|
+
bdrv_set_guest_block_size(s->conf.bs, s->blocksize);
|
64
|
+
|
65
|
+
--
|
66
|
+
1.8.3.1
|
67
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
From 2dc9b654f678a1cfa95a680f31085cdff1e648b2 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Miroslav Rezanina <mrezanin@redhat.com>
|
3
|
+
Date: Fri, 22 Apr 2016 05:14:07 +0200
|
4
|
+
Subject: [PATCH 02/10] seccomp: adding sysinfo system call to whitelist
|
5
|
+
|
6
|
+
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
|
7
|
+
Message-id: <1461302047-6677-1-git-send-email-mrezanin@redhat.com>
|
8
|
+
Patchwork-id: 70221
|
9
|
+
O-Subject: [RHEL 7.3 qemu-kvm PATCH] seccomp: adding sysinfo system call to whitelist
|
10
|
+
Bugzilla: 1177318
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
13
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
14
|
+
|
15
|
+
From: Miroslav Rezanina <mrezanin@redhat.com>
|
16
|
+
|
17
|
+
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1177318
|
18
|
+
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=10914613
|
19
|
+
RHEV: BZ 1177309, fixed with 2.6 rebase
|
20
|
+
|
21
|
+
Newer version of nss-softokn libraries (> 3.16.2.3) use sysinfo call
|
22
|
+
so qemu using rbd image hang after start when run in sandbox mode.
|
23
|
+
|
24
|
+
To allow using rbd images in sandbox mode we have to whitelist it.
|
25
|
+
|
26
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
27
|
+
Acked-by: Eduardo Otubo <eduardo.otubo@profitbricks.com>
|
28
|
+
(cherry picked from commit 8e08f8a4a7f613af65b29fcc3ac3bfc2a08a3343)
|
29
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
30
|
+
---
|
31
|
+
qemu-seccomp.c | 1 +
|
32
|
+
1 file changed, 1 insertion(+)
|
33
|
+
|
34
|
+
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
|
35
|
+
index 5e60fce..e947909 100644
|
36
|
+
--- a/qemu-seccomp.c
|
37
|
+
+++ b/qemu-seccomp.c
|
38
|
+
@@ -249,6 +249,7 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = {
|
39
|
+
{ SCMP_SYS(munlock), 240 },
|
40
|
+
{ SCMP_SYS(semctl), 240 },
|
41
|
+
{ SCMP_SYS(timerfd_create), 240 },
|
42
|
+
+ { SCMP_SYS(sysinfo), 240 },
|
43
|
+
};
|
44
|
+
|
45
|
+
int seccomp_start(void)
|
46
|
+
--
|
47
|
+
1.8.3.1
|
48
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
From f40c437eed664b31984a21ec6bbed12c6b03dd0b Mon Sep 17 00:00:00 2001
|
2
|
+
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
+
Date: Wed, 1 Jun 2016 13:16:08 +0200
|
4
|
+
Subject: [PATCH 1/2] spice: do not require TCP ports
|
5
|
+
MIME-Version: 1.0
|
6
|
+
Content-Type: text/plain; charset=UTF-8
|
7
|
+
Content-Transfer-Encoding: 8bit
|
8
|
+
|
9
|
+
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
10
|
+
Message-id: <1464786968-25518-2-git-send-email-kraxel@redhat.com>
|
11
|
+
Patchwork-id: 70523
|
12
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] spice: do not require TCP ports
|
13
|
+
Bugzilla: 1336491
|
14
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
15
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
16
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
17
|
+
|
18
|
+
From: Marc-André Lureau <marcandre.lureau@gmail.com>
|
19
|
+
|
20
|
+
It is possible to use Spice server without TCP port. On local VM,
|
21
|
+
qemu (and libvirt) can add new clients thanks to QMP add_client command.
|
22
|
+
|
23
|
+
Signed-off-by: Marc-André Lureau <marcandre.lureau@gmail.com>
|
24
|
+
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
25
|
+
(cherry picked from commit cf7856adefebe86e0cd50302d93b3045e3111690)
|
26
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
27
|
+
---
|
28
|
+
ui/spice-core.c | 4 ----
|
29
|
+
1 file changed, 4 deletions(-)
|
30
|
+
|
31
|
+
diff --git a/ui/spice-core.c b/ui/spice-core.c
|
32
|
+
index 141afd1..8d6e726 100644
|
33
|
+
--- a/ui/spice-core.c
|
34
|
+
+++ b/ui/spice-core.c
|
35
|
+
@@ -648,10 +648,6 @@ void qemu_spice_init(void)
|
36
|
+
}
|
37
|
+
port = qemu_opt_get_number(opts, "port", 0);
|
38
|
+
tls_port = qemu_opt_get_number(opts, "tls-port", 0);
|
39
|
+
- if (!port && !tls_port) {
|
40
|
+
- error_report("neither port nor tls-port specified for spice");
|
41
|
+
- exit(1);
|
42
|
+
- }
|
43
|
+
if (port < 0 || port > 65535) {
|
44
|
+
error_report("spice port is out of range");
|
45
|
+
exit(1);
|
46
|
+
--
|
47
|
+
1.8.3.1
|
48
|
+
|
@@ -0,0 +1,93 @@
|
|
1
|
+
From 73b0c0b62c08330e65e9ec3d54ae5738d4b5211d Mon Sep 17 00:00:00 2001
|
2
|
+
From: Eduardo Habkost <ehabkost@redhat.com>
|
3
|
+
Date: Fri, 9 Sep 2016 19:08:34 +0200
|
4
|
+
Subject: [PATCH 2/2] target-i386: Add more Intel AVX-512 instructions support
|
5
|
+
|
6
|
+
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
|
7
|
+
Message-id: <1473448114-1430-3-git-send-email-ehabkost@redhat.com>
|
8
|
+
Patchwork-id: 72277
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 2/2] target-i386: Add more Intel AVX-512 instructions support
|
10
|
+
Bugzilla: 1372459
|
11
|
+
RH-Acked-by: Bandan Das <bsd@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Luwei Kang <luwei.kang@intel.com>
|
16
|
+
|
17
|
+
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1372459
|
18
|
+
|
19
|
+
Add more AVX512 feature bits, include AVX512DQ, AVX512IFMA,
|
20
|
+
AVX512BW, AVX512VL, AVX512VBMI. Its spec can be found at:
|
21
|
+
https://software.intel.com/sites/default/files/managed/b4/3a/319433-024.pdf
|
22
|
+
|
23
|
+
Signed-off-by: Luwei Kang <luwei.kang@intel.com>
|
24
|
+
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
25
|
+
(cherry picked from commit cc728d1493eee3e20c1547191862e43d3f55e714)
|
26
|
+
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
27
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
28
|
+
---
|
29
|
+
target-i386/cpu.c | 14 +++++++++-----
|
30
|
+
target-i386/cpu.h | 13 +++++++++++++
|
31
|
+
2 files changed, 22 insertions(+), 5 deletions(-)
|
32
|
+
|
33
|
+
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
|
34
|
+
index d9c214c..476306d 100644
|
35
|
+
--- a/target-i386/cpu.c
|
36
|
+
+++ b/target-i386/cpu.c
|
37
|
+
@@ -144,14 +144,18 @@ static const char *svm_feature_name[] = {
|
38
|
+
};
|
39
|
+
|
40
|
+
static const char *cpuid_7_0_ebx_feature_name[] = {
|
41
|
+
- "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
|
42
|
+
- "bmi2", "erms", "invpcid", "rtm", NULL, NULL, "mpx", NULL,
|
43
|
+
- "avx512f", NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
|
44
|
+
- NULL, NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
|
45
|
+
+ "fsgsbase", NULL, NULL, "bmi1",
|
46
|
+
+ "hle", "avx2", NULL, "smep",
|
47
|
+
+ "bmi2", "erms", "invpcid", "rtm",
|
48
|
+
+ NULL, NULL, "mpx", NULL,
|
49
|
+
+ "avx512f", "avx512dq", "rdseed", "adx",
|
50
|
+
+ "smap", "avx512ifma", NULL, NULL,
|
51
|
+
+ NULL, NULL, "avx512pf", "avx512er",
|
52
|
+
+ "avx512cd", NULL, "avx512bw", "avx512vl",
|
53
|
+
};
|
54
|
+
|
55
|
+
static const char *cpuid_7_0_ecx_feature_name[] = {
|
56
|
+
- NULL, NULL, NULL, NULL,
|
57
|
+
+ NULL, "avx512vbmi", NULL, NULL,
|
58
|
+
NULL, NULL, NULL, NULL,
|
59
|
+
NULL, NULL, NULL, NULL,
|
60
|
+
NULL, NULL, NULL, NULL,
|
61
|
+
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
|
62
|
+
index 5c62ee3..d541809 100644
|
63
|
+
--- a/target-i386/cpu.h
|
64
|
+
+++ b/target-i386/cpu.h
|
65
|
+
@@ -560,12 +560,25 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
|
66
|
+
#define CPUID_7_0_EBX_RTM (1U << 11)
|
67
|
+
#define CPUID_7_0_EBX_MPX (1U << 14)
|
68
|
+
#define CPUID_7_0_EBX_AVX512F (1U << 16) /* AVX-512 Foundation */
|
69
|
+
+#define CPUID_7_0_EBX_AVX512DQ (1U << 17) /* AVX-512 Doubleword & Quadword Instrs */
|
70
|
+
#define CPUID_7_0_EBX_RDSEED (1U << 18)
|
71
|
+
#define CPUID_7_0_EBX_ADX (1U << 19)
|
72
|
+
#define CPUID_7_0_EBX_SMAP (1U << 20)
|
73
|
+
+#define CPUID_7_0_EBX_AVX512IFMA (1U << 21) /* AVX-512 Integer Fused Multiply Add */
|
74
|
+
+#define CPUID_7_0_EBX_PCOMMIT (1U << 22) /* Persistent Commit */
|
75
|
+
+#define CPUID_7_0_EBX_CLFLUSHOPT (1U << 23) /* Flush a Cache Line Optimized */
|
76
|
+
+#define CPUID_7_0_EBX_CLWB (1U << 24) /* Cache Line Write Back */
|
77
|
+
#define CPUID_7_0_EBX_AVX512PF (1U << 26) /* AVX-512 Prefetch */
|
78
|
+
#define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */
|
79
|
+
#define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */
|
80
|
+
+#define CPUID_7_0_EBX_AVX512BW (1U << 30) /* AVX-512 Byte and Word Instructions */
|
81
|
+
+#define CPUID_7_0_EBX_AVX512VL (1U << 31) /* AVX-512 Vector Length Extensions */
|
82
|
+
+
|
83
|
+
+#define CPUID_7_0_ECX_VBMI (1U << 1) /* AVX-512 Vector Byte Manipulation Instrs */
|
84
|
+
+#define CPUID_7_0_ECX_UMIP (1U << 2)
|
85
|
+
+#define CPUID_7_0_ECX_PKU (1U << 3)
|
86
|
+
+#define CPUID_7_0_ECX_OSPKE (1U << 4)
|
87
|
+
+#define CPUID_7_0_ECX_RDPID (1U << 22)
|
88
|
+
|
89
|
+
#define CPUID_XSAVE_XSAVEOPT (1U << 0)
|
90
|
+
#define CPUID_XSAVE_XSAVEC (1U << 1)
|
91
|
+
--
|
92
|
+
1.8.3.1
|
93
|
+
|
@@ -0,0 +1,147 @@
|
|
1
|
+
From eb87f1106d038247356ecd3071e6fa5654386ff5 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Eduardo Habkost <ehabkost@redhat.com>
|
3
|
+
Date: Fri, 9 Sep 2016 19:08:33 +0200
|
4
|
+
Subject: [PATCH 1/2] target-i386: Add support for FEAT_7_0_ECX
|
5
|
+
|
6
|
+
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
|
7
|
+
Message-id: <1473448114-1430-2-git-send-email-ehabkost@redhat.com>
|
8
|
+
Patchwork-id: 72276
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH v2 1/2] target-i386: Add support for FEAT_7_0_ECX
|
10
|
+
Bugzilla: 1372459
|
11
|
+
RH-Acked-by: Bandan Das <bsd@redhat.com>
|
12
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Paolo Bonzini <pbonzini@redhat.com>
|
16
|
+
|
17
|
+
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1372459
|
18
|
+
|
19
|
+
Done from scratch by copying what is done for FEAT_7_0_EBX. Compare
|
20
|
+
to upstream commit f74eefe ("target-i386: Add PKU and and OSPKE support",
|
21
|
+
2016-01-21), but without actually adding PKU and OSPKE. Because all
|
22
|
+
these features are "-cpu host"-only, they can be added without modifying
|
23
|
+
machine types.
|
24
|
+
|
25
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
26
|
+
[ehabkost: v2: removed the non-upstream cpuid_level < 7 check]
|
27
|
+
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
28
|
+
|
29
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
30
|
+
---
|
31
|
+
target-i386/cpu.c | 29 ++++++++++++++++++++++++++++-
|
32
|
+
target-i386/cpu.h | 1 +
|
33
|
+
2 files changed, 29 insertions(+), 1 deletion(-)
|
34
|
+
|
35
|
+
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
|
36
|
+
index 1001c47..d9c214c 100644
|
37
|
+
--- a/target-i386/cpu.c
|
38
|
+
+++ b/target-i386/cpu.c
|
39
|
+
@@ -150,6 +150,17 @@ static const char *cpuid_7_0_ebx_feature_name[] = {
|
40
|
+
NULL, NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
|
41
|
+
};
|
42
|
+
|
43
|
+
+static const char *cpuid_7_0_ecx_feature_name[] = {
|
44
|
+
+ NULL, NULL, NULL, NULL,
|
45
|
+
+ NULL, NULL, NULL, NULL,
|
46
|
+
+ NULL, NULL, NULL, NULL,
|
47
|
+
+ NULL, NULL, NULL, NULL,
|
48
|
+
+ NULL, NULL, NULL, NULL,
|
49
|
+
+ NULL, NULL, NULL, NULL,
|
50
|
+
+ NULL, NULL, NULL, NULL,
|
51
|
+
+ NULL, NULL, NULL, NULL,
|
52
|
+
+};
|
53
|
+
+
|
54
|
+
static const char *cpuid_xsave_feature_name[] = {
|
55
|
+
"xsaveopt", "xsavec", "xgetbv1", NULL,
|
56
|
+
NULL, NULL, NULL, NULL,
|
57
|
+
@@ -204,6 +215,12 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
58
|
+
.cpuid_needs_ecx = true, .cpuid_ecx = 0,
|
59
|
+
.cpuid_reg = R_EBX,
|
60
|
+
},
|
61
|
+
+ [FEAT_7_0_ECX] = {
|
62
|
+
+ .feat_names = cpuid_7_0_ecx_feature_name,
|
63
|
+
+ .cpuid_eax = 7,
|
64
|
+
+ .cpuid_needs_ecx = true, .cpuid_ecx = 0,
|
65
|
+
+ .cpuid_reg = R_ECX,
|
66
|
+
+ },
|
67
|
+
[FEAT_XSAVE] = {
|
68
|
+
.feat_names = cpuid_xsave_feature_name,
|
69
|
+
.cpuid_eax = 0xd,
|
70
|
+
@@ -462,6 +479,7 @@ typedef struct x86_def_t {
|
71
|
+
CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
|
72
|
+
CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
|
73
|
+
CPUID_7_0_EBX_RDSEED */
|
74
|
+
+#define TCG_7_0_ECX_FEATURES 0
|
75
|
+
|
76
|
+
/* built-in CPU model definitions
|
77
|
+
*/
|
78
|
+
@@ -1198,8 +1216,11 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
|
79
|
+
if (x86_cpu_def->level >= 7) {
|
80
|
+
x86_cpu_def->features[FEAT_7_0_EBX] =
|
81
|
+
kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
|
82
|
+
+ x86_cpu_def->features[FEAT_7_0_ECX] =
|
83
|
+
+ kvm_arch_get_supported_cpuid(s, 0x7, 0, R_ECX);
|
84
|
+
} else {
|
85
|
+
x86_cpu_def->features[FEAT_7_0_EBX] = 0;
|
86
|
+
+ x86_cpu_def->features[FEAT_7_0_ECX] = 0;
|
87
|
+
}
|
88
|
+
x86_cpu_def->features[FEAT_XSAVE] =
|
89
|
+
kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
|
90
|
+
@@ -1283,6 +1304,9 @@ static int kvm_check_features_against_host(X86CPU *cpu)
|
91
|
+
{&env->features[FEAT_7_0_EBX],
|
92
|
+
&host_def.features[FEAT_7_0_EBX],
|
93
|
+
FEAT_7_0_EBX },
|
94
|
+
+ {&env->features[FEAT_7_0_ECX],
|
95
|
+
+ &host_def.features[FEAT_7_0_ECX],
|
96
|
+
+ FEAT_7_0_ECX },
|
97
|
+
{&env->features[FEAT_XSAVE],
|
98
|
+
&host_def.features[FEAT_XSAVE],
|
99
|
+
FEAT_XSAVE },
|
100
|
+
@@ -1824,6 +1848,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
101
|
+
env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
|
102
|
+
env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
|
103
|
+
env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
|
104
|
+
+ env->features[FEAT_7_0_ECX] |= plus_features[FEAT_7_0_ECX];
|
105
|
+
env->features[FEAT_XSAVE] |= plus_features[FEAT_XSAVE];
|
106
|
+
env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
|
107
|
+
env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
|
108
|
+
@@ -1833,6 +1858,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
109
|
+
env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
|
110
|
+
env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
|
111
|
+
env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
|
112
|
+
+ env->features[FEAT_7_0_ECX] &= ~minus_features[FEAT_7_0_ECX];
|
113
|
+
env->features[FEAT_XSAVE] &= ~minus_features[FEAT_XSAVE];
|
114
|
+
|
115
|
+
out:
|
116
|
+
@@ -1969,6 +1995,7 @@ static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
|
117
|
+
env->features[FEAT_SVM] = def->features[FEAT_SVM];
|
118
|
+
env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
|
119
|
+
env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
|
120
|
+
+ env->features[FEAT_7_0_ECX] = def->features[FEAT_7_0_ECX];
|
121
|
+
env->features[FEAT_XSAVE] = def->features[FEAT_XSAVE];
|
122
|
+
env->cpuid_xlevel2 = def->xlevel2;
|
123
|
+
|
124
|
+
@@ -2206,7 +2233,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
125
|
+
if (count == 0) {
|
126
|
+
*eax = 0; /* Maximum ECX value for sub-leaves */
|
127
|
+
*ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
|
128
|
+
- *ecx = 0; /* Reserved */
|
129
|
+
+ *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
|
130
|
+
*edx = 0; /* Reserved */
|
131
|
+
} else {
|
132
|
+
*eax = 0;
|
133
|
+
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
|
134
|
+
index da7e060..5c62ee3 100644
|
135
|
+
--- a/target-i386/cpu.h
|
136
|
+
+++ b/target-i386/cpu.h
|
137
|
+
@@ -400,6 +400,7 @@ typedef enum FeatureWord {
|
138
|
+
FEAT_1_EDX, /* CPUID[1].EDX */
|
139
|
+
FEAT_1_ECX, /* CPUID[1].ECX */
|
140
|
+
FEAT_7_0_EBX, /* CPUID[EAX=7,ECX=0].EBX */
|
141
|
+
+ FEAT_7_0_ECX, /* CPUID[EAX=7,ECX=0].ECX */
|
142
|
+
FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
|
143
|
+
FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
|
144
|
+
FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
|
145
|
+
--
|
146
|
+
1.8.3.1
|
147
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
From ce561d78c7199821beae26112f41da5733fab5bb Mon Sep 17 00:00:00 2001
|
2
|
+
From: Eduardo Habkost <ehabkost@redhat.com>
|
3
|
+
Date: Wed, 6 Jul 2016 20:47:53 +0200
|
4
|
+
Subject: [PATCH 2/2] target-i386: add Skylake-Client cpu model
|
5
|
+
|
6
|
+
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
|
7
|
+
Message-id: <1467838073-23873-3-git-send-email-ehabkost@redhat.com>
|
8
|
+
Patchwork-id: 71052
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 2/2] target-i386: add Skylake-Client cpu model
|
10
|
+
Bugzilla: 1327599
|
11
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
12
|
+
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
13
|
+
RH-Acked-by: Bandan Das <bsd@redhat.com>
|
14
|
+
|
15
|
+
Introduce Skylake-Client cpu mode which inherits the features from
|
16
|
+
Broadwell and supports some additional features that are: MPX,
|
17
|
+
XSAVEC, and XGETBV1.
|
18
|
+
|
19
|
+
Backport notes:
|
20
|
+
* ARAT feature not included, as it is not available in the
|
21
|
+
qemu-kvm-1.5.3 tree (and disabled by compat code in
|
22
|
+
pc-i440fx-rhel7.2.0 and older on qemu-kvm-rhev)
|
23
|
+
|
24
|
+
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
25
|
+
Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
|
26
|
+
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
|
27
|
+
Reviewed-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
|
28
|
+
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
29
|
+
(cherry picked from commit f6f949e9295889fb272698aea763dcea77d616ce)
|
30
|
+
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
31
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
32
|
+
---
|
33
|
+
target-i386/cpu.c | 43 +++++++++++++++++++++++++++++++++++++++++++
|
34
|
+
1 file changed, 43 insertions(+)
|
35
|
+
|
36
|
+
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
|
37
|
+
index 6650c72..80106ba 100644
|
38
|
+
--- a/target-i386/cpu.c
|
39
|
+
+++ b/target-i386/cpu.c
|
40
|
+
@@ -927,6 +927,49 @@ static x86_def_t builtin_x86_defs[] = {
|
41
|
+
.model_id = "Intel Core Processor (Broadwell)",
|
42
|
+
},
|
43
|
+
{
|
44
|
+
+ .name = "Skylake-Client",
|
45
|
+
+ .level = 0xd,
|
46
|
+
+ .vendor = CPUID_VENDOR_INTEL,
|
47
|
+
+ .family = 6,
|
48
|
+
+ .model = 94,
|
49
|
+
+ .stepping = 3,
|
50
|
+
+ .features[FEAT_1_EDX] =
|
51
|
+
+ CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
|
52
|
+
+ CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
|
53
|
+
+ CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
|
54
|
+
+ CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
|
55
|
+
+ CPUID_DE | CPUID_FP87,
|
56
|
+
+ .features[FEAT_1_ECX] =
|
57
|
+
+ CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
|
58
|
+
+ CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
|
59
|
+
+ CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
|
60
|
+
+ CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
|
61
|
+
+ CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
|
62
|
+
+ CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
|
63
|
+
+ .features[FEAT_8000_0001_EDX] =
|
64
|
+
+ CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
|
65
|
+
+ CPUID_EXT2_SYSCALL,
|
66
|
+
+ .features[FEAT_8000_0001_ECX] =
|
67
|
+
+ CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
|
68
|
+
+ .features[FEAT_7_0_EBX] =
|
69
|
+
+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
|
70
|
+
+ CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
|
71
|
+
+ CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
|
72
|
+
+ CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
|
73
|
+
+ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
|
74
|
+
+ /* Missing: XSAVES (not supported by some Linux versions,
|
75
|
+
+ * including v4.1 to v4.6).
|
76
|
+
+ * KVM doesn't yet expose any XSAVES state save component,
|
77
|
+
+ * and the only one defined in Skylake (processor tracing)
|
78
|
+
+ * probably will block migration anyway.
|
79
|
+
+ */
|
80
|
+
+ .features[FEAT_XSAVE] =
|
81
|
+
+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
|
82
|
+
+ CPUID_XSAVE_XGETBV1,
|
83
|
+
+ .xlevel = 0x80000008,
|
84
|
+
+ .model_id = "Intel Core Processor (Skylake)",
|
85
|
+
+ },
|
86
|
+
+ {
|
87
|
+
.name = "Opteron_G1",
|
88
|
+
.level = 5,
|
89
|
+
.vendor = CPUID_VENDOR_AMD,
|
90
|
+
--
|
91
|
+
1.8.3.1
|
92
|
+
|
@@ -0,0 +1,168 @@
|
|
1
|
+
From 5fcaf5176d7545518c76f3aa8ea7ce6fb063c62d Mon Sep 17 00:00:00 2001
|
2
|
+
From: Eduardo Habkost <ehabkost@redhat.com>
|
3
|
+
Date: Wed, 6 Jul 2016 20:47:52 +0200
|
4
|
+
Subject: [PATCH 1/2] target-i386: add feature flags for CPUID[EAX=0xd, ECX=1]
|
5
|
+
|
6
|
+
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
|
7
|
+
Message-id: <1467838073-23873-2-git-send-email-ehabkost@redhat.com>
|
8
|
+
Patchwork-id: 71051
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/2] target-i386: add feature flags for CPUID[EAX=0xd, ECX=1]
|
10
|
+
Bugzilla: 1327599
|
11
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
12
|
+
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
13
|
+
RH-Acked-by: Bandan Das <bsd@redhat.com>
|
14
|
+
|
15
|
+
From: Paolo Bonzini <pbonzini@redhat.com>
|
16
|
+
|
17
|
+
These represent xsave-related capabilities of the processor, and KVM may
|
18
|
+
or may not support them.
|
19
|
+
|
20
|
+
Add feature bits so that they are considered by "-cpu ...,enforce", and use
|
21
|
+
the new feature work instead of calling kvm_arch_get_supported_cpuid.
|
22
|
+
|
23
|
+
Bit 3 (XSAVES) is not migratables because it requires saving MSR_IA32_XSS.
|
24
|
+
Neither KVM nor any commonly available hardware supports it anyway.
|
25
|
+
|
26
|
+
RHEL backport notes:
|
27
|
+
* In addition to allowing xsave flags to be configured, this
|
28
|
+
patch is a bug fix because we shouldn't use
|
29
|
+
kvm_arch_supported_cpuid() directly when configuring CPUID for
|
30
|
+
the guest
|
31
|
+
* tcg_features didn't exist, handle it inside x86_cpu_realizefn()
|
32
|
+
directly in the !kvm_enabled() check
|
33
|
+
* As the unmigratable_flags mechanism is not present yet,
|
34
|
+
remove the "xsaves" flag name so it can't be enabled manually
|
35
|
+
(otherwise we would need to backport upstream commit
|
36
|
+
18cd2c17b5370369a886155c001da0a7f54bbcca too)
|
37
|
+
|
38
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
39
|
+
(cherry picked from commit 0bb0b2d2fe7f645ddaf1f0ff40ac669c9feb4aa1)
|
40
|
+
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
41
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
42
|
+
---
|
43
|
+
target-i386/cpu.c | 28 +++++++++++++++++++++++++++-
|
44
|
+
target-i386/cpu.h | 6 ++++++
|
45
|
+
2 files changed, 33 insertions(+), 1 deletion(-)
|
46
|
+
|
47
|
+
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
|
48
|
+
index 06efe17..6650c72 100644
|
49
|
+
--- a/target-i386/cpu.c
|
50
|
+
+++ b/target-i386/cpu.c
|
51
|
+
@@ -150,6 +150,17 @@ static const char *cpuid_7_0_ebx_feature_name[] = {
|
52
|
+
NULL, NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
|
53
|
+
};
|
54
|
+
|
55
|
+
+static const char *cpuid_xsave_feature_name[] = {
|
56
|
+
+ "xsaveopt", "xsavec", "xgetbv1", NULL,
|
57
|
+
+ NULL, NULL, NULL, NULL,
|
58
|
+
+ NULL, NULL, NULL, NULL,
|
59
|
+
+ NULL, NULL, NULL, NULL,
|
60
|
+
+ NULL, NULL, NULL, NULL,
|
61
|
+
+ NULL, NULL, NULL, NULL,
|
62
|
+
+ NULL, NULL, NULL, NULL,
|
63
|
+
+ NULL, NULL, NULL, NULL,
|
64
|
+
+};
|
65
|
+
+
|
66
|
+
typedef struct FeatureWordInfo {
|
67
|
+
const char **feat_names;
|
68
|
+
uint32_t cpuid_eax; /* Input EAX for CPUID */
|
69
|
+
@@ -193,6 +204,12 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
70
|
+
.cpuid_needs_ecx = true, .cpuid_ecx = 0,
|
71
|
+
.cpuid_reg = R_EBX,
|
72
|
+
},
|
73
|
+
+ [FEAT_XSAVE] = {
|
74
|
+
+ .feat_names = cpuid_xsave_feature_name,
|
75
|
+
+ .cpuid_eax = 0xd,
|
76
|
+
+ .cpuid_needs_ecx = true, .cpuid_ecx = 1,
|
77
|
+
+ .cpuid_reg = R_EAX,
|
78
|
+
+ },
|
79
|
+
};
|
80
|
+
|
81
|
+
typedef struct X86RegisterInfo32 {
|
82
|
+
@@ -833,6 +850,8 @@ static x86_def_t builtin_x86_defs[] = {
|
83
|
+
CPUID_EXT2_SYSCALL,
|
84
|
+
.features[FEAT_8000_0001_ECX] =
|
85
|
+
CPUID_EXT3_LAHF_LM,
|
86
|
+
+ .features[FEAT_XSAVE] =
|
87
|
+
+ CPUID_XSAVE_XSAVEOPT,
|
88
|
+
.xlevel = 0x8000000A,
|
89
|
+
.model_id = "Intel Xeon E312xx (Sandy Bridge)",
|
90
|
+
},
|
91
|
+
@@ -866,6 +885,8 @@ static x86_def_t builtin_x86_defs[] = {
|
92
|
+
CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
|
93
|
+
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
|
94
|
+
CPUID_7_0_EBX_RTM,
|
95
|
+
+ .features[FEAT_XSAVE] =
|
96
|
+
+ CPUID_XSAVE_XSAVEOPT,
|
97
|
+
.xlevel = 0x8000000A,
|
98
|
+
.model_id = "Intel Core Processor (Haswell)",
|
99
|
+
},
|
100
|
+
@@ -900,6 +921,8 @@ static x86_def_t builtin_x86_defs[] = {
|
101
|
+
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
|
102
|
+
CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
|
103
|
+
CPUID_7_0_EBX_SMAP,
|
104
|
+
+ .features[FEAT_XSAVE] =
|
105
|
+
+ CPUID_XSAVE_XSAVEOPT,
|
106
|
+
.xlevel = 0x8000000A,
|
107
|
+
.model_id = "Intel Core Processor (Broadwell)",
|
108
|
+
},
|
109
|
+
@@ -1017,6 +1040,7 @@ static x86_def_t builtin_x86_defs[] = {
|
110
|
+
CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
|
111
|
+
CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
|
112
|
+
CPUID_EXT3_LAHF_LM,
|
113
|
+
+ /* no xsaveopt! */
|
114
|
+
.xlevel = 0x8000001A,
|
115
|
+
.model_id = "AMD Opteron 62xx class CPU",
|
116
|
+
},
|
117
|
+
@@ -1051,6 +1075,7 @@ static x86_def_t builtin_x86_defs[] = {
|
118
|
+
CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
|
119
|
+
CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
|
120
|
+
CPUID_EXT3_LAHF_LM,
|
121
|
+
+ /* no xsaveopt! */
|
122
|
+
.xlevel = 0x8000001A,
|
123
|
+
.model_id = "AMD Opteron 63xx class CPU",
|
124
|
+
},
|
125
|
+
@@ -2196,7 +2221,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
126
|
+
*eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
|
127
|
+
*ebx = *ecx;
|
128
|
+
} else if (count == 1) {
|
129
|
+
- *eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
|
130
|
+
+ *eax = env->features[FEAT_XSAVE];
|
131
|
+
} else if (count < ARRAY_SIZE(ext_save_areas)) {
|
132
|
+
const ExtSaveArea *esa = &ext_save_areas[count];
|
133
|
+
if ((env->features[esa->feature] & esa->bits) == esa->bits &&
|
134
|
+
@@ -2540,6 +2565,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
|
135
|
+
);
|
136
|
+
env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
|
137
|
+
env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
|
138
|
+
+ env->features[FEAT_XSAVE] = 0;
|
139
|
+
} else {
|
140
|
+
if ((cpu->check_cpuid || cpu->enforce_cpuid)
|
141
|
+
&& kvm_check_features_against_host(cpu) && cpu->enforce_cpuid) {
|
142
|
+
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
|
143
|
+
index 61e9b86..da7e060 100644
|
144
|
+
--- a/target-i386/cpu.h
|
145
|
+
+++ b/target-i386/cpu.h
|
146
|
+
@@ -405,6 +405,7 @@ typedef enum FeatureWord {
|
147
|
+
FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
|
148
|
+
FEAT_KVM, /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
|
149
|
+
FEAT_SVM, /* CPUID[8000_000A].EDX */
|
150
|
+
+ FEAT_XSAVE, /* CPUID[EAX=0xd,ECX=1].EAX */
|
151
|
+
FEATURE_WORDS,
|
152
|
+
} FeatureWord;
|
153
|
+
|
154
|
+
@@ -565,6 +566,11 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
|
155
|
+
#define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */
|
156
|
+
#define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */
|
157
|
+
|
158
|
+
+#define CPUID_XSAVE_XSAVEOPT (1U << 0)
|
159
|
+
+#define CPUID_XSAVE_XSAVEC (1U << 1)
|
160
|
+
+#define CPUID_XSAVE_XGETBV1 (1U << 2)
|
161
|
+
+#define CPUID_XSAVE_XSAVES (1U << 3)
|
162
|
+
+
|
163
|
+
#define CPUID_VENDOR_SZ 12
|
164
|
+
|
165
|
+
#define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
|
166
|
+
--
|
167
|
+
1.8.3.1
|
168
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
From b05eb2cc7decc07ed044484861587b3490144d02 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Paolo Bonzini <pbonzini@redhat.com>
|
3
|
+
Date: Wed, 8 Jun 2016 13:04:21 +0200
|
4
|
+
Subject: [PATCH 2/3] target-i386: fix pcmpxstrx equal-ordered (strstr) mode
|
5
|
+
|
6
|
+
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
7
|
+
Message-id: <1465391061-17748-1-git-send-email-pbonzini@redhat.com>
|
8
|
+
Patchwork-id: 70570
|
9
|
+
O-Subject: [RHEL7.3/7.2.z qemu-kvm PATCH] target-i386: fix pcmpxstrx equal-ordered (strstr) mode
|
10
|
+
Bugzilla: 1340971
|
11
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
13
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
14
|
+
|
15
|
+
Kindly requested by the Openstack folks, who sometimes uses TCG
|
16
|
+
instead of nested virt.
|
17
|
+
|
18
|
+
In this mode, referring an invalid element of the source forces the
|
19
|
+
result to false (table 4-7, last column) but referring an invalid
|
20
|
+
element of the destination forces the result to true, so the outer
|
21
|
+
loop should still be run even if some elements of the destination
|
22
|
+
will be invalid. They will be avoided in the inner loop, which
|
23
|
+
correctly bounds "i" to validd, but they will still contribute to a
|
24
|
+
positive outcome of the search.
|
25
|
+
|
26
|
+
This fixes tst_strstr in glibc 2.17.
|
27
|
+
|
28
|
+
Reported-by: Florian Weimer <fweimer@redhat.com>
|
29
|
+
Cc: Richard Henderson <rth@twiddle.net>
|
30
|
+
Cc: Eduardo Habkost <ehabkost@redhat.com>
|
31
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
32
|
+
(cherry picked from commit 54c54f8b56047d3c2420e1ae06a6a8890c220ac4)
|
33
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
34
|
+
---
|
35
|
+
target-i386/ops_sse.h | 4 ++--
|
36
|
+
1 file changed, 2 insertions(+), 2 deletions(-)
|
37
|
+
|
38
|
+
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
|
39
|
+
index eb24b5f..5145d9e 100644
|
40
|
+
--- a/target-i386/ops_sse.h
|
41
|
+
+++ b/target-i386/ops_sse.h
|
42
|
+
@@ -2034,10 +2034,10 @@ static inline unsigned pcmpxstrx(CPUX86State *env, Reg *d, Reg *s,
|
43
|
+
}
|
44
|
+
break;
|
45
|
+
case 3:
|
46
|
+
- for (j = valids - validd; j >= 0; j--) {
|
47
|
+
+ for (j = valids; j >= 0; j--) {
|
48
|
+
res <<= 1;
|
49
|
+
v = 1;
|
50
|
+
- for (i = MIN(upper - j, validd); i >= 0; i--) {
|
51
|
+
+ for (i = MIN(valids - j, validd); i >= 0; i--) {
|
52
|
+
v &= (pcmp_val(s, ctrl, i + j) == pcmp_val(d, ctrl, i));
|
53
|
+
}
|
54
|
+
res |= v;
|
55
|
+
--
|
56
|
+
1.8.3.1
|
57
|
+
|
@@ -0,0 +1,93 @@
|
|
1
|
+
From f9a24822687113e34194f05aeb641365b8202e9e Mon Sep 17 00:00:00 2001
|
2
|
+
From: Amit Shah <amit.shah@redhat.com>
|
3
|
+
Date: Wed, 25 Nov 2015 05:51:34 +0100
|
4
|
+
Subject: [PATCH 4/6] target-i386: get/put MSR_TSC_AUX across reset and
|
5
|
+
migration
|
6
|
+
|
7
|
+
Message-id: <daab7f1c955ec81df8aff4ab10fd6ae17e16e99e.1448430513.git.amit.shah@redhat.com>
|
8
|
+
Patchwork-id: 68467
|
9
|
+
O-Subject: [RHEL 7.3 qemu-kvm PATCH 1/1] target-i386: get/put MSR_TSC_AUX across reset and migration
|
10
|
+
Bugzilla: 1265427
|
11
|
+
RH-Acked-by: Juan Quintela <quintela@redhat.com>
|
12
|
+
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
There's one report of migration breaking due to missing MSR_TSC_AUX
|
16
|
+
save/restore. Fix this by adding a new subsection that saves the state
|
17
|
+
of this MSR.
|
18
|
+
|
19
|
+
https://bugzilla.redhat.com/show_bug.cgi?id=1261797
|
20
|
+
|
21
|
+
Reported-by: Xiaoqing Wei <xwei@redhat.com>
|
22
|
+
Signed-off-by: Amit Shah <amit.shah@redhat.com>
|
23
|
+
CC: Paolo Bonzini <pbonzini@redhat.com>
|
24
|
+
CC: Juan Quintela <quintela@redhat.com>
|
25
|
+
CC: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
26
|
+
CC: Marcelo Tosatti <mtosatti@redhat.com>
|
27
|
+
CC: Richard Henderson <rth@twiddle.net>
|
28
|
+
CC: Eduardo Habkost <ehabkost@redhat.com>
|
29
|
+
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
|
30
|
+
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
31
|
+
(cherry picked from commit c9b8f6b6210847b4381c5b2ee172b1c7eb9985d6)
|
32
|
+
Signed-off-by: Amit Shah <amit.shah@redhat.com>
|
33
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
34
|
+
---
|
35
|
+
target-i386/kvm.c | 14 ++++++++++++++
|
36
|
+
1 file changed, 14 insertions(+)
|
37
|
+
|
38
|
+
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
|
39
|
+
index c91bfb8..e1b0ca2 100644
|
40
|
+
--- a/target-i386/kvm.c
|
41
|
+
+++ b/target-i386/kvm.c
|
42
|
+
@@ -63,6 +63,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
43
|
+
|
44
|
+
static bool has_msr_star;
|
45
|
+
static bool has_msr_hsave_pa;
|
46
|
+
+static bool has_msr_tsc_aux;
|
47
|
+
static bool has_msr_tsc_adjust;
|
48
|
+
static bool has_msr_tsc_deadline;
|
49
|
+
static bool has_msr_async_pf_en;
|
50
|
+
@@ -774,6 +775,10 @@ static int kvm_get_supported_msrs(KVMState *s)
|
51
|
+
has_msr_hsave_pa = true;
|
52
|
+
continue;
|
53
|
+
}
|
54
|
+
+ if (kvm_msr_list->indices[i] == MSR_TSC_AUX) {
|
55
|
+
+ has_msr_tsc_aux = true;
|
56
|
+
+ continue;
|
57
|
+
+ }
|
58
|
+
if (kvm_msr_list->indices[i] == MSR_TSC_ADJUST) {
|
59
|
+
has_msr_tsc_adjust = true;
|
60
|
+
continue;
|
61
|
+
@@ -1159,6 +1164,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
|
62
|
+
if (has_msr_hsave_pa) {
|
63
|
+
kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave);
|
64
|
+
}
|
65
|
+
+ if (has_msr_tsc_aux) {
|
66
|
+
+ kvm_msr_entry_set(&msrs[n++], MSR_TSC_AUX, env->tsc_aux);
|
67
|
+
+ }
|
68
|
+
if (has_msr_tsc_adjust) {
|
69
|
+
kvm_msr_entry_set(&msrs[n++], MSR_TSC_ADJUST, env->tsc_adjust);
|
70
|
+
}
|
71
|
+
@@ -1507,6 +1515,9 @@ static int kvm_get_msrs(X86CPU *cpu)
|
72
|
+
if (has_msr_hsave_pa) {
|
73
|
+
msrs[n++].index = MSR_VM_HSAVE_PA;
|
74
|
+
}
|
75
|
+
+ if (has_msr_tsc_aux) {
|
76
|
+
+ msrs[n++].index = MSR_TSC_AUX;
|
77
|
+
+ }
|
78
|
+
if (has_msr_tsc_adjust) {
|
79
|
+
msrs[n++].index = MSR_TSC_ADJUST;
|
80
|
+
}
|
81
|
+
@@ -1636,6 +1647,9 @@ static int kvm_get_msrs(X86CPU *cpu)
|
82
|
+
case MSR_IA32_TSC:
|
83
|
+
env->tsc = msrs[i].data;
|
84
|
+
break;
|
85
|
+
+ case MSR_TSC_AUX:
|
86
|
+
+ env->tsc_aux = msrs[i].data;
|
87
|
+
+ break;
|
88
|
+
case MSR_TSC_ADJUST:
|
89
|
+
env->tsc_adjust = msrs[i].data;
|
90
|
+
break;
|
91
|
+
--
|
92
|
+
1.8.3.1
|
93
|
+
|
@@ -0,0 +1,104 @@
|
|
1
|
+
From d15566b6a91973dbf83c92a9678bd3ac4939af75 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Miroslav Rezanina <mrezanin@redhat.com>
|
3
|
+
Date: Fri, 29 Jul 2016 07:41:27 +0200
|
4
|
+
Subject: [PATCH 16/16] trace: remove malloc tracing
|
5
|
+
|
6
|
+
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
|
7
|
+
Message-id: <1469778087-316-1-git-send-email-mrezanin@redhat.com>
|
8
|
+
Patchwork-id: 71514
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH] trace: remove malloc tracing
|
10
|
+
Bugzilla: 1360137
|
11
|
+
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
12
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
13
|
+
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
14
|
+
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
15
|
+
|
16
|
+
From: Paolo Bonzini <pbonzini@redhat.com>
|
17
|
+
|
18
|
+
The malloc vtable is not supported anymore in glib, because it broke
|
19
|
+
when constructors called g_malloc. Remove tracing of g_malloc,
|
20
|
+
g_realloc and g_free calls.
|
21
|
+
|
22
|
+
Note that, for systemtap users, glib also provides tracepoints
|
23
|
+
glib.mem_alloc, glib.mem_free, glib.mem_realloc, glib.slice_alloc
|
24
|
+
and glib.slice_free.
|
25
|
+
|
26
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
27
|
+
Reviewed-by: Alberto Garcia <berto@igalia.com>
|
28
|
+
Message-id: 1442417924-25831-1-git-send-email-pbonzini@redhat.com
|
29
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
30
|
+
(cherry picked from commit 98cf48f60aa4999f5b2808569a193a401a390e6a)
|
31
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
32
|
+
---
|
33
|
+
trace-events | 3 ---
|
34
|
+
vl.c | 26 --------------------------
|
35
|
+
2 files changed, 29 deletions(-)
|
36
|
+
|
37
|
+
diff --git a/trace-events b/trace-events
|
38
|
+
index af5147a..6cd46e9 100644
|
39
|
+
--- a/trace-events
|
40
|
+
+++ b/trace-events
|
41
|
+
@@ -474,9 +474,6 @@ scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag %d"
|
42
|
+
vm_state_notify(int running, int reason) "running %d reason %d"
|
43
|
+
load_file(const char *name, const char *path) "name %s location %s"
|
44
|
+
runstate_set(int new_state) "new state %d"
|
45
|
+
-g_malloc(size_t size, void *ptr) "size %zu ptr %p"
|
46
|
+
-g_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
|
47
|
+
-g_free(void *ptr) "ptr %p"
|
48
|
+
qemu_system_shutdown_request(void) ""
|
49
|
+
qemu_system_powerdown_request(void) ""
|
50
|
+
|
51
|
+
diff --git a/vl.c b/vl.c
|
52
|
+
index 35b927e..9756361 100644
|
53
|
+
--- a/vl.c
|
54
|
+
+++ b/vl.c
|
55
|
+
@@ -2738,26 +2738,6 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
|
56
|
+
return popt;
|
57
|
+
}
|
58
|
+
|
59
|
+
-static gpointer malloc_and_trace(gsize n_bytes)
|
60
|
+
-{
|
61
|
+
- void *ptr = malloc(n_bytes);
|
62
|
+
- trace_g_malloc(n_bytes, ptr);
|
63
|
+
- return ptr;
|
64
|
+
-}
|
65
|
+
-
|
66
|
+
-static gpointer realloc_and_trace(gpointer mem, gsize n_bytes)
|
67
|
+
-{
|
68
|
+
- void *ptr = realloc(mem, n_bytes);
|
69
|
+
- trace_g_realloc(mem, n_bytes, ptr);
|
70
|
+
- return ptr;
|
71
|
+
-}
|
72
|
+
-
|
73
|
+
-static void free_and_trace(gpointer mem)
|
74
|
+
-{
|
75
|
+
- trace_g_free(mem);
|
76
|
+
- free(mem);
|
77
|
+
-}
|
78
|
+
-
|
79
|
+
static int object_set_property(const char *name, const char *value, void *opaque)
|
80
|
+
{
|
81
|
+
Object *obj = OBJECT(opaque);
|
82
|
+
@@ -2832,11 +2812,6 @@ int main(int argc, char **argv, char **envp)
|
83
|
+
bool userconfig = true;
|
84
|
+
const char *log_mask = NULL;
|
85
|
+
const char *log_file = NULL;
|
86
|
+
- GMemVTable mem_trace = {
|
87
|
+
- .malloc = malloc_and_trace,
|
88
|
+
- .realloc = realloc_and_trace,
|
89
|
+
- .free = free_and_trace,
|
90
|
+
- };
|
91
|
+
const char *trace_events = NULL;
|
92
|
+
const char *trace_file = NULL;
|
93
|
+
FILE *vmstate_dump_file = NULL;
|
94
|
+
@@ -2845,7 +2820,6 @@ int main(int argc, char **argv, char **envp)
|
95
|
+
error_set_progname(argv[0]);
|
96
|
+
qemu_init_exec_dir(argv[0]);
|
97
|
+
|
98
|
+
- g_mem_set_vtable(&mem_trace);
|
99
|
+
if (!g_thread_supported()) {
|
100
|
+
#if !GLIB_CHECK_VERSION(2, 31, 0)
|
101
|
+
g_thread_init(NULL);
|
102
|
+
--
|
103
|
+
1.8.3.1
|
104
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
From 756b23c15387acefe4139831c2f3c8a5f3d41bb2 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 18 Jul 2016 01:32:10 +0200
|
4
|
+
Subject: [PATCH 7/7] util: Fix MIN_NON_ZERO
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1468805530-19033-1-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 71200
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 7/6] util: Fix MIN_NON_ZERO
|
10
|
+
Bugzilla: 1318199
|
11
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
12
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
15
|
+
|
16
|
+
MIN_NON_ZERO(1, 0) is evaluated to 0. Rewrite the macro to fix it.
|
17
|
+
|
18
|
+
Reported-by: Miroslav Rezanina <mrezanin@redhat.com>
|
19
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
20
|
+
Message-Id: <1468306113-847-1-git-send-email-famz@redhat.com>
|
21
|
+
Reviewed-by: Eric Blake <eblake@redhat.com>
|
22
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
23
|
+
(cherry picked from commit d27ba624aa1dfe5c07cc01200d95967ffce905d9)
|
24
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
include/qemu/osdep.h | 3 ++-
|
28
|
+
1 file changed, 2 insertions(+), 1 deletion(-)
|
29
|
+
|
30
|
+
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
|
31
|
+
index c47a600..5ca05bc 100644
|
32
|
+
--- a/include/qemu/osdep.h
|
33
|
+
+++ b/include/qemu/osdep.h
|
34
|
+
@@ -71,7 +71,8 @@ typedef signed int int_fast16_t;
|
35
|
+
/* Minimum function that returns zero only iff both values are zero.
|
36
|
+
* Intended for use with unsigned values only. */
|
37
|
+
#ifndef MIN_NON_ZERO
|
38
|
+
-#define MIN_NON_ZERO(a, b) (((a) != 0 && (a) < (b)) ? (a) : (b))
|
39
|
+
+#define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \
|
40
|
+
+ ((b) == 0 ? (a) : (MIN(a, b))))
|
41
|
+
#endif
|
42
|
+
|
43
|
+
#ifndef ROUND_UP
|
44
|
+
--
|
45
|
+
1.8.3.1
|
46
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
From 6e14ac55a7b40804cf69de560f38561214129b07 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 11 Jul 2016 05:33:34 +0200
|
4
|
+
Subject: [PATCH 1/7] util: introduce MIN_NON_ZERO
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1468215219-30793-2-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 71105
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/6] util: introduce MIN_NON_ZERO
|
10
|
+
Bugzilla: 1318199
|
11
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
12
|
+
RH-Acked-by: John Snow <jsnow@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Peter Lieven <pl@kamp.de>
|
16
|
+
|
17
|
+
at least in block layer we have the case of limits being defined for a
|
18
|
+
BlockDriverState. However, in this context often zero (0) has the special
|
19
|
+
meanining of undefined which means no limit. If two of those limits are
|
20
|
+
combined and the minimum is needed the minimum function should only return
|
21
|
+
zero if both parameters are zero.
|
22
|
+
|
23
|
+
Signed-off-by: Peter Lieven <pl@kamp.de>
|
24
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
25
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
26
|
+
(cherry picked from commit ac3a8726644d4783eacf54212d23db01d1d30044)
|
27
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
28
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
29
|
+
---
|
30
|
+
include/qemu/osdep.h | 6 ++++++
|
31
|
+
1 file changed, 6 insertions(+)
|
32
|
+
|
33
|
+
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
|
34
|
+
index 8984da0..c47a600 100644
|
35
|
+
--- a/include/qemu/osdep.h
|
36
|
+
+++ b/include/qemu/osdep.h
|
37
|
+
@@ -68,6 +68,12 @@ typedef signed int int_fast16_t;
|
38
|
+
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
39
|
+
#endif
|
40
|
+
|
41
|
+
+/* Minimum function that returns zero only iff both values are zero.
|
42
|
+
+ * Intended for use with unsigned values only. */
|
43
|
+
+#ifndef MIN_NON_ZERO
|
44
|
+
+#define MIN_NON_ZERO(a, b) (((a) != 0 && (a) < (b)) ? (a) : (b))
|
45
|
+
+#endif
|
46
|
+
+
|
47
|
+
#ifndef ROUND_UP
|
48
|
+
#define ROUND_UP(n,d) (((n) + (d) - 1) & -(d))
|
49
|
+
#endif
|
50
|
+
--
|
51
|
+
1.8.3.1
|
52
|
+
|
@@ -1,13 +1,13 @@
|
|
1
|
-
From
|
1
|
+
From c5ee3f3aab59ff26b0fed770077a16714da9696e Mon Sep 17 00:00:00 2001
|
2
2
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
-
Date:
|
4
|
-
Subject: [PATCH
|
3
|
+
Date: Thu, 28 Apr 2016 16:07:27 +0200
|
4
|
+
Subject: [PATCH 22/27] vga: Remove some "should be done in BIOS" comments
|
5
5
|
|
6
6
|
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
-
Message-id: <
|
8
|
-
Patchwork-id:
|
9
|
-
O-Subject: [virt-devel] [RHEL-7.
|
10
|
-
Bugzilla:
|
7
|
+
Message-id: <1461859652-20918-2-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 70292
|
9
|
+
O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 1/6] vga: Remove some "should be done in BIOS" comments
|
10
|
+
Bugzilla: 1331413
|
11
11
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
12
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
13
|
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
@@ -20,6 +20,7 @@ using the DISPI interface to initialize the card.
|
|
20
20
|
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
21
21
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
22
22
|
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
23
|
+
(cherry picked from commit ace89b8ff21cc3fb20986a334e54e6e6a1ccf729)
|
23
24
|
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
24
25
|
---
|
25
26
|
hw/display/vga.c | 6 ++----
|
@@ -1,13 +1,13 @@
|
|
1
|
-
From
|
1
|
+
From 40d4a0ec487abcde65d4175dde0c9dda45b570f9 Mon Sep 17 00:00:00 2001
|
2
2
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
3
|
Date: Thu, 16 Jun 2016 15:30:11 +0200
|
4
|
-
Subject: [PATCH] vga: add sr_vbe register set
|
4
|
+
Subject: [PATCH 2/2] vga: add sr_vbe register set
|
5
5
|
|
6
6
|
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
7
|
Message-id: <1466091011-8095-2-git-send-email-kraxel@redhat.com>
|
8
8
|
Patchwork-id: 70639
|
9
9
|
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] vga: add sr_vbe register set
|
10
|
-
Bugzilla:
|
10
|
+
Bugzilla: 1346982
|
11
11
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
12
12
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
13
13
|
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
@@ -1,13 +1,13 @@
|
|
1
|
-
From
|
1
|
+
From 6e615e8fbbd979134868bcd63150365d48d12137 Mon Sep 17 00:00:00 2001
|
2
2
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
-
Date:
|
4
|
-
Subject: [PATCH
|
3
|
+
Date: Thu, 28 Apr 2016 16:07:29 +0200
|
4
|
+
Subject: [PATCH 24/27] vga: add vbe_enabled() helper
|
5
5
|
|
6
6
|
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
-
Message-id: <
|
8
|
-
Patchwork-id:
|
9
|
-
O-Subject: [virt-devel] [RHEL-7.
|
10
|
-
Bugzilla:
|
7
|
+
Message-id: <1461859652-20918-4-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 70294
|
9
|
+
O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 3/6] vga: add vbe_enabled() helper
|
10
|
+
Bugzilla: 1331413
|
11
11
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
12
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
13
|
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
@@ -1,13 +1,13 @@
|
|
1
|
-
From
|
1
|
+
From 445ec835479fd06142078a59f1a88f2b30708930 Mon Sep 17 00:00:00 2001
|
2
2
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
-
Date:
|
4
|
-
Subject: [PATCH
|
3
|
+
Date: Thu, 28 Apr 2016 16:07:30 +0200
|
4
|
+
Subject: [PATCH 25/27] vga: factor out vga register setup
|
5
5
|
|
6
6
|
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
-
Message-id: <
|
8
|
-
Patchwork-id:
|
9
|
-
O-Subject: [virt-devel] [RHEL-7.
|
10
|
-
Bugzilla:
|
7
|
+
Message-id: <1461859652-20918-5-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 70295
|
9
|
+
O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 4/6] vga: factor out vga register setup
|
10
|
+
Bugzilla: 1331413
|
11
11
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
12
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
13
|
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
@@ -1,13 +1,13 @@
|
|
1
|
-
From
|
1
|
+
From 27bca97bf22a55b1be7611e07c7592fcef5dd7cc Mon Sep 17 00:00:00 2001
|
2
2
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
-
Date:
|
4
|
-
Subject: [PATCH
|
3
|
+
Date: Thu, 28 Apr 2016 16:07:28 +0200
|
4
|
+
Subject: [PATCH 23/27] vga: fix banked access bounds checking (CVE-2016-xxxx).
|
5
5
|
|
6
6
|
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
-
Message-id: <
|
8
|
-
Patchwork-id:
|
9
|
-
O-Subject: [virt-devel] [RHEL-7.
|
10
|
-
Bugzilla:
|
7
|
+
Message-id: <1461859652-20918-3-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 70293
|
9
|
+
O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 2/6] vga: fix banked access bounds checking (CVE-2016-xxxx).
|
10
|
+
Bugzilla: 1331413
|
11
11
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
12
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
13
|
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
@@ -28,7 +28,6 @@ can easily change access modes after setting the bank register.
|
|
28
28
|
Drop the bogus check, add range checks to vga_mem_{readb,writeb}
|
29
29
|
instead.
|
30
30
|
|
31
|
-
Fixes: CVE-2016-3710
|
32
31
|
Reported-by: Qinghao Tang <luodalongde@gmail.com>
|
33
32
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
34
33
|
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
@@ -1,13 +1,13 @@
|
|
1
|
-
From
|
1
|
+
From 3c18025a495a2c105c2c33051ece0f3525d1e0c4 Mon Sep 17 00:00:00 2001
|
2
2
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
-
Date:
|
4
|
-
Subject: [PATCH
|
3
|
+
Date: Thu, 28 Apr 2016 16:07:32 +0200
|
4
|
+
Subject: [PATCH 27/27] vga: make sure vga register setup for vbe stays intact.
|
5
5
|
|
6
6
|
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
-
Message-id: <
|
8
|
-
Patchwork-id:
|
9
|
-
O-Subject: [virt-devel] [RHEL-7.
|
10
|
-
Bugzilla:
|
7
|
+
Message-id: <1461859652-20918-7-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 70297
|
9
|
+
O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 6/6] vga: make sure vga register setup for vbe stays intact.
|
10
|
+
Bugzilla: 1331413
|
11
11
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
12
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
13
|
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
@@ -1,13 +1,13 @@
|
|
1
|
-
From
|
1
|
+
From 6bf28a8a9e2e6d6505f2a906b7fc532427037c5f Mon Sep 17 00:00:00 2001
|
2
2
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
3
|
-
Date:
|
4
|
-
Subject: [PATCH
|
3
|
+
Date: Thu, 28 Apr 2016 16:07:31 +0200
|
4
|
+
Subject: [PATCH 26/27] vga: update vga register setup on vbe changes
|
5
5
|
|
6
6
|
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
7
|
-
Message-id: <
|
8
|
-
Patchwork-id:
|
9
|
-
O-Subject: [virt-devel] [RHEL-7.
|
10
|
-
Bugzilla:
|
7
|
+
Message-id: <1461859652-20918-6-git-send-email-kraxel@redhat.com>
|
8
|
+
Patchwork-id: 70296
|
9
|
+
O-Subject: [virt-devel] [RHEL-7.3 qemu-kvm PATCH 5/6] vga: update vga register setup on vbe changes
|
10
|
+
Bugzilla: 1331413
|
11
11
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
12
12
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
13
13
|
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
@@ -1,7 +1,7 @@
|
|
1
|
-
From
|
1
|
+
From acb67d9c43f3921861eebbabb447a85644e99320 Mon Sep 17 00:00:00 2001
|
2
2
|
From: Stefan Hajnoczi <stefanha@redhat.com>
|
3
3
|
Date: Mon, 25 Jul 2016 12:55:36 +0200
|
4
|
-
Subject: [PATCH] virtio: error out if guest exceeds virtqueue size
|
4
|
+
Subject: [PATCH 2/2] virtio: error out if guest exceeds virtqueue size
|
5
5
|
MIME-Version: 1.0
|
6
6
|
Content-Type: text/plain; charset=UTF-8
|
7
7
|
Content-Transfer-Encoding: 8bit
|
@@ -10,7 +10,7 @@ RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
|
10
10
|
Message-id: <1469451336-20117-2-git-send-email-stefanha@redhat.com>
|
11
11
|
Patchwork-id: 71428
|
12
12
|
O-Subject: [virt-devel] [RHEL-7.3 EMBARGOED qemu-kvm PATCH 1/1] virtio: error out if guest exceeds virtqueue size
|
13
|
-
Bugzilla:
|
13
|
+
Bugzilla: 1359729
|
14
14
|
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
15
15
|
RH-Acked-by: Marc-André Lureau <mlureau@redhat.com>
|
16
16
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
@@ -0,0 +1,73 @@
|
|
1
|
+
From 4d0430b1f847d672a39c76e6567bb5e88bc33c78 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Stefan Hajnoczi <stefanha@redhat.com>
|
3
|
+
Date: Fri, 16 Sep 2016 08:38:18 +0200
|
4
|
+
Subject: [PATCH] virtio: recalculate vq->inuse after migration
|
5
|
+
|
6
|
+
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
7
|
+
Message-id: <1474015098-11019-2-git-send-email-stefanha@redhat.com>
|
8
|
+
Patchwork-id: 72372
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] virtio: recalculate vq->inuse after migration
|
10
|
+
Bugzilla: 1376542
|
11
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
12
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
13
|
+
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
14
|
+
|
15
|
+
The vq->inuse field is not migrated. Many devices don't hold
|
16
|
+
VirtQueueElements across migration so it doesn't matter that vq->inuse
|
17
|
+
starts at 0 on the destination QEMU.
|
18
|
+
|
19
|
+
At least virtio-serial, virtio-blk, and virtio-balloon migrate while
|
20
|
+
holding VirtQueueElements. For these devices we need to recalculate
|
21
|
+
vq->inuse upon load so the value is correct.
|
22
|
+
|
23
|
+
Cc: qemu-stable@nongnu.org
|
24
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
25
|
+
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
26
|
+
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
|
27
|
+
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
28
|
+
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
29
|
+
(cherry picked from commit bccdef6b1a204db0f41ffb6e24ce373e4d7890d4)
|
30
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
31
|
+
|
32
|
+
Conflicts:
|
33
|
+
|
34
|
+
hw/virtio/virtio.c
|
35
|
+
|
36
|
+
Downstream does not have the vq->used_idx field which was added
|
37
|
+
upstream as a performance optimization reducing guest memory accesses.
|
38
|
+
Replace vq->used_idx with vring_used_idx(&vdev->vq[i]).
|
39
|
+
|
40
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
41
|
+
---
|
42
|
+
hw/virtio/virtio.c | 15 +++++++++++++++
|
43
|
+
1 file changed, 15 insertions(+)
|
44
|
+
|
45
|
+
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
|
46
|
+
index e67337b..0df4ed3 100644
|
47
|
+
--- a/hw/virtio/virtio.c
|
48
|
+
+++ b/hw/virtio/virtio.c
|
49
|
+
@@ -932,6 +932,21 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
50
|
+
vdev->vq[i].last_avail_idx, nheads);
|
51
|
+
return -1;
|
52
|
+
}
|
53
|
+
+
|
54
|
+
+ /*
|
55
|
+
+ * Some devices migrate VirtQueueElements that have been popped
|
56
|
+
+ * from the avail ring but not yet returned to the used ring.
|
57
|
+
+ */
|
58
|
+
+ vdev->vq[i].inuse = vdev->vq[i].last_avail_idx -
|
59
|
+
+ vring_used_idx(&vdev->vq[i]);
|
60
|
+
+ if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
|
61
|
+
+ error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
|
62
|
+
+ "used_idx 0x%x",
|
63
|
+
+ i, vdev->vq[i].vring.num,
|
64
|
+
+ vdev->vq[i].last_avail_idx,
|
65
|
+
+ vring_used_idx(&vdev->vq[i]));
|
66
|
+
+ return -1;
|
67
|
+
+ }
|
68
|
+
} else if (vdev->vq[i].last_avail_idx) {
|
69
|
+
error_report("VQ %d address 0x0 "
|
70
|
+
"inconsistent with Host index 0x%x",
|
71
|
+
--
|
72
|
+
1.8.3.1
|
73
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
From 3fdd5ce3ece26d5fd0d7702e08167bf5e513f620 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 18 Apr 2016 02:50:12 +0200
|
4
|
+
Subject: [PATCH 01/10] virtio-scsi: Prevent assertion on missed events
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1460947812-5704-1-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 70202
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH] virtio-scsi: Prevent assertion on missed events
|
10
|
+
Bugzilla: 1312289
|
11
|
+
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
12
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
13
|
+
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
14
|
+
|
15
|
+
From: Eric Farman <farman@linux.vnet.ibm.com>
|
16
|
+
|
17
|
+
In some cases, an unplug can cause events to be dropped, which
|
18
|
+
leads to an assertion failure when preparing to notify the guest
|
19
|
+
kernel.
|
20
|
+
|
21
|
+
Signed-off-by: Eric Farman <farman@linux.vnet.ibm.com>
|
22
|
+
Cc: qemu-stable@nongnu.org
|
23
|
+
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
24
|
+
(cherry picked from commit 49fb65c7f985baa56d2964e0a85c1f098e3e2a9d)
|
25
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
26
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
27
|
+
---
|
28
|
+
hw/scsi/virtio-scsi.c | 2 +-
|
29
|
+
1 file changed, 1 insertion(+), 1 deletion(-)
|
30
|
+
|
31
|
+
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
|
32
|
+
index 8232fc9..808eb54 100644
|
33
|
+
--- a/hw/scsi/virtio-scsi.c
|
34
|
+
+++ b/hw/scsi/virtio-scsi.c
|
35
|
+
@@ -530,7 +530,7 @@ static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
|
36
|
+
evt->event = event;
|
37
|
+
evt->reason = reason;
|
38
|
+
if (!dev) {
|
39
|
+
- assert(event == VIRTIO_SCSI_T_NO_EVENT);
|
40
|
+
+ assert(event == VIRTIO_SCSI_T_EVENTS_MISSED);
|
41
|
+
} else {
|
42
|
+
evt->lun[0] = 1;
|
43
|
+
evt->lun[1] = dev->id;
|
44
|
+
--
|
45
|
+
1.8.3.1
|
46
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
From 612017cc4834cd5eabc12afc7dd6cebf890b42e5 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Xiao Wang <jasowang@redhat.com>
|
3
|
+
Date: Fri, 19 Aug 2016 09:24:25 +0200
|
4
|
+
Subject: [PATCH] virtio: validate the existence of handle_output before
|
5
|
+
calling it
|
6
|
+
|
7
|
+
RH-Author: Xiao Wang <jasowang@redhat.com>
|
8
|
+
Message-id: <1471598665-23846-1-git-send-email-jasowang@redhat.com>
|
9
|
+
Patchwork-id: 72021
|
10
|
+
O-Subject: [RHEL7.3 qemu-kvm PATCH] virtio: validate the existence of handle_output before calling it
|
11
|
+
Bugzilla: 1367040
|
12
|
+
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
13
|
+
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
14
|
+
RH-Acked-by: Pankaj Gupta <pagupta@redhat.com>
|
15
|
+
|
16
|
+
Bugzilla: 1367040
|
17
|
+
Brew Build: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=11620539
|
18
|
+
Test status: Tested by myself.
|
19
|
+
|
20
|
+
We don't validate the existence of handle_output which may let a buggy
|
21
|
+
guest to trigger a SIGSEV easily. E.g:
|
22
|
+
|
23
|
+
1) write 10 to queue_sel to a virtio net device with only 1 queue
|
24
|
+
2) setup an arbitrary pfn
|
25
|
+
3) then notify queue 10
|
26
|
+
|
27
|
+
Fixing this by validating the existence of handle_output before.
|
28
|
+
|
29
|
+
Cc: qemu-stable@nongnu.org
|
30
|
+
Cc: Michael S. Tsirkin <mst@redhat.com>
|
31
|
+
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
32
|
+
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
33
|
+
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
34
|
+
Reviewed-by: Don Koch <dkoch@verizon.com>
|
35
|
+
Reviewed-by: Fam Zheng <famz@redhat.com>
|
36
|
+
(cherry picked from commit 9e0f5b8108e248b78444c9a2ec41a8309825736c)
|
37
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
38
|
+
---
|
39
|
+
hw/virtio/virtio.c | 3 ++-
|
40
|
+
1 file changed, 2 insertions(+), 1 deletion(-)
|
41
|
+
|
42
|
+
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
|
43
|
+
index a861870..e67337b 100644
|
44
|
+
--- a/hw/virtio/virtio.c
|
45
|
+
+++ b/hw/virtio/virtio.c
|
46
|
+
@@ -692,8 +692,9 @@ int virtio_queue_get_id(VirtQueue *vq)
|
47
|
+
|
48
|
+
void virtio_queue_notify_vq(VirtQueue *vq)
|
49
|
+
{
|
50
|
+
- if (vq->vring.desc) {
|
51
|
+
+ if (vq->vring.desc && vq->handle_output) {
|
52
|
+
VirtIODevice *vdev = vq->vdev;
|
53
|
+
+
|
54
|
+
trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
|
55
|
+
vq->handle_output(vdev, vq);
|
56
|
+
}
|
57
|
+
--
|
58
|
+
1.8.3.1
|
59
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
From 86c71987b64382e1177f86e6bc00bfc19e20082d Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:18 +0100
|
4
|
+
Subject: [PATCH 05/18] vmdk: Check descriptor file length when reading it
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-6-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69171
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 05/18] vmdk: Check descriptor file length when reading it
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
16
|
+
|
17
|
+
Since a too small file cannot be a valid VMDK image, and also since the
|
18
|
+
buffer's first 4 bytes will be unconditionally examined by
|
19
|
+
vmdk_open_sparse, let's error out the small file case to be clear.
|
20
|
+
|
21
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
22
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
23
|
+
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
24
|
+
Reviewed-by: Don Koch <dkoch@verizon.com>
|
25
|
+
Message-id: 1417649314-13704-5-git-send-email-famz@redhat.com
|
26
|
+
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
27
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
28
|
+
(cherry picked from commit 03c3359dfc490eaf922f88955d6a8cc51a37ce92)
|
29
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
30
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
31
|
+
---
|
32
|
+
block/vmdk.c | 8 ++++++++
|
33
|
+
1 file changed, 8 insertions(+)
|
34
|
+
|
35
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
36
|
+
index 3dfbd41..db3cdc0 100644
|
37
|
+
--- a/block/vmdk.c
|
38
|
+
+++ b/block/vmdk.c
|
39
|
+
@@ -559,6 +559,14 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
|
40
|
+
return NULL;
|
41
|
+
}
|
42
|
+
|
43
|
+
+ if (size < 4) {
|
44
|
+
+ /* Both descriptor file and sparse image must be much larger than 4
|
45
|
+
+ * bytes, also callers of vmdk_read_desc want to compare the first 4
|
46
|
+
+ * bytes with VMDK4_MAGIC, let's error out if less is read. */
|
47
|
+
+ error_setg(errp, "File is too small, not a valid image");
|
48
|
+
+ return NULL;
|
49
|
+
+ }
|
50
|
+
+
|
51
|
+
size = MIN(size, (1 << 20) - 1); /* avoid unbounded allocation */
|
52
|
+
buf = g_malloc(size + 1);
|
53
|
+
|
54
|
+
--
|
55
|
+
1.8.3.1
|
56
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
From 2aa26696846adf25a41fa082f4d42c98b2b05fe3 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:17 +0100
|
4
|
+
Subject: [PATCH 04/18] vmdk: Clean up descriptor file reading
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-5-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69170
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 04/18] vmdk: Clean up descriptor file reading
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
16
|
+
|
17
|
+
Zeroing a buffer that will be filled right after is not necessary, and
|
18
|
+
allocating a power of two + 1 is naughty.
|
19
|
+
|
20
|
+
Suggested-by: Markus Armbruster <armbru@redhat.com>
|
21
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
22
|
+
Reviewed-by: Don Koch <dkoch@verizon.com>
|
23
|
+
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
24
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
25
|
+
Message-id: 1417649314-13704-4-git-send-email-famz@redhat.com
|
26
|
+
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
27
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
28
|
+
(cherry picked from commit 73b7bcad439e0edaced05049897090cc10d84b5b)
|
29
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
30
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
31
|
+
---
|
32
|
+
block/vmdk.c | 5 +++--
|
33
|
+
1 file changed, 3 insertions(+), 2 deletions(-)
|
34
|
+
|
35
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
36
|
+
index 3f34abf..3dfbd41 100644
|
37
|
+
--- a/block/vmdk.c
|
38
|
+
+++ b/block/vmdk.c
|
39
|
+
@@ -559,8 +559,8 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
|
40
|
+
return NULL;
|
41
|
+
}
|
42
|
+
|
43
|
+
- size = MIN(size, 1 << 20); /* avoid unbounded allocation */
|
44
|
+
- buf = g_malloc0(size + 1);
|
45
|
+
+ size = MIN(size, (1 << 20) - 1); /* avoid unbounded allocation */
|
46
|
+
+ buf = g_malloc(size + 1);
|
47
|
+
|
48
|
+
ret = bdrv_pread(file, desc_offset, buf, size);
|
49
|
+
if (ret < 0) {
|
50
|
+
@@ -568,6 +568,7 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
|
51
|
+
g_free(buf);
|
52
|
+
return NULL;
|
53
|
+
}
|
54
|
+
+ buf[ret] = 0;
|
55
|
+
|
56
|
+
return buf;
|
57
|
+
}
|
58
|
+
--
|
59
|
+
1.8.3.1
|
60
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
From 7777177c3c7291ff5c4b24040b075a1bd1c1db77 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:29 +0100
|
4
|
+
Subject: [PATCH 16/18] vmdk: Create streamOptimized as version 3
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-17-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69182
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 16/18] vmdk: Create streamOptimized as version 3
|
10
|
+
Bugzilla: 1299116
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299116
|
16
|
+
|
17
|
+
VMware products accept only version 3 for streamOptimized, let's bump
|
18
|
+
the version.
|
19
|
+
|
20
|
+
Reported-by: Radoslav Gerganov <rgerganov@vmware.com>
|
21
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
22
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
23
|
+
(cherry picked from commit d62d9dc4b814950dcc8bd261a3e2e9300d9065e6)
|
24
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
25
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
26
|
+
---
|
27
|
+
block/vmdk.c | 8 +++++++-
|
28
|
+
1 file changed, 7 insertions(+), 1 deletion(-)
|
29
|
+
|
30
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
31
|
+
index 7009660..7b3e397 100644
|
32
|
+
--- a/block/vmdk.c
|
33
|
+
+++ b/block/vmdk.c
|
34
|
+
@@ -1658,7 +1658,13 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
|
35
|
+
}
|
36
|
+
magic = cpu_to_be32(VMDK4_MAGIC);
|
37
|
+
memset(&header, 0, sizeof(header));
|
38
|
+
- header.version = zeroed_grain ? 2 : 1;
|
39
|
+
+ if (compress) {
|
40
|
+
+ header.version = 3;
|
41
|
+
+ } else if (zeroed_grain) {
|
42
|
+
+ header.version = 2;
|
43
|
+
+ } else {
|
44
|
+
+ header.version = 1;
|
45
|
+
+ }
|
46
|
+
header.flags = VMDK4_FLAG_RGD | VMDK4_FLAG_NL_DETECT
|
47
|
+
| (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0)
|
48
|
+
| (zeroed_grain ? VMDK4_FLAG_ZERO_GRAIN : 0);
|
49
|
+
--
|
50
|
+
1.8.3.1
|
51
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
From 0cdb7038a7027cbb63c820e60bb34abd191ac85f Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:31 +0100
|
4
|
+
Subject: [PATCH 18/18] vmdk: Fix calculation of block status's offset
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-19-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69184
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 18/18] vmdk: Fix calculation of block status's offset
|
10
|
+
Bugzilla: 1299116
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
"offset" is the offset of cluster and sector_num doesn't necessarily
|
16
|
+
refer to the start of it, it should add index_in_cluster.
|
17
|
+
|
18
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
19
|
+
Message-id: 1453780743-16806-12-git-send-email-famz@redhat.com
|
20
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
21
|
+
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
22
|
+
(cherry picked from commit d0a18f10251f515c86dcaec5bdf979a4e07fafc5)
|
23
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
24
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
25
|
+
---
|
26
|
+
block/vmdk.c | 6 ++++--
|
27
|
+
1 file changed, 4 insertions(+), 2 deletions(-)
|
28
|
+
|
29
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
30
|
+
index b0c312b..b4f0d44 100644
|
31
|
+
--- a/block/vmdk.c
|
32
|
+
+++ b/block/vmdk.c
|
33
|
+
@@ -1275,6 +1275,7 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
|
34
|
+
0, 0);
|
35
|
+
qemu_co_mutex_unlock(&s->lock);
|
36
|
+
|
37
|
+
+ index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
|
38
|
+
switch (ret) {
|
39
|
+
case VMDK_ERROR:
|
40
|
+
ret = -EIO;
|
41
|
+
@@ -1288,13 +1289,14 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
|
42
|
+
case VMDK_OK:
|
43
|
+
ret = BDRV_BLOCK_DATA;
|
44
|
+
if (extent->file == bs->file && !extent->compressed) {
|
45
|
+
- ret |= BDRV_BLOCK_OFFSET_VALID | offset;
|
46
|
+
+ ret |= BDRV_BLOCK_OFFSET_VALID;
|
47
|
+
+ ret |= (offset + (index_in_cluster << BDRV_SECTOR_BITS))
|
48
|
+
+ & BDRV_BLOCK_OFFSET_MASK;
|
49
|
+
}
|
50
|
+
|
51
|
+
break;
|
52
|
+
}
|
53
|
+
|
54
|
+
- index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
|
55
|
+
n = extent->cluster_sectors - index_in_cluster;
|
56
|
+
if (n > nb_sectors) {
|
57
|
+
n = nb_sectors;
|
58
|
+
--
|
59
|
+
1.8.3.1
|
60
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
From ad76b22d2d96499bbbd1172f347b4ec8a2327c7d Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:16 +0100
|
4
|
+
Subject: [PATCH 03/18] vmdk: Fix comment to match code of extent lines
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-4-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69169
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 03/18] vmdk: Fix comment to match code of extent lines
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
16
|
+
|
17
|
+
commit 04d542c8b (vmdk: support vmfs files) added support of VMFS extent
|
18
|
+
type but the comment above the changed code is left out. Update the
|
19
|
+
comment so they are consistent.
|
20
|
+
|
21
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
22
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
23
|
+
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
24
|
+
Reviewed-by: Don Koch <dkoch@verizon.com>
|
25
|
+
Message-id: 1417649314-13704-3-git-send-email-famz@redhat.com
|
26
|
+
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
27
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
28
|
+
(cherry picked from commit 8a3e0bc370de9274170b82f48b0393204c3fb43b)
|
29
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
30
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
31
|
+
---
|
32
|
+
block/vmdk.c | 6 ++++--
|
33
|
+
1 file changed, 4 insertions(+), 2 deletions(-)
|
34
|
+
|
35
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
36
|
+
index a9f5bab..3f34abf 100644
|
37
|
+
--- a/block/vmdk.c
|
38
|
+
+++ b/block/vmdk.c
|
39
|
+
@@ -788,10 +788,12 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
40
|
+
VmdkExtent *extent;
|
41
|
+
|
42
|
+
while (*p) {
|
43
|
+
- /* parse extent line:
|
44
|
+
+ /* parse extent line in one of below formats:
|
45
|
+
+ *
|
46
|
+
* RW [size in sectors] FLAT "file-name.vmdk" OFFSET
|
47
|
+
- * or
|
48
|
+
* RW [size in sectors] SPARSE "file-name.vmdk"
|
49
|
+
+ * RW [size in sectors] VMFS "file-name.vmdk"
|
50
|
+
+ * RW [size in sectors] VMFSSPARSE "file-name.vmdk"
|
51
|
+
*/
|
52
|
+
flat_offset = -1;
|
53
|
+
ret = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
|
54
|
+
--
|
55
|
+
1.8.3.1
|
56
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
From b72998772910dbd04c86a2332b1c69ac1afc7a9e Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:30 +0100
|
4
|
+
Subject: [PATCH 17/18] vmdk: Fix converting to streamOptimized
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-18-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69183
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 17/18] vmdk: Fix converting to streamOptimized
|
10
|
+
Bugzilla: 1299116
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299116
|
16
|
+
|
17
|
+
Commit d62d9dc4b8 lifted streamOptimized images's version to 3, but we
|
18
|
+
now refuse to open version 3 images read-write. We need to make
|
19
|
+
streamOptimized an exception to allow converting to it. This fixes the
|
20
|
+
accidentally broken iotests case 059 for the same reason.
|
21
|
+
|
22
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
23
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
24
|
+
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
25
|
+
(cherry picked from commit 3db1d98a20262228373bb973ca62b1ab64b29af4)
|
26
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
27
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
28
|
+
---
|
29
|
+
block/vmdk.c | 6 +++++-
|
30
|
+
1 file changed, 5 insertions(+), 1 deletion(-)
|
31
|
+
|
32
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
33
|
+
index 7b3e397..b0c312b 100644
|
34
|
+
--- a/block/vmdk.c
|
35
|
+
+++ b/block/vmdk.c
|
36
|
+
@@ -592,6 +592,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
37
|
+
VmdkExtent *extent;
|
38
|
+
BDRVVmdkState *s = bs->opaque;
|
39
|
+
int64_t l1_backup_offset = 0;
|
40
|
+
+ bool compressed;
|
41
|
+
|
42
|
+
ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header));
|
43
|
+
if (ret < 0) {
|
44
|
+
@@ -666,6 +667,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
45
|
+
header = footer.header;
|
46
|
+
}
|
47
|
+
|
48
|
+
+ compressed =
|
49
|
+
+ le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
|
50
|
+
if (le32_to_cpu(header.version) > 3) {
|
51
|
+
char buf[64];
|
52
|
+
snprintf(buf, sizeof(buf), "VMDK version %" PRId32,
|
53
|
+
@@ -673,7 +676,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
54
|
+
error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
|
55
|
+
bs->device_name, "vmdk", buf);
|
56
|
+
return -ENOTSUP;
|
57
|
+
- } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
|
58
|
+
+ } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR) &&
|
59
|
+
+ !compressed) {
|
60
|
+
/* VMware KB 2064959 explains that version 3 added support for
|
61
|
+
* persistent changed block tracking (CBT), and backup software can
|
62
|
+
* read it as version=1 if it doesn't care about the changed area
|
63
|
+
--
|
64
|
+
1.8.3.1
|
65
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
From 32791762f04b3342e9b10d1f553326cd01ea451f Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:26 +0100
|
4
|
+
Subject: [PATCH 13/18] vmdk: Fix index_in_cluster calculation in
|
5
|
+
vmdk_co_get_block_status
|
6
|
+
|
7
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
8
|
+
Message-id: <1455528511-9357-14-git-send-email-famz@redhat.com>
|
9
|
+
Patchwork-id: 69179
|
10
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 13/18] vmdk: Fix index_in_cluster calculation in vmdk_co_get_block_status
|
11
|
+
Bugzilla: 1299250
|
12
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
13
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
14
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
15
|
+
|
16
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
17
|
+
|
18
|
+
It has the similar issue with b1649fae49a8. Since the calculation
|
19
|
+
is repeated for a few times already, introduce a function so it can be
|
20
|
+
reused.
|
21
|
+
|
22
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
23
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
24
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
25
|
+
(cherry picked from commit 61f0ed1d54601b91b8195c1a30d7046f83283b40)
|
26
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
27
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
28
|
+
---
|
29
|
+
block/vmdk.c | 13 ++++++++++++-
|
30
|
+
1 file changed, 12 insertions(+), 1 deletion(-)
|
31
|
+
|
32
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
33
|
+
index dd8b638..10c08f3 100644
|
34
|
+
--- a/block/vmdk.c
|
35
|
+
+++ b/block/vmdk.c
|
36
|
+
@@ -1242,6 +1242,17 @@ static VmdkExtent *find_extent(BDRVVmdkState *s,
|
37
|
+
return NULL;
|
38
|
+
}
|
39
|
+
|
40
|
+
+static inline uint64_t vmdk_find_index_in_cluster(VmdkExtent *extent,
|
41
|
+
+ int64_t sector_num)
|
42
|
+
+{
|
43
|
+
+ uint64_t index_in_cluster, extent_begin_sector, extent_relative_sector_num;
|
44
|
+
+
|
45
|
+
+ extent_begin_sector = extent->end_sector - extent->sectors;
|
46
|
+
+ extent_relative_sector_num = sector_num - extent_begin_sector;
|
47
|
+
+ index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
|
48
|
+
+ return index_in_cluster;
|
49
|
+
+}
|
50
|
+
+
|
51
|
+
static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
|
52
|
+
int64_t sector_num, int nb_sectors, int *pnum)
|
53
|
+
{
|
54
|
+
@@ -1279,7 +1290,7 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
|
55
|
+
break;
|
56
|
+
}
|
57
|
+
|
58
|
+
- index_in_cluster = sector_num % extent->cluster_sectors;
|
59
|
+
+ index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
|
60
|
+
n = extent->cluster_sectors - index_in_cluster;
|
61
|
+
if (n > nb_sectors) {
|
62
|
+
n = nb_sectors;
|
63
|
+
--
|
64
|
+
1.8.3.1
|
65
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
From 47886bf3b19f06d0a5255d9656d1c02800baddd0 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:25 +0100
|
4
|
+
Subject: [PATCH 12/18] vmdk: Fix next_cluster_sector for compressed write
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-13-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69178
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 12/18] vmdk: Fix next_cluster_sector for compressed write
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
16
|
+
|
17
|
+
This fixes the bug introduced by commit c6ac36e (vmdk: Optimize cluster
|
18
|
+
allocation).
|
19
|
+
|
20
|
+
Sometimes, write_len could be larger than cluster size, because it
|
21
|
+
contains both data and marker. We must advance next_cluster_sector in
|
22
|
+
this case, otherwise the image gets corrupted.
|
23
|
+
|
24
|
+
Cc: qemu-stable@nongnu.org
|
25
|
+
Reported-by: Antoni Villalonga <qemu-list@friki.cat>
|
26
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
27
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
28
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
29
|
+
(cherry picked from commit 5e82a31eb967db135fc4e688b134fb0972d62de3)
|
30
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
31
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
32
|
+
---
|
33
|
+
block/vmdk.c | 14 ++++++++++----
|
34
|
+
1 file changed, 10 insertions(+), 4 deletions(-)
|
35
|
+
|
36
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
37
|
+
index 3810d75..dd8b638 100644
|
38
|
+
--- a/block/vmdk.c
|
39
|
+
+++ b/block/vmdk.c
|
40
|
+
@@ -1297,6 +1297,8 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
|
41
|
+
uLongf buf_len;
|
42
|
+
const uint8_t *write_buf = buf;
|
43
|
+
int write_len = nb_sectors * 512;
|
44
|
+
+ int64_t write_offset;
|
45
|
+
+ int64_t write_end_sector;
|
46
|
+
|
47
|
+
if (extent->compressed) {
|
48
|
+
if (!extent->has_marker) {
|
49
|
+
@@ -1315,10 +1317,14 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
|
50
|
+
write_buf = (uint8_t *)data;
|
51
|
+
write_len = buf_len + sizeof(VmdkGrainMarker);
|
52
|
+
}
|
53
|
+
- ret = bdrv_pwrite(extent->file,
|
54
|
+
- cluster_offset + offset_in_cluster,
|
55
|
+
- write_buf,
|
56
|
+
- write_len);
|
57
|
+
+ write_offset = cluster_offset + offset_in_cluster,
|
58
|
+
+ ret = bdrv_pwrite(extent->file, write_offset, write_buf, write_len);
|
59
|
+
+
|
60
|
+
+ write_end_sector = DIV_ROUND_UP(write_offset + write_len, BDRV_SECTOR_SIZE);
|
61
|
+
+
|
62
|
+
+ extent->next_cluster_sector = MAX(extent->next_cluster_sector,
|
63
|
+
+ write_end_sector);
|
64
|
+
+
|
65
|
+
if (ret != write_len) {
|
66
|
+
ret = ret < 0 ? ret : -EIO;
|
67
|
+
goto out;
|
68
|
+
--
|
69
|
+
1.8.3.1
|
70
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
From bc048d2d5f362757fa0bf51add81d92ec19ad161 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:28 +0100
|
4
|
+
Subject: [PATCH 15/18] vmdk: Fix next_cluster_sector for compressed write
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-16-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69181
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 15/18] vmdk: Fix next_cluster_sector for compressed write
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
From: Radoslav Gerganov <rgerganov@vmware.com>
|
16
|
+
|
17
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
18
|
+
|
19
|
+
When the VMDK is streamOptimized (or compressed), the
|
20
|
+
next_cluster_sector must not be incremented by a fixed number of
|
21
|
+
sectors. Instead of this, it must be rounded up to the next consecutive
|
22
|
+
sector. Fixing this results in much smaller compressed images.
|
23
|
+
|
24
|
+
Signed-off-by: Radoslav Gerganov <rgerganov@vmware.com>
|
25
|
+
Reviewed-by: Fam Zheng <famz@redhat.com>
|
26
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
27
|
+
(cherry picked from commit 3efffc3292d94271a15b1606b4a56adf6c6f04ed)
|
28
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
29
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
30
|
+
---
|
31
|
+
block/vmdk.c | 8 ++++++--
|
32
|
+
1 file changed, 6 insertions(+), 2 deletions(-)
|
33
|
+
|
34
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
35
|
+
index cb5255c..7009660 100644
|
36
|
+
--- a/block/vmdk.c
|
37
|
+
+++ b/block/vmdk.c
|
38
|
+
@@ -1333,8 +1333,12 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
|
39
|
+
|
40
|
+
write_end_sector = DIV_ROUND_UP(write_offset + write_len, BDRV_SECTOR_SIZE);
|
41
|
+
|
42
|
+
- extent->next_cluster_sector = MAX(extent->next_cluster_sector,
|
43
|
+
- write_end_sector);
|
44
|
+
+ if (extent->compressed) {
|
45
|
+
+ extent->next_cluster_sector = write_end_sector;
|
46
|
+
+ } else {
|
47
|
+
+ extent->next_cluster_sector = MAX(extent->next_cluster_sector,
|
48
|
+
+ write_end_sector);
|
49
|
+
+ }
|
50
|
+
|
51
|
+
if (ret != write_len) {
|
52
|
+
ret = ret < 0 ? ret : -EIO;
|
53
|
+
--
|
54
|
+
1.8.3.1
|
55
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
From 824614c344ceeb60dd27b38cfdb190471b6a2ef9 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:14 +0100
|
4
|
+
Subject: [PATCH 01/18] vmdk: Leave bdi intact if -ENOTSUP in vmdk_get_info
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-2-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69167
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 01/18] vmdk: Leave bdi intact if -ENOTSUP in vmdk_get_info
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
16
|
+
|
17
|
+
When extent types don't match, we return -ENOTSUP. In this case, be
|
18
|
+
polite to the caller and don't modify bdi.
|
19
|
+
|
20
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
21
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
22
|
+
Message-id: 1415938161-16217-1-git-send-email-famz@redhat.com
|
23
|
+
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
24
|
+
(cherry picked from commit 5f58330790b72c4705b373ee0646fb3adf800b4e)
|
25
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
26
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
27
|
+
---
|
28
|
+
block/vmdk.c | 20 +++++++++++++-------
|
29
|
+
1 file changed, 13 insertions(+), 7 deletions(-)
|
30
|
+
|
31
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
32
|
+
index 6b015ab..fa53d2f 100644
|
33
|
+
--- a/block/vmdk.c
|
34
|
+
+++ b/block/vmdk.c
|
35
|
+
@@ -2137,23 +2137,29 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
|
36
|
+
return spec_info;
|
37
|
+
}
|
38
|
+
|
39
|
+
+static bool vmdk_extents_type_eq(const VmdkExtent *a, const VmdkExtent *b)
|
40
|
+
+{
|
41
|
+
+ return a->flat == b->flat &&
|
42
|
+
+ a->compressed == b->compressed &&
|
43
|
+
+ (a->flat || a->cluster_sectors == b->cluster_sectors);
|
44
|
+
+}
|
45
|
+
+
|
46
|
+
static int vmdk_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
47
|
+
{
|
48
|
+
int i;
|
49
|
+
BDRVVmdkState *s = bs->opaque;
|
50
|
+
assert(s->num_extents);
|
51
|
+
- bdi->needs_compressed_writes = s->extents[0].compressed;
|
52
|
+
- if (!s->extents[0].flat) {
|
53
|
+
- bdi->cluster_size = s->extents[0].cluster_sectors << BDRV_SECTOR_BITS;
|
54
|
+
- }
|
55
|
+
+
|
56
|
+
/* See if we have multiple extents but they have different cases */
|
57
|
+
for (i = 1; i < s->num_extents; i++) {
|
58
|
+
- if (bdi->needs_compressed_writes != s->extents[i].compressed ||
|
59
|
+
- (bdi->cluster_size && bdi->cluster_size !=
|
60
|
+
- s->extents[i].cluster_sectors << BDRV_SECTOR_BITS)) {
|
61
|
+
+ if (!vmdk_extents_type_eq(&s->extents[0], &s->extents[i])) {
|
62
|
+
return -ENOTSUP;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
+ bdi->needs_compressed_writes = s->extents[0].compressed;
|
66
|
+
+ if (!s->extents[0].flat) {
|
67
|
+
+ bdi->cluster_size = s->extents[0].cluster_sectors << BDRV_SECTOR_BITS;
|
68
|
+
+ }
|
69
|
+
return 0;
|
70
|
+
}
|
71
|
+
|
72
|
+
--
|
73
|
+
1.8.3.1
|
74
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
From aea042fc3e0a8454edb4e9884635af63128b15d3 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:19 +0100
|
4
|
+
Subject: [PATCH 06/18] vmdk: Remove unnecessary initialization
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-7-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69172
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 06/18] vmdk: Remove unnecessary initialization
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
16
|
+
|
17
|
+
It will be assigned to the return value of vmdk_read_desc.
|
18
|
+
|
19
|
+
Suggested-by: Markus Armbruster <armbru@redhat.com>
|
20
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
21
|
+
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
22
|
+
Reviewed-by: Don Koch <dkoch@verizon.com>
|
23
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
24
|
+
Message-id: 1417649314-13704-6-git-send-email-famz@redhat.com
|
25
|
+
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
26
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
27
|
+
(cherry picked from commit 9aeecbbc62ce52a94b2621a0d53567b5d4ed915d)
|
28
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
29
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
30
|
+
---
|
31
|
+
block/vmdk.c | 2 +-
|
32
|
+
1 file changed, 1 insertion(+), 1 deletion(-)
|
33
|
+
|
34
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
35
|
+
index db3cdc0..69d8a6e 100644
|
36
|
+
--- a/block/vmdk.c
|
37
|
+
+++ b/block/vmdk.c
|
38
|
+
@@ -916,7 +916,7 @@ exit:
|
39
|
+
static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
|
40
|
+
Error **errp)
|
41
|
+
{
|
42
|
+
- char *buf = NULL;
|
43
|
+
+ char *buf;
|
44
|
+
int ret;
|
45
|
+
BDRVVmdkState *s = bs->opaque;
|
46
|
+
uint32_t magic;
|
47
|
+
--
|
48
|
+
1.8.3.1
|
49
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
From 005308f5b469f749980310be141315e8bd46556f Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:20 +0100
|
4
|
+
Subject: [PATCH 07/18] vmdk: Set errp on failures in vmdk_open_vmdk4
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-8-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69173
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 07/18] vmdk: Set errp on failures in vmdk_open_vmdk4
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
16
|
+
|
17
|
+
Reported-by: Markus Armbruster <armbru@redhat.com>
|
18
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
19
|
+
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
20
|
+
Reviewed-by: Don Koch <dkoch@verizon.com>
|
21
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
22
|
+
Message-id: 1417649314-13704-7-git-send-email-famz@redhat.com
|
23
|
+
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
24
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
25
|
+
(cherry picked from commit d899d2e248b900c53dd9081bde9f110e05747433)
|
26
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
27
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
28
|
+
---
|
29
|
+
block/vmdk.c | 3 +++
|
30
|
+
1 file changed, 3 insertions(+)
|
31
|
+
|
32
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
33
|
+
index 69d8a6e..1247ea4 100644
|
34
|
+
--- a/block/vmdk.c
|
35
|
+
+++ b/block/vmdk.c
|
36
|
+
@@ -647,6 +647,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
37
|
+
bs->file->total_sectors * 512 - 1536,
|
38
|
+
&footer, sizeof(footer));
|
39
|
+
if (ret < 0) {
|
40
|
+
+ error_setg_errno(errp, -ret, "Failed to read footer");
|
41
|
+
return ret;
|
42
|
+
}
|
43
|
+
|
44
|
+
@@ -658,6 +659,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
45
|
+
le32_to_cpu(footer.eos_marker.size) != 0 ||
|
46
|
+
le32_to_cpu(footer.eos_marker.type) != MARKER_END_OF_STREAM)
|
47
|
+
{
|
48
|
+
+ error_setg(errp, "Invalid footer");
|
49
|
+
return -EINVAL;
|
50
|
+
}
|
51
|
+
|
52
|
+
@@ -688,6 +690,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
53
|
+
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
|
54
|
+
* le64_to_cpu(header.granularity);
|
55
|
+
if (l1_entry_sectors == 0) {
|
56
|
+
+ error_setg(errp, "L1 entry size is invalid");
|
57
|
+
return -EINVAL;
|
58
|
+
}
|
59
|
+
l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
|
60
|
+
--
|
61
|
+
1.8.3.1
|
62
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
From bf9dd867ef8d4164685cac6451e88b6c32b190b1 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:15 +0100
|
4
|
+
Subject: [PATCH 02/18] vmdk: Use g_random_int to generate CID
|
5
|
+
MIME-Version: 1.0
|
6
|
+
Content-Type: text/plain; charset=UTF-8
|
7
|
+
Content-Transfer-Encoding: 8bit
|
8
|
+
|
9
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
10
|
+
Message-id: <1455528511-9357-3-git-send-email-famz@redhat.com>
|
11
|
+
Patchwork-id: 69168
|
12
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 02/18] vmdk: Use g_random_int to generate CID
|
13
|
+
Bugzilla: 1299250
|
14
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
15
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
16
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
17
|
+
|
18
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
19
|
+
|
20
|
+
This replaces two "time(NULL)" invocations with "g_random_int()".
|
21
|
+
According to VMDK spec, CID "is a random 32‐bit value updated the first
|
22
|
+
time the content of the virtual disk is modified after the virtual disk
|
23
|
+
is opened". Using "seconds since epoch" is just a "lame way" to generate
|
24
|
+
it, and not completely safe because of the low precision.
|
25
|
+
|
26
|
+
Suggested-by: Markus Armbruster <armbru@redhat.com>
|
27
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
28
|
+
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
29
|
+
Reviewed-by: Don Koch <dkoch@verizon.com>
|
30
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
31
|
+
Message-id: 1417649314-13704-2-git-send-email-famz@redhat.com
|
32
|
+
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
33
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
34
|
+
(cherry picked from commit e5dc64b8ff09cc4c186273e4461c7479739db2ae)
|
35
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
36
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
37
|
+
---
|
38
|
+
block/vmdk.c | 5 +++--
|
39
|
+
1 file changed, 3 insertions(+), 2 deletions(-)
|
40
|
+
|
41
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
42
|
+
index fa53d2f..a9f5bab 100644
|
43
|
+
--- a/block/vmdk.c
|
44
|
+
+++ b/block/vmdk.c
|
45
|
+
|
46
|
+
#include "qemu/module.h"
|
47
|
+
#include "migration/migration.h"
|
48
|
+
#include <zlib.h>
|
49
|
+
+#include <glib.h>
|
50
|
+
|
51
|
+
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
|
52
|
+
#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
|
53
|
+
@@ -1540,7 +1541,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
|
54
|
+
/* update CID on the first write every time the virtual disk is
|
55
|
+
* opened */
|
56
|
+
if (!s->cid_updated) {
|
57
|
+
- ret = vmdk_write_cid(bs, time(NULL));
|
58
|
+
+ ret = vmdk_write_cid(bs, g_random_int());
|
59
|
+
if (ret < 0) {
|
60
|
+
return ret;
|
61
|
+
}
|
62
|
+
@@ -1927,7 +1928,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
|
63
|
+
}
|
64
|
+
/* generate descriptor file */
|
65
|
+
desc = g_strdup_printf(desc_template,
|
66
|
+
- (uint32_t)time(NULL),
|
67
|
+
+ g_random_int(),
|
68
|
+
parent_cid,
|
69
|
+
fmt,
|
70
|
+
parent_desc_line,
|
71
|
+
--
|
72
|
+
1.8.3.1
|
73
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
From f7f34dfdb448a0344210f6bfa77b67c637ffea56 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:27 +0100
|
4
|
+
Subject: [PATCH 14/18] vmdk: Use vmdk_find_index_in_cluster everywhere
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-15-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69180
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 14/18] vmdk: Use vmdk_find_index_in_cluster everywhere
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
16
|
+
|
17
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
18
|
+
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
19
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
20
|
+
(cherry picked from commit 90df601f06de14f062d2e8dc1bc57f0decf86fd1)
|
21
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
22
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
23
|
+
---
|
24
|
+
block/vmdk.c | 10 ++--------
|
25
|
+
1 file changed, 2 insertions(+), 8 deletions(-)
|
26
|
+
|
27
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
28
|
+
index 10c08f3..cb5255c 100644
|
29
|
+
--- a/block/vmdk.c
|
30
|
+
+++ b/block/vmdk.c
|
31
|
+
@@ -1418,7 +1418,6 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
|
32
|
+
BDRVVmdkState *s = bs->opaque;
|
33
|
+
int ret;
|
34
|
+
uint64_t n, index_in_cluster;
|
35
|
+
- uint64_t extent_begin_sector, extent_relative_sector_num;
|
36
|
+
VmdkExtent *extent = NULL;
|
37
|
+
uint64_t cluster_offset;
|
38
|
+
|
39
|
+
@@ -1430,9 +1429,7 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
|
40
|
+
ret = get_cluster_offset(bs, extent, NULL,
|
41
|
+
sector_num << 9, false, &cluster_offset,
|
42
|
+
0, 0);
|
43
|
+
- extent_begin_sector = extent->end_sector - extent->sectors;
|
44
|
+
- extent_relative_sector_num = sector_num - extent_begin_sector;
|
45
|
+
- index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
|
46
|
+
+ index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
|
47
|
+
n = extent->cluster_sectors - index_in_cluster;
|
48
|
+
if (n > nb_sectors) {
|
49
|
+
n = nb_sectors;
|
50
|
+
@@ -1494,7 +1491,6 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
|
51
|
+
VmdkExtent *extent = NULL;
|
52
|
+
int ret;
|
53
|
+
int64_t index_in_cluster, n;
|
54
|
+
- uint64_t extent_begin_sector, extent_relative_sector_num;
|
55
|
+
uint64_t cluster_offset;
|
56
|
+
VmdkMetaData m_data;
|
57
|
+
|
58
|
+
@@ -1510,9 +1506,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
|
59
|
+
if (!extent) {
|
60
|
+
return -EIO;
|
61
|
+
}
|
62
|
+
- extent_begin_sector = extent->end_sector - extent->sectors;
|
63
|
+
- extent_relative_sector_num = sector_num - extent_begin_sector;
|
64
|
+
- index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
|
65
|
+
+ index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
|
66
|
+
n = extent->cluster_sectors - index_in_cluster;
|
67
|
+
if (n > nb_sectors) {
|
68
|
+
n = nb_sectors;
|
69
|
+
--
|
70
|
+
1.8.3.1
|
71
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
From 649835536d4bb1366e01ff5600d3005042dd50d5 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Fam Zheng <famz@redhat.com>
|
3
|
+
Date: Mon, 15 Feb 2016 09:28:24 +0100
|
4
|
+
Subject: [PATCH 11/18] vmdk: Widen before shifting 32 bit header field
|
5
|
+
|
6
|
+
RH-Author: Fam Zheng <famz@redhat.com>
|
7
|
+
Message-id: <1455528511-9357-12-git-send-email-famz@redhat.com>
|
8
|
+
Patchwork-id: 69177
|
9
|
+
O-Subject: [RHEL-7.3 qemu-kvm PATCH 11/18] vmdk: Widen before shifting 32 bit header field
|
10
|
+
Bugzilla: 1299250
|
11
|
+
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
12
|
+
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
13
|
+
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
14
|
+
|
15
|
+
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1299250
|
16
|
+
|
17
|
+
Coverity spotted this.
|
18
|
+
|
19
|
+
The field is 32 bits, but if it's possible to overflow in 32 bit
|
20
|
+
left shift.
|
21
|
+
|
22
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
23
|
+
Reviewed-by: John Snow <jsnow@redhat.com>
|
24
|
+
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
25
|
+
(cherry picked from commit 7237aecd7e8fcc3ccf7fded77b6c127b4df5d3ac)
|
26
|
+
Signed-off-by: Fam Zheng <famz@redhat.com>
|
27
|
+
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
28
|
+
---
|
29
|
+
block/vmdk.c | 2 +-
|
30
|
+
1 file changed, 1 insertion(+), 1 deletion(-)
|
31
|
+
|
32
|
+
diff --git a/block/vmdk.c b/block/vmdk.c
|
33
|
+
index 32b3d4c..3810d75 100644
|
34
|
+
--- a/block/vmdk.c
|
35
|
+
+++ b/block/vmdk.c
|
36
|
+
@@ -525,7 +525,7 @@ static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
|
37
|
+
}
|
38
|
+
ret = vmdk_add_extent(bs, file, false,
|
39
|
+
le32_to_cpu(header.disk_sectors),
|
40
|
+
- le32_to_cpu(header.l1dir_offset) << 9,
|
41
|
+
+ (int64_t)le32_to_cpu(header.l1dir_offset) << 9,
|
42
|
+
0,
|
43
|
+
le32_to_cpu(header.l1dir_size),
|
44
|
+
4096,
|
45
|
+
--
|
46
|
+
1.8.3.1
|
47
|
+
|
@@ -76,7 +76,7 @@ Obsoletes: %1 < %{obsoletes_version} \
|
|
76
76
|
Summary: QEMU is a FAST! processor emulator
|
77
77
|
Name: %{pkgname}%{?pkgsuffix}
|
78
78
|
Version: 1.5.3
|
79
|
-
Release:
|
79
|
+
Release: 126%{?dist}
|
80
80
|
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
|
81
81
|
Epoch: 10
|
82
82
|
License: GPLv2+ and LGPLv2+ and BSD
|
@@ -97,6 +97,7 @@ Requires: libseccomp >= 1.0.0
|
|
97
97
|
%if 0%{!?build_only_sub:1}
|
98
98
|
Requires: glusterfs-api >= 3.6.0
|
99
99
|
%endif
|
100
|
+
Requires: libusbx >= 1.0.19
|
100
101
|
# OOM killer breaks builds with parallel make on s390(x)
|
101
102
|
%ifarch s390 s390x
|
102
103
|
%define _smp_mflags %{nil}
|
@@ -3161,32 +3162,232 @@ Patch1551: kvm-util-uri-Add-overflow-check-to-rfc3986_parse_port.patch
|
|
3161
3162
|
Patch1552: kvm-qemu-iotests-Filter-qemu-io-output-in-025.patch
|
3162
3163
|
# For bz#1270341 - qemu-kvm build failure race condition in tests/ide-test
|
3163
3164
|
Patch1553: kvm-qtest-ide-test-disable-flush-test.patch
|
3164
|
-
# For bz#
|
3165
|
-
Patch1554: kvm-
|
3166
|
-
# For bz#
|
3167
|
-
Patch1555: kvm-rbd-
|
3168
|
-
# For bz#
|
3169
|
-
Patch1556: kvm-
|
3170
|
-
# For bz#
|
3171
|
-
Patch1557: kvm-
|
3172
|
-
# For bz#
|
3173
|
-
Patch1558: kvm-
|
3174
|
-
# For bz#
|
3175
|
-
Patch1559: kvm-
|
3176
|
-
# For bz#
|
3177
|
-
Patch1560: kvm-
|
3178
|
-
# For bz#
|
3179
|
-
Patch1561: kvm-
|
3180
|
-
# For bz#
|
3181
|
-
Patch1562: kvm-
|
3182
|
-
# For bz#
|
3183
|
-
Patch1563: kvm-
|
3184
|
-
# For bz#
|
3185
|
-
Patch1564: kvm-
|
3186
|
-
# For bz#
|
3187
|
-
Patch1565: kvm-
|
3188
|
-
# For bz#
|
3189
|
-
Patch1566: kvm-
|
3165
|
+
# For bz#1268879 - Camera stops work after remote-viewer re-connection [qemu-kvm]
|
3166
|
+
Patch1554: kvm-ehci-clear-suspend-bit-on-detach.patch
|
3167
|
+
# For bz#1277248 - ceph.conf properties override qemu's command-line properties
|
3168
|
+
Patch1555: kvm-rbd-make-qemu-s-cache-setting-override-any-ceph-sett.patch
|
3169
|
+
# For bz#1277248 - ceph.conf properties override qemu's command-line properties
|
3170
|
+
Patch1556: kvm-rbd-fix-ceph-settings-precedence.patch
|
3171
|
+
# For bz#1265427 - contents of MSR_TSC_AUX are not migrated
|
3172
|
+
Patch1557: kvm-target-i386-get-put-MSR_TSC_AUX-across-reset-and-mig.patch
|
3173
|
+
# For bz#1252757 - [RHEL-7.2-qmu-kvm] Package is 100% lost when ping from host to Win2012r2 guest with 64000 size
|
3174
|
+
Patch1558: kvm-rtl8139-Fix-receive-buffer-overflow-check.patch
|
3175
|
+
# For bz#1252757 - [RHEL-7.2-qmu-kvm] Package is 100% lost when ping from host to Win2012r2 guest with 64000 size
|
3176
|
+
Patch1559: kvm-rtl8139-Do-not-consume-the-packet-during-overflow-in.patch
|
3177
|
+
# For bz#1283116 - [abrt] qemu-img: get_block_status(): qemu-img killed by SIGABRT
|
3178
|
+
Patch1560: kvm-raw-posix-Fix-.bdrv_co_get_block_status-for-unaligne.patch
|
3179
|
+
# For bz#1269738 - Vlan table display repeat four times in qmp when queues=4
|
3180
|
+
Patch1561: kvm-net-Make-qmp_query_rx_filter-with-name-argument-more.patch
|
3181
|
+
# For bz#1298048 - CVE-2016-1714 qemu-kvm: Qemu: nvram: OOB r/w access in processing firmware configurations [rhel-7.3]
|
3182
|
+
Patch1562: kvm-fw_cfg-add-check-to-validate-current-entry-value-CVE.patch
|
3183
|
+
# For bz#1296044 - qemu-kvm: insufficient loop termination conditions in start_xmit() and e1000_receive() [rhel-7.3]
|
3184
|
+
Patch1563: kvm-e1000-eliminate-infinite-loops-on-out-of-bounds-tran.patch
|
3185
|
+
# For bz#1285453 - An NBD client can cause QEMU main loop to block when connecting to built-in NBD server
|
3186
|
+
Patch1564: kvm-nbd-Always-call-close_fn-in-nbd_client_new.patch
|
3187
|
+
# For bz#1285453 - An NBD client can cause QEMU main loop to block when connecting to built-in NBD server
|
3188
|
+
Patch1565: kvm-nbd-server-Coroutine-based-negotiation.patch
|
3189
|
+
# For bz#1285453 - An NBD client can cause QEMU main loop to block when connecting to built-in NBD server
|
3190
|
+
Patch1566: kvm-nbd-client_close-on-error-in-nbd_co_client_start.patch
|
3191
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3192
|
+
Patch1567: kvm-qemu-io-Remove-unused-args_command.patch
|
3193
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3194
|
+
Patch1568: kvm-cutils-Support-P-and-E-suffixes-in-strtosz.patch
|
3195
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3196
|
+
Patch1569: kvm-qemu-io-Make-cvtnum-a-wrapper-around-strtosz_suffix.patch
|
3197
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3198
|
+
Patch1570: kvm-qemu-io-Handle-cvtnum-errors-in-alloc.patch
|
3199
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3200
|
+
Patch1571: kvm-qemu-io-Don-t-use-global-bs-in-command-implementatio.patch
|
3201
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3202
|
+
Patch1572: kvm-qemu-io-Split-off-commands-to-qemu-io-cmds.c.patch
|
3203
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3204
|
+
Patch1573: kvm-qemu-io-Factor-out-qemuio_command.patch
|
3205
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3206
|
+
Patch1574: kvm-qemu-io-Move-help-function.patch
|
3207
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3208
|
+
Patch1575: kvm-qemu-io-Move-quit-function.patch
|
3209
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3210
|
+
Patch1576: kvm-qemu-io-Move-qemu_strsep-to-cutils.c.patch
|
3211
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3212
|
+
Patch1577: kvm-qemu-io-Move-functions-for-registering-and-running-c.patch
|
3213
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3214
|
+
Patch1578: kvm-qemu-io-Move-command_loop-and-friends.patch
|
3215
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3216
|
+
Patch1579: kvm-qemu-io-Move-remaining-helpers-from-cmd.c.patch
|
3217
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3218
|
+
Patch1580: kvm-qemu-io-Interface-cleanup.patch
|
3219
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3220
|
+
Patch1581: kvm-qemu-io-Use-the-qemu-version-for-V.patch
|
3221
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3222
|
+
Patch1582: kvm-Make-qemu-io-commands-available-in-HMP.patch
|
3223
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3224
|
+
Patch1583: kvm-blkdebug-Add-BLKDBG_FLUSH_TO_OS-DISK-events.patch
|
3225
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3226
|
+
Patch1584: kvm-qemu-io-fix-cvtnum-lval-types.patch
|
3227
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3228
|
+
Patch1585: kvm-qemu-io-Check-for-trailing-chars.patch
|
3229
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3230
|
+
Patch1586: kvm-qemu-io-Correct-error-messages.patch
|
3231
|
+
# For bz#1272523 - qemu-kvm build failure race condition in tests/ide-test
|
3232
|
+
Patch1587: kvm-ide-test-fix-failure-for-test_flush.patch
|
3233
|
+
# For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
|
3234
|
+
Patch1588: kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch
|
3235
|
+
# For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
|
3236
|
+
Patch1589: kvm-vga-fix-banked-access-bounds-checking-CVE-2016-xxxx.patch
|
3237
|
+
# For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
|
3238
|
+
Patch1590: kvm-vga-add-vbe_enabled-helper.patch
|
3239
|
+
# For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
|
3240
|
+
Patch1591: kvm-vga-factor-out-vga-register-setup.patch
|
3241
|
+
# For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
|
3242
|
+
Patch1592: kvm-vga-update-vga-register-setup-on-vbe-changes.patch
|
3243
|
+
# For bz#1331413 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]
|
3244
|
+
Patch1593: kvm-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
|
3245
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3246
|
+
Patch1594: kvm-vmdk-Leave-bdi-intact-if-ENOTSUP-in-vmdk_get_info.patch
|
3247
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3248
|
+
Patch1595: kvm-vmdk-Use-g_random_int-to-generate-CID.patch
|
3249
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3250
|
+
Patch1596: kvm-vmdk-Fix-comment-to-match-code-of-extent-lines.patch
|
3251
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3252
|
+
Patch1597: kvm-vmdk-Clean-up-descriptor-file-reading.patch
|
3253
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3254
|
+
Patch1598: kvm-vmdk-Check-descriptor-file-length-when-reading-it.patch
|
3255
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3256
|
+
Patch1599: kvm-vmdk-Remove-unnecessary-initialization.patch
|
3257
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3258
|
+
Patch1600: kvm-vmdk-Set-errp-on-failures-in-vmdk_open_vmdk4.patch
|
3259
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3260
|
+
Patch1601: kvm-block-vmdk-make-ret-variable-usage-clear.patch
|
3261
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3262
|
+
Patch1602: kvm-block-vmdk-move-string-allocations-from-stack-to-the.patch
|
3263
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3264
|
+
Patch1603: kvm-block-vmdk-fixed-sizeof-error.patch
|
3265
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3266
|
+
Patch1604: kvm-vmdk-Widen-before-shifting-32-bit-header-field.patch
|
3267
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3268
|
+
Patch1605: kvm-vmdk-Fix-next_cluster_sector-for-compressed-write.patch
|
3269
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3270
|
+
Patch1606: kvm-vmdk-Fix-index_in_cluster-calculation-in-vmdk_co_get.patch
|
3271
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3272
|
+
Patch1607: kvm-vmdk-Use-vmdk_find_index_in_cluster-everywhere.patch
|
3273
|
+
# For bz#1299250 - qemu-img created VMDK images are unbootable
|
3274
|
+
Patch1608: kvm-vmdk-Fix-next_cluster_sector-for-compressed-write2.patch
|
3275
|
+
# For bz#1299116 - qemu-img created VMDK images lead to "Not a supported disk format (sparse VMDK version too old)"
|
3276
|
+
Patch1609: kvm-vmdk-Create-streamOptimized-as-version-3.patch
|
3277
|
+
# For bz#1299116 - qemu-img created VMDK images lead to "Not a supported disk format (sparse VMDK version too old)"
|
3278
|
+
Patch1610: kvm-vmdk-Fix-converting-to-streamOptimized.patch
|
3279
|
+
# For bz#1299116 - qemu-img created VMDK images lead to "Not a supported disk format (sparse VMDK version too old)"
|
3280
|
+
Patch1611: kvm-vmdk-Fix-calculation-of-block-status-s-offset.patch
|
3281
|
+
# For bz#1312289 - "qemu-kvm: /builddir/build/BUILD/qemu-1.5.3/hw/scsi/virtio-scsi.c:533: virtio_scsi_push_event: Assertion `event == 0' failed" after hotplug 20 virtio-scsi disks then hotunplug them
|
3282
|
+
Patch1612: kvm-virtio-scsi-Prevent-assertion-on-missed-events.patch
|
3283
|
+
# For bz#1177318 - Guest using rbd based image as disk failed to start when sandbox was enabled
|
3284
|
+
Patch1613: kvm-seccomp-adding-sysinfo-system-call-to-whitelist.patch
|
3285
|
+
# For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
|
3286
|
+
Patch1614: kvm-acpi-strip-compiler-info-in-built-in-DSDT.patch
|
3287
|
+
# For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
|
3288
|
+
Patch1615: kvm-acpi-fix-endian-ness-for-table-ids.patch
|
3289
|
+
# For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
|
3290
|
+
Patch1616: kvm-acpi-support-specified-oem-table-id-for-build_header.patch
|
3291
|
+
# For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
|
3292
|
+
Patch1617: kvm-acpi-take-oem_id-in-build_header-optionally.patch
|
3293
|
+
# For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
|
3294
|
+
Patch1618: kvm-acpi-expose-oem_id-and-oem_table_id-in-build_rsdt.patch
|
3295
|
+
# For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
|
3296
|
+
Patch1619: kvm-acpi-add-function-to-extract-oem_id-and-oem_table_id.patch
|
3297
|
+
# For bz#1330969 - match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC
|
3298
|
+
Patch1620: kvm-pc-set-the-OEM-fields-in-the-RSDT-and-the-FADT-from-.patch
|
3299
|
+
# For bz#1156635 - Libvirt is confused that qemu-kvm exposes 'block-job-cancel' but not 'block-stream'
|
3300
|
+
Patch1621: kvm-block-jobs-qemu-kvm-rhel-differentiation.patch
|
3301
|
+
# For bz#1283198 - RFE: backport max monitor limitation from Qemu upstream
|
3302
|
+
Patch1622: kvm-qxl-allow-to-specify-head-limit-to-qxl-driver.patch
|
3303
|
+
# For bz#1283198 - RFE: backport max monitor limitation from Qemu upstream
|
3304
|
+
Patch1623: kvm-qxl-Fix-new-function-name-for-spice-server-library.patch
|
3305
|
+
# For bz#1268345 - posix_fallocate emulation on NFS fails with Bad file descriptor if fd is opened O_WRONLY
|
3306
|
+
Patch1624: kvm-block-raw-posix-Open-file-descriptor-O_RDWR-to-work-.patch
|
3307
|
+
# For bz#1256741 - "CapsLock" will work as "\" when boot a guest with usb-kbd
|
3308
|
+
Patch1625: kvm-hw-input-hid.c-Fix-capslock-hid-code.patch
|
3309
|
+
# For bz#1340971 - qemu: accel=tcg does not implement SSE 4 properly
|
3310
|
+
Patch1626: kvm-target-i386-fix-pcmpxstrx-equal-ordered-strstr-mode.patch
|
3311
|
+
# For bz#1336491 - Ship FD connection patches qemu-kvm part
|
3312
|
+
Patch1627: kvm-spice-do-not-require-TCP-ports.patch
|
3313
|
+
# For bz#1346982 - Regression from CVE-2016-3712: windows installer fails to start
|
3314
|
+
Patch1628: kvm-vga-add-sr_vbe-register-set.patch
|
3315
|
+
# For bz#1340929 - CVE-2016-5126 qemu-kvm: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.3]
|
3316
|
+
Patch1629: kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch
|
3317
|
+
# For bz#1327599 - Add Skylake CPU model
|
3318
|
+
Patch1630: kvm-target-i386-add-feature-flags-for-CPUID-EAX-0xd-ECX-.patch
|
3319
|
+
# For bz#1327599 - Add Skylake CPU model
|
3320
|
+
Patch1631: kvm-target-i386-add-Skylake-Client-cpu-model.patch
|
3321
|
+
# For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
|
3322
|
+
Patch1632: kvm-util-introduce-MIN_NON_ZERO.patch
|
3323
|
+
# For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
|
3324
|
+
Patch1633: kvm-BlockLimits-introduce-max_transfer_length.patch
|
3325
|
+
# For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
|
3326
|
+
Patch1634: kvm-block-backend-expose-bs-bl.max_transfer_length.patch
|
3327
|
+
# For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
|
3328
|
+
Patch1635: kvm-scsi-generic-Merge-block-max-xfer-len-in-INQUIRY-res.patch
|
3329
|
+
# For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
|
3330
|
+
Patch1636: kvm-raw-posix-Fetch-max-sectors-for-host-block-device.patch
|
3331
|
+
# For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
|
3332
|
+
Patch1637: kvm-scsi-Advertise-limits-by-blocksize-not-512.patch
|
3333
|
+
# For bz#1318199 - expose host BLKSECTGET limit in scsi-block (qemu-kvm)
|
3334
|
+
Patch1638: kvm-util-Fix-MIN_NON_ZERO.patch
|
3335
|
+
# For bz#1355730 - spice-gtk shows outdated screen state after migration [qemu-kvm]
|
3336
|
+
Patch1639: kvm-qxl-factor-out-qxl_get_check_slot_offset.patch
|
3337
|
+
# For bz#1355730 - spice-gtk shows outdated screen state after migration [qemu-kvm]
|
3338
|
+
Patch1640: kvm-qxl-store-memory-region-and-offset-instead-of-pointe.patch
|
3339
|
+
# For bz#1355730 - spice-gtk shows outdated screen state after migration [qemu-kvm]
|
3340
|
+
Patch1641: kvm-qxl-fix-surface-migration.patch
|
3341
|
+
# For bz#1355730 - spice-gtk shows outdated screen state after migration [qemu-kvm]
|
3342
|
+
Patch1642: kvm-qxl-fix-qxl_set_dirty-call-in-qxl_dirty_one_surface.patch
|
3343
|
+
# For bz#1359729 - CVE-2016-5403 qemu-kvm: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.3]
|
3344
|
+
Patch1643: kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch
|
3345
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3346
|
+
Patch1644: kvm-json-parser-drop-superfluous-assignment-for-token-va.patch
|
3347
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3348
|
+
Patch1645: kvm-qjson-Apply-nesting-limit-more-sanely.patch
|
3349
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3350
|
+
Patch1646: kvm-qjson-Don-t-crash-when-input-exceeds-nesting-limit.patch
|
3351
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3352
|
+
Patch1647: kvm-check-qjson-Add-test-for-JSON-nesting-depth-limit.patch
|
3353
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3354
|
+
Patch1648: kvm-qjson-Spell-out-some-silent-assumptions.patch
|
3355
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3356
|
+
Patch1649: kvm-qjson-Give-each-of-the-six-structural-chars-its-own-.patch
|
3357
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3358
|
+
Patch1650: kvm-qjson-Inline-token_is_keyword-and-simplify.patch
|
3359
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3360
|
+
Patch1651: kvm-qjson-Inline-token_is_escape-and-simplify.patch
|
3361
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3362
|
+
Patch1652: kvm-qjson-replace-QString-in-JSONLexer-with-GString.patch
|
3363
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3364
|
+
Patch1653: kvm-qjson-Convert-to-parser-to-recursive-descent.patch
|
3365
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3366
|
+
Patch1654: kvm-qjson-store-tokens-in-a-GQueue.patch
|
3367
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3368
|
+
Patch1655: kvm-qjson-surprise-allocating-6-QObjects-per-token-is-ex.patch
|
3369
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3370
|
+
Patch1656: kvm-qjson-Limit-number-of-tokens-in-addition-to-total-si.patch
|
3371
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3372
|
+
Patch1657: kvm-json-streamer-Don-t-leak-tokens-on-incomplete-parse.patch
|
3373
|
+
# For bz#1276036 - Crash on QMP input exceeding limits
|
3374
|
+
Patch1658: kvm-json-streamer-fix-double-free-on-exiting-during-a-pa.patch
|
3375
|
+
# For bz#1360137 - GLib-WARNING **: gmem.c:482: custom memory allocation vtable not supported
|
3376
|
+
Patch1659: kvm-trace-remove-malloc-tracing.patch
|
3377
|
+
# For bz#1367040 - QEMU crash when guest notifies non-existent virtqueue
|
3378
|
+
Patch1660: kvm-virtio-validate-the-existence-of-handle_output-befor.patch
|
3379
|
+
# For bz#1371619 - Flags xsaveopt xsavec xgetbv1 are missing on qemu-kvm
|
3380
|
+
Patch1661: kvm-Fix-backport-of-target-i386-add-feature-flags-for-CP.patch
|
3381
|
+
# For bz#1373088 - [FJ7.3 Bug]: virsh dump with both --memory-only and --format option fails
|
3382
|
+
Patch1662: kvm-Add-skip_dump-flag-to-ignore-memory-region-during-du.patch
|
3383
|
+
# For bz#1372459 - [Intel 7.3 Bug] SKL-SP Guest cpu doesn't support avx512 instruction sets(avx512bw, avx512dq and avx512vl) (qemu-kvm)
|
3384
|
+
Patch1663: kvm-target-i386-Add-support-for-FEAT_7_0_ECX.patch
|
3385
|
+
# For bz#1372459 - [Intel 7.3 Bug] SKL-SP Guest cpu doesn't support avx512 instruction sets(avx512bw, avx512dq and avx512vl) (qemu-kvm)
|
3386
|
+
Patch1664: kvm-target-i386-Add-more-Intel-AVX-512-instructions-supp.patch
|
3387
|
+
# For bz#1285453 - An NBD client can cause QEMU main loop to block when connecting to built-in NBD server
|
3388
|
+
Patch1665: kvm-nbd-server-Set-O_NONBLOCK-on-client-fd.patch
|
3389
|
+
# For bz#1376542 - RHSA-2016-1756 breaks migration of instances
|
3390
|
+
Patch1666: kvm-virtio-recalculate-vq-inuse-after-migration.patch
|
3190
3391
|
|
3191
3392
|
|
3192
3393
|
BuildRequires: zlib-devel
|
@@ -3366,37 +3567,6 @@ This package contains some diagnostics and debugging tools for KVM,
|
|
3366
3567
|
such as kvm_stat.
|
3367
3568
|
%endif
|
3368
3569
|
|
3369
|
-
%package -n libcacard%{?pkgsuffix}
|
3370
|
-
Summary: Common Access Card (CAC) Emulation
|
3371
|
-
Group: Development/Libraries
|
3372
|
-
|
3373
|
-
%rhel_rhev_conflicts libcacard
|
3374
|
-
|
3375
|
-
%description -n libcacard%{?pkgsuffix}
|
3376
|
-
Common Access Card (CAC) emulation library.
|
3377
|
-
|
3378
|
-
%package -n libcacard-tools%{?pkgsuffix}
|
3379
|
-
Summary: CAC Emulation tools
|
3380
|
-
Group: Development/Libraries
|
3381
|
-
Requires: libcacard = %{epoch}:%{version}-%{release}
|
3382
|
-
# older qemu-img has vscclient which is now in libcacard-tools
|
3383
|
-
Requires: qemu-img >= 3:1.3.0-5
|
3384
|
-
|
3385
|
-
%rhel_rhev_conflicts libcacard-tools
|
3386
|
-
|
3387
|
-
%description -n libcacard-tools%{?pkgsuffix}
|
3388
|
-
CAC emulation tools.
|
3389
|
-
|
3390
|
-
%package -n libcacard-devel%{?pkgsuffix}
|
3391
|
-
Summary: CAC Emulation devel
|
3392
|
-
Group: Development/Libraries
|
3393
|
-
Requires: libcacard = %{epoch}:%{version}-%{release}
|
3394
|
-
|
3395
|
-
%rhel_rhev_conflicts libcacard-devel
|
3396
|
-
|
3397
|
-
%description -n libcacard-devel%{?pkgsuffix}
|
3398
|
-
CAC emulation development files.
|
3399
|
-
|
3400
3570
|
%prep
|
3401
3571
|
%setup -q -n qemu-%{version}
|
3402
3572
|
cp %{SOURCE18} pc-bios # keep "make check" happy
|
@@ -4966,6 +5136,106 @@ cp %{SOURCE18} pc-bios # keep "make check" happy
|
|
4966
5136
|
%patch1564 -p1
|
4967
5137
|
%patch1565 -p1
|
4968
5138
|
%patch1566 -p1
|
5139
|
+
%patch1567 -p1
|
5140
|
+
%patch1568 -p1
|
5141
|
+
%patch1569 -p1
|
5142
|
+
%patch1570 -p1
|
5143
|
+
%patch1571 -p1
|
5144
|
+
%patch1572 -p1
|
5145
|
+
%patch1573 -p1
|
5146
|
+
%patch1574 -p1
|
5147
|
+
%patch1575 -p1
|
5148
|
+
%patch1576 -p1
|
5149
|
+
%patch1577 -p1
|
5150
|
+
%patch1578 -p1
|
5151
|
+
%patch1579 -p1
|
5152
|
+
%patch1580 -p1
|
5153
|
+
%patch1581 -p1
|
5154
|
+
%patch1582 -p1
|
5155
|
+
%patch1583 -p1
|
5156
|
+
%patch1584 -p1
|
5157
|
+
%patch1585 -p1
|
5158
|
+
%patch1586 -p1
|
5159
|
+
%patch1587 -p1
|
5160
|
+
%patch1588 -p1
|
5161
|
+
%patch1589 -p1
|
5162
|
+
%patch1590 -p1
|
5163
|
+
%patch1591 -p1
|
5164
|
+
%patch1592 -p1
|
5165
|
+
%patch1593 -p1
|
5166
|
+
%patch1594 -p1
|
5167
|
+
%patch1595 -p1
|
5168
|
+
%patch1596 -p1
|
5169
|
+
%patch1597 -p1
|
5170
|
+
%patch1598 -p1
|
5171
|
+
%patch1599 -p1
|
5172
|
+
%patch1600 -p1
|
5173
|
+
%patch1601 -p1
|
5174
|
+
%patch1602 -p1
|
5175
|
+
%patch1603 -p1
|
5176
|
+
%patch1604 -p1
|
5177
|
+
%patch1605 -p1
|
5178
|
+
%patch1606 -p1
|
5179
|
+
%patch1607 -p1
|
5180
|
+
%patch1608 -p1
|
5181
|
+
%patch1609 -p1
|
5182
|
+
%patch1610 -p1
|
5183
|
+
%patch1611 -p1
|
5184
|
+
%patch1612 -p1
|
5185
|
+
%patch1613 -p1
|
5186
|
+
%patch1614 -p1
|
5187
|
+
%patch1615 -p1
|
5188
|
+
%patch1616 -p1
|
5189
|
+
%patch1617 -p1
|
5190
|
+
%patch1618 -p1
|
5191
|
+
%patch1619 -p1
|
5192
|
+
%patch1620 -p1
|
5193
|
+
%patch1621 -p1
|
5194
|
+
%patch1622 -p1
|
5195
|
+
%patch1623 -p1
|
5196
|
+
%patch1624 -p1
|
5197
|
+
%patch1625 -p1
|
5198
|
+
%patch1626 -p1
|
5199
|
+
%patch1627 -p1
|
5200
|
+
%patch1628 -p1
|
5201
|
+
%patch1629 -p1
|
5202
|
+
%patch1630 -p1
|
5203
|
+
%patch1631 -p1
|
5204
|
+
%patch1632 -p1
|
5205
|
+
%patch1633 -p1
|
5206
|
+
%patch1634 -p1
|
5207
|
+
%patch1635 -p1
|
5208
|
+
%patch1636 -p1
|
5209
|
+
%patch1637 -p1
|
5210
|
+
%patch1638 -p1
|
5211
|
+
%patch1639 -p1
|
5212
|
+
%patch1640 -p1
|
5213
|
+
%patch1641 -p1
|
5214
|
+
%patch1642 -p1
|
5215
|
+
%patch1643 -p1
|
5216
|
+
%patch1644 -p1
|
5217
|
+
%patch1645 -p1
|
5218
|
+
%patch1646 -p1
|
5219
|
+
%patch1647 -p1
|
5220
|
+
%patch1648 -p1
|
5221
|
+
%patch1649 -p1
|
5222
|
+
%patch1650 -p1
|
5223
|
+
%patch1651 -p1
|
5224
|
+
%patch1652 -p1
|
5225
|
+
%patch1653 -p1
|
5226
|
+
%patch1654 -p1
|
5227
|
+
%patch1655 -p1
|
5228
|
+
%patch1656 -p1
|
5229
|
+
%patch1657 -p1
|
5230
|
+
%patch1658 -p1
|
5231
|
+
%patch1659 -p1
|
5232
|
+
%patch1660 -p1
|
5233
|
+
%patch1661 -p1
|
5234
|
+
%patch1662 -p1
|
5235
|
+
%patch1663 -p1
|
5236
|
+
%patch1664 -p1
|
5237
|
+
%patch1665 -p1
|
5238
|
+
%patch1666 -p1
|
4969
5239
|
|
4970
5240
|
%build
|
4971
5241
|
buildarch="%{kvm_target}-softmmu"
|
@@ -5065,8 +5335,6 @@ dobuild() {
|
|
5065
5335
|
--disable-guest-agent \
|
5066
5336
|
"$@"
|
5067
5337
|
|
5068
|
-
make libcacard.la %{?_smp_mflags} $buildldflags
|
5069
|
-
make vscclient %{?_smp_mflags} $buildldflags
|
5070
5338
|
make qemu-img %{?_smp_mflags} $buildldflags
|
5071
5339
|
make qemu-io %{?_smp_mflags} $buildldflags
|
5072
5340
|
make qemu-nbd %{?_smp_mflags} $buildldflags
|
@@ -5215,6 +5483,12 @@ dobuild --target-list="$buildarch"
|
|
5215
5483
|
rom_link ../sgabios/sgabios.bin sgabios.bin
|
5216
5484
|
%endif
|
5217
5485
|
|
5486
|
+
# Remove libcacard
|
5487
|
+
rm -rf $RPM_BUILD_ROOT%{_bindir}/vscclient
|
5488
|
+
rm -rf $RPM_BUILD_ROOT%{_includedir}/cacard
|
5489
|
+
rm -rf $RPM_BUILD_ROOT%{_libdir}/libcacard.so*
|
5490
|
+
rm -rf $RPM_BUILD_ROOT%{_libdir}/pkgconfig/libcacard.pc
|
5491
|
+
|
5218
5492
|
%if %{with guest_agent}
|
5219
5493
|
# For the qemu-guest-agent subpackage, install:
|
5220
5494
|
# - the systemd service file and the udev rules:
|
@@ -5250,8 +5524,6 @@ dobuild --target-list="$buildarch"
|
|
5250
5524
|
install -m 0644 %{SOURCE12} $RPM_BUILD_ROOT%{_sysconfdir}/%{pkgname}
|
5251
5525
|
%endif
|
5252
5526
|
|
5253
|
-
make %{?_smp_mflags} $buildldflags DESTDIR=$RPM_BUILD_ROOT install-libcacard
|
5254
|
-
find $RPM_BUILD_ROOT -name "libcacard.so*" -exec chmod +x \{\} \;
|
5255
5527
|
|
5256
5528
|
find $RPM_BUILD_ROOT -name '*.la' -or -name '*.a' | xargs rm -f
|
5257
5529
|
|
@@ -5259,7 +5531,6 @@ find $RPM_BUILD_ROOT -name '*.la' -or -name '*.a' | xargs rm -f
|
|
5259
5531
|
mkdir -p $RPM_BUILD_ROOT%{_bindir}
|
5260
5532
|
mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1/*
|
5261
5533
|
mkdir -p $RPM_BUILD_ROOT%{_mandir}/man8/*
|
5262
|
-
libtool --mode=install install -m 0755 vscclient $RPM_BUILD_ROOT%{_bindir}/vscclient
|
5263
5534
|
install -m 0755 qemu-img $RPM_BUILD_ROOT%{_bindir}/qemu-img
|
5264
5535
|
install -m 0755 qemu-io $RPM_BUILD_ROOT%{_bindir}/qemu-io
|
5265
5536
|
install -m 0755 qemu-nbd $RPM_BUILD_ROOT%{_bindir}/qemu-nbd
|
@@ -5280,6 +5551,7 @@ find $RPM_BUILD_ROOT -name '*.la' -or -name '*.a' | xargs rm -f
|
|
5280
5551
|
%post
|
5281
5552
|
# load kvm modules now, so we can make sure no reboot is needed.
|
5282
5553
|
# If there's already a kvm module installed, we don't mess with it
|
5554
|
+
%udev_rules_update
|
5283
5555
|
sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || :
|
5284
5556
|
udevadm trigger --subsystem-match=misc --sysname-match=kvm --action=add || :
|
5285
5557
|
|
@@ -5407,60 +5679,241 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || :
|
|
5407
5679
|
%{_mandir}/man1/qemu-img.1*
|
5408
5680
|
%{_mandir}/man8/qemu-nbd.8*
|
5409
5681
|
|
5410
|
-
%files -n libcacard%{?pkgsuffix}
|
5411
|
-
%defattr(-,root,root,-)
|
5412
|
-
%{_libdir}/libcacard.so.*
|
5413
|
-
|
5414
|
-
%files -n libcacard-tools%{?pkgsuffix}
|
5415
|
-
%defattr(-,root,root,-)
|
5416
|
-
%{_bindir}/vscclient
|
5417
|
-
|
5418
|
-
%files -n libcacard-devel%{?pkgsuffix}
|
5419
|
-
%defattr(-,root,root,-)
|
5420
|
-
%{_includedir}/cacard
|
5421
|
-
%{_libdir}/libcacard.so
|
5422
|
-
%{_libdir}/pkgconfig/libcacard.pc
|
5423
|
-
|
5424
5682
|
%changelog
|
5425
|
-
* Tue
|
5426
|
-
- kvm-
|
5427
|
-
- Resolves: bz#
|
5428
|
-
(
|
5429
|
-
|
5430
|
-
*
|
5431
|
-
- kvm-
|
5432
|
-
- Resolves: bz#
|
5433
|
-
(
|
5434
|
-
|
5435
|
-
*
|
5436
|
-
- kvm-
|
5437
|
-
-
|
5683
|
+
* Tue Sep 20 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-126.el7
|
5684
|
+
- kvm-virtio-recalculate-vq-inuse-after-migration.patch [bz#1376542]
|
5685
|
+
- Resolves: bz#1376542
|
5686
|
+
(RHSA-2016-1756 breaks migration of instances)
|
5687
|
+
|
5688
|
+
* Thu Sep 15 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-125.el7
|
5689
|
+
- kvm-nbd-server-Set-O_NONBLOCK-on-client-fd.patch [bz#1285453]
|
5690
|
+
- Resolves: bz#1285453
|
5691
|
+
(An NBD client can cause QEMU main loop to block when connecting to built-in NBD server)
|
5692
|
+
|
5693
|
+
* Tue Sep 13 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-124.el7
|
5694
|
+
- kvm-target-i386-Add-support-for-FEAT_7_0_ECX.patch [bz#1372459]
|
5695
|
+
- kvm-target-i386-Add-more-Intel-AVX-512-instructions-supp.patch [bz#1372459]
|
5696
|
+
- Resolves: bz#1372459
|
5697
|
+
([Intel 7.3 Bug] SKL-SP Guest cpu doesn't support avx512 instruction sets(avx512bw, avx512dq and avx512vl) (qemu-kvm))
|
5698
|
+
|
5699
|
+
* Fri Sep 09 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-123.el7
|
5700
|
+
- kvm-Fix-backport-of-target-i386-add-feature-flags-for-CP.patch [bz#1371619]
|
5701
|
+
- kvm-Add-skip_dump-flag-to-ignore-memory-region-during-du.patch [bz#1373088]
|
5702
|
+
- Resolves: bz#1371619
|
5703
|
+
(Flags xsaveopt xsavec xgetbv1 are missing on qemu-kvm)
|
5704
|
+
- Resolves: bz#1373088
|
5705
|
+
([FJ7.3 Bug]: virsh dump with both --memory-only and --format option fails)
|
5706
|
+
|
5707
|
+
* Fri Aug 26 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-122.el7
|
5708
|
+
- kvm-virtio-validate-the-existence-of-handle_output-befor.patch [bz#1367040]
|
5709
|
+
- Resolves: bz#1367040
|
5710
|
+
(QEMU crash when guest notifies non-existent virtqueue)
|
5711
|
+
|
5712
|
+
* Tue Aug 02 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-121.el7
|
5713
|
+
- kvm-json-parser-drop-superfluous-assignment-for-token-va.patch [bz#1276036]
|
5714
|
+
- kvm-qjson-Apply-nesting-limit-more-sanely.patch [bz#1276036]
|
5715
|
+
- kvm-qjson-Don-t-crash-when-input-exceeds-nesting-limit.patch [bz#1276036]
|
5716
|
+
- kvm-check-qjson-Add-test-for-JSON-nesting-depth-limit.patch [bz#1276036]
|
5717
|
+
- kvm-qjson-Spell-out-some-silent-assumptions.patch [bz#1276036]
|
5718
|
+
- kvm-qjson-Give-each-of-the-six-structural-chars-its-own-.patch [bz#1276036]
|
5719
|
+
- kvm-qjson-Inline-token_is_keyword-and-simplify.patch [bz#1276036]
|
5720
|
+
- kvm-qjson-Inline-token_is_escape-and-simplify.patch [bz#1276036]
|
5721
|
+
- kvm-qjson-replace-QString-in-JSONLexer-with-GString.patch [bz#1276036]
|
5722
|
+
- kvm-qjson-Convert-to-parser-to-recursive-descent.patch [bz#1276036]
|
5723
|
+
- kvm-qjson-store-tokens-in-a-GQueue.patch [bz#1276036]
|
5724
|
+
- kvm-qjson-surprise-allocating-6-QObjects-per-token-is-ex.patch [bz#1276036]
|
5725
|
+
- kvm-qjson-Limit-number-of-tokens-in-addition-to-total-si.patch [bz#1276036]
|
5726
|
+
- kvm-json-streamer-Don-t-leak-tokens-on-incomplete-parse.patch [bz#1276036]
|
5727
|
+
- kvm-json-streamer-fix-double-free-on-exiting-during-a-pa.patch [bz#1276036]
|
5728
|
+
- kvm-trace-remove-malloc-tracing.patch [bz#1360137]
|
5729
|
+
- Resolves: bz#1276036
|
5730
|
+
(Crash on QMP input exceeding limits)
|
5731
|
+
- Resolves: bz#1360137
|
5732
|
+
(GLib-WARNING **: gmem.c:482: custom memory allocation vtable not supported)
|
5733
|
+
|
5734
|
+
* Fri Jul 29 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-120.el7
|
5735
|
+
- kvm-Add-install-dependency-to-newer-libusbx-version.patch [bz#1351106]
|
5736
|
+
- kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch [bz#1359729]
|
5737
|
+
- Resolves: bz#1351106
|
5738
|
+
(symbol lookup error: /usr/libexec/qemu-kvm: undefined symbol: libusb_get_port_numbers)
|
5739
|
+
- Resolves: bz#1359729
|
5740
|
+
(CVE-2016-5403 qemu-kvm: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.3])
|
5741
|
+
|
5742
|
+
* Tue Jul 26 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-119.el7
|
5743
|
+
- kvm-qxl-factor-out-qxl_get_check_slot_offset.patch [bz#1355730]
|
5744
|
+
- kvm-qxl-store-memory-region-and-offset-instead-of-pointe.patch [bz#1355730]
|
5745
|
+
- kvm-qxl-fix-surface-migration.patch [bz#1355730]
|
5746
|
+
- kvm-qxl-fix-qxl_set_dirty-call-in-qxl_dirty_one_surface.patch [bz#1355730]
|
5747
|
+
- Resolves: bz#1355730
|
5748
|
+
(spice-gtk shows outdated screen state after migration [qemu-kvm])
|
5749
|
+
|
5750
|
+
* Tue Jul 19 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-118.el7
|
5751
|
+
- kvm-util-introduce-MIN_NON_ZERO.patch [bz#1318199]
|
5752
|
+
- kvm-BlockLimits-introduce-max_transfer_length.patch [bz#1318199]
|
5753
|
+
- kvm-block-backend-expose-bs-bl.max_transfer_length.patch [bz#1318199]
|
5754
|
+
- kvm-scsi-generic-Merge-block-max-xfer-len-in-INQUIRY-res.patch [bz#1318199]
|
5755
|
+
- kvm-raw-posix-Fetch-max-sectors-for-host-block-device.patch [bz#1318199]
|
5756
|
+
- kvm-scsi-Advertise-limits-by-blocksize-not-512.patch [bz#1318199]
|
5757
|
+
- kvm-util-Fix-MIN_NON_ZERO.patch [bz#1318199]
|
5758
|
+
- Resolves: bz#1318199
|
5759
|
+
(expose host BLKSECTGET limit in scsi-block (qemu-kvm))
|
5760
|
+
|
5761
|
+
* Tue Jul 12 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-117.el7
|
5762
|
+
- kvm-target-i386-add-feature-flags-for-CPUID-EAX-0xd-ECX-.patch [bz#1327599]
|
5763
|
+
- kvm-target-i386-add-Skylake-Client-cpu-model.patch [bz#1327599]
|
5764
|
+
- Resolves: bz#1327599
|
5765
|
+
(Add Skylake CPU model)
|
5766
|
+
|
5767
|
+
* Tue Jun 28 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-116.el7
|
5768
|
+
- kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch [bz#1340929]
|
5769
|
+
- Resolves: bz#1340929
|
5770
|
+
(CVE-2016-5126 qemu-kvm: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.3])
|
5771
|
+
|
5772
|
+
* Mon Jun 20 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-115.el7
|
5773
|
+
- kvm-spice-do-not-require-TCP-ports.patch [bz#1336491]
|
5774
|
+
- kvm-vga-add-sr_vbe-register-set.patch [bz#1346982]
|
5775
|
+
- Resolves: bz#1336491
|
5776
|
+
(Ship FD connection patches qemu-kvm part)
|
5777
|
+
- Resolves: bz#1346982
|
5438
5778
|
(Regression from CVE-2016-3712: windows installer fails to start)
|
5439
5779
|
|
5440
|
-
*
|
5441
|
-
- kvm-
|
5442
|
-
- kvm-
|
5443
|
-
- kvm-
|
5444
|
-
-
|
5445
|
-
|
5446
|
-
-
|
5447
|
-
-
|
5448
|
-
|
5449
|
-
|
5450
|
-
|
5451
|
-
-
|
5452
|
-
-
|
5453
|
-
|
5454
|
-
|
5455
|
-
|
5456
|
-
|
5457
|
-
- Resolves: bz#
|
5780
|
+
* Wed Jun 15 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-114.el7
|
5781
|
+
- kvm-hw-input-hid.c-Fix-capslock-hid-code.patch [bz#1256741]
|
5782
|
+
- kvm-target-i386-fix-pcmpxstrx-equal-ordered-strstr-mode.patch [bz#1340971]
|
5783
|
+
- kvm-spec-Update-rules-before-triggering-for-kvm-device.patch [bz#1333159]
|
5784
|
+
- Resolves: bz#1256741
|
5785
|
+
("CapsLock" will work as "\" when boot a guest with usb-kbd)
|
5786
|
+
- Resolves: bz#1333159
|
5787
|
+
(qemu-kvm doesn't reload udev rules before triggering for kvm device)
|
5788
|
+
- Resolves: bz#1340971
|
5789
|
+
(qemu: accel=tcg does not implement SSE 4 properly)
|
5790
|
+
|
5791
|
+
* Sat May 28 2016 Jeff E. Nelson <jen@redhat.com> - 1.5.3-113.el7
|
5792
|
+
- kvm-qxl-allow-to-specify-head-limit-to-qxl-driver.patch [bz#1283198]
|
5793
|
+
- kvm-qxl-Fix-new-function-name-for-spice-server-library.patch [bz#1283198]
|
5794
|
+
- kvm-block-raw-posix-Open-file-descriptor-O_RDWR-to-work-.patch [bz#1268345]
|
5795
|
+
- Resolves: bz#1268345
|
5796
|
+
(posix_fallocate emulation on NFS fails with Bad file descriptor if fd is opened O_WRONLY)
|
5797
|
+
- Resolves: bz#1283198
|
5798
|
+
(RFE: backport max monitor limitation from Qemu upstream)
|
5799
|
+
|
5800
|
+
* Mon May 16 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-112.el7
|
5801
|
+
- kvm-virtio-scsi-Prevent-assertion-on-missed-events.patch [bz#1312289]
|
5802
|
+
- kvm-seccomp-adding-sysinfo-system-call-to-whitelist.patch [bz#1177318]
|
5803
|
+
- kvm-acpi-strip-compiler-info-in-built-in-DSDT.patch [bz#1330969]
|
5804
|
+
- kvm-acpi-fix-endian-ness-for-table-ids.patch [bz#1330969]
|
5805
|
+
- kvm-acpi-support-specified-oem-table-id-for-build_header.patch [bz#1330969]
|
5806
|
+
- kvm-acpi-take-oem_id-in-build_header-optionally.patch [bz#1330969]
|
5807
|
+
- kvm-acpi-expose-oem_id-and-oem_table_id-in-build_rsdt.patch [bz#1330969]
|
5808
|
+
- kvm-acpi-add-function-to-extract-oem_id-and-oem_table_id.patch [bz#1330969]
|
5809
|
+
- kvm-pc-set-the-OEM-fields-in-the-RSDT-and-the-FADT-from-.patch [bz#1330969]
|
5810
|
+
- kvm-block-jobs-qemu-kvm-rhel-differentiation.patch [bz#1156635]
|
5811
|
+
- Resolves: bz#1156635
|
5812
|
+
(Libvirt is confused that qemu-kvm exposes 'block-job-cancel' but not 'block-stream')
|
5813
|
+
- Resolves: bz#1177318
|
5814
|
+
(Guest using rbd based image as disk failed to start when sandbox was enabled)
|
5815
|
+
- Resolves: bz#1312289
|
5816
|
+
("qemu-kvm: /builddir/build/BUILD/qemu-1.5.3/hw/scsi/virtio-scsi.c:533: virtio_scsi_push_event: Assertion `event == 0' failed" after hotplug 20 virtio-scsi disks then hotunplug them)
|
5817
|
+
- Resolves: bz#1330969
|
5818
|
+
(match the OEM ID and OEM Table ID fields of the FADT and the RSDT to those of the SLIC)
|
5819
|
+
|
5820
|
+
* Thu May 05 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-111.el7
|
5821
|
+
- kvm-vmdk-Leave-bdi-intact-if-ENOTSUP-in-vmdk_get_info.patch [bz#1299250]
|
5822
|
+
- kvm-vmdk-Use-g_random_int-to-generate-CID.patch [bz#1299250]
|
5823
|
+
- kvm-vmdk-Fix-comment-to-match-code-of-extent-lines.patch [bz#1299250]
|
5824
|
+
- kvm-vmdk-Clean-up-descriptor-file-reading.patch [bz#1299250]
|
5825
|
+
- kvm-vmdk-Check-descriptor-file-length-when-reading-it.patch [bz#1299250]
|
5826
|
+
- kvm-vmdk-Remove-unnecessary-initialization.patch [bz#1299250]
|
5827
|
+
- kvm-vmdk-Set-errp-on-failures-in-vmdk_open_vmdk4.patch [bz#1299250]
|
5828
|
+
- kvm-block-vmdk-make-ret-variable-usage-clear.patch [bz#1299250]
|
5829
|
+
- kvm-block-vmdk-move-string-allocations-from-stack-to-the.patch [bz#1299250]
|
5830
|
+
- kvm-block-vmdk-fixed-sizeof-error.patch [bz#1299250]
|
5831
|
+
- kvm-vmdk-Widen-before-shifting-32-bit-header-field.patch [bz#1299250]
|
5832
|
+
- kvm-vmdk-Fix-next_cluster_sector-for-compressed-write.patch [bz#1299250]
|
5833
|
+
- kvm-vmdk-Fix-index_in_cluster-calculation-in-vmdk_co_get.patch [bz#1299250]
|
5834
|
+
- kvm-vmdk-Use-vmdk_find_index_in_cluster-everywhere.patch [bz#1299250]
|
5835
|
+
- kvm-vmdk-Fix-next_cluster_sector-for-compressed-write2.patch [bz#1299250]
|
5836
|
+
- kvm-vmdk-Create-streamOptimized-as-version-3.patch [bz#1299116]
|
5837
|
+
- kvm-vmdk-Fix-converting-to-streamOptimized.patch [bz#1299116]
|
5838
|
+
- kvm-vmdk-Fix-calculation-of-block-status-s-offset.patch [bz#1299116]
|
5839
|
+
- Resolves: bz#1299116
|
5840
|
+
(qemu-img created VMDK images lead to "Not a supported disk format (sparse VMDK version too old)")
|
5841
|
+
- Resolves: bz#1299250
|
5842
|
+
(qemu-img created VMDK images are unbootable)
|
5843
|
+
|
5844
|
+
* Wed May 04 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-110.el7
|
5845
|
+
- kvm-qemu-io-Remove-unused-args_command.patch [bz#1272523]
|
5846
|
+
- kvm-cutils-Support-P-and-E-suffixes-in-strtosz.patch [bz#1272523]
|
5847
|
+
- kvm-qemu-io-Make-cvtnum-a-wrapper-around-strtosz_suffix.patch [bz#1272523]
|
5848
|
+
- kvm-qemu-io-Handle-cvtnum-errors-in-alloc.patch [bz#1272523]
|
5849
|
+
- kvm-qemu-io-Don-t-use-global-bs-in-command-implementatio.patch [bz#1272523]
|
5850
|
+
- kvm-qemu-io-Split-off-commands-to-qemu-io-cmds.c.patch [bz#1272523]
|
5851
|
+
- kvm-qemu-io-Factor-out-qemuio_command.patch [bz#1272523]
|
5852
|
+
- kvm-qemu-io-Move-help-function.patch [bz#1272523]
|
5853
|
+
- kvm-qemu-io-Move-quit-function.patch [bz#1272523]
|
5854
|
+
- kvm-qemu-io-Move-qemu_strsep-to-cutils.c.patch [bz#1272523]
|
5855
|
+
- kvm-qemu-io-Move-functions-for-registering-and-running-c.patch [bz#1272523]
|
5856
|
+
- kvm-qemu-io-Move-command_loop-and-friends.patch [bz#1272523]
|
5857
|
+
- kvm-qemu-io-Move-remaining-helpers-from-cmd.c.patch [bz#1272523]
|
5858
|
+
- kvm-qemu-io-Interface-cleanup.patch [bz#1272523]
|
5859
|
+
- kvm-qemu-io-Use-the-qemu-version-for-V.patch [bz#1272523]
|
5860
|
+
- kvm-Make-qemu-io-commands-available-in-HMP.patch [bz#1272523]
|
5861
|
+
- kvm-blkdebug-Add-BLKDBG_FLUSH_TO_OS-DISK-events.patch [bz#1272523]
|
5862
|
+
- kvm-qemu-io-fix-cvtnum-lval-types.patch [bz#1272523]
|
5863
|
+
- kvm-qemu-io-Check-for-trailing-chars.patch [bz#1272523]
|
5864
|
+
- kvm-qemu-io-Correct-error-messages.patch [bz#1272523]
|
5865
|
+
- kvm-ide-test-fix-failure-for-test_flush.patch [bz#1272523]
|
5866
|
+
- kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch [bz#1331413]
|
5867
|
+
- kvm-vga-fix-banked-access-bounds-checking-CVE-2016-xxxx.patch [bz#1331413]
|
5868
|
+
- kvm-vga-add-vbe_enabled-helper.patch [bz#1331413]
|
5869
|
+
- kvm-vga-factor-out-vga-register-setup.patch [bz#1331413]
|
5870
|
+
- kvm-vga-update-vga-register-setup-on-vbe-changes.patch [bz#1331413]
|
5871
|
+
- kvm-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch [bz#1331413]
|
5872
|
+
- Resolves: bz#1272523
|
5873
|
+
(qemu-kvm build failure race condition in tests/ide-test)
|
5874
|
+
- Resolves: bz#1331413
|
5875
|
+
(EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.3])
|
5876
|
+
|
5877
|
+
* Mon Mar 14 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-109.el7
|
5878
|
+
- kvm-e1000-eliminate-infinite-loops-on-out-of-bounds-tran.patch [bz#1296044]
|
5879
|
+
- kvm-nbd-Always-call-close_fn-in-nbd_client_new.patch [bz#1285453]
|
5880
|
+
- kvm-nbd-server-Coroutine-based-negotiation.patch [bz#1285453]
|
5881
|
+
- kvm-nbd-client_close-on-error-in-nbd_co_client_start.patch [bz#1285453]
|
5882
|
+
- kvm-Remove-libcacard-build.patch [bz#1314153]
|
5883
|
+
- Resolves: bz#1285453
|
5884
|
+
(An NBD client can cause QEMU main loop to block when connecting to built-in NBD server)
|
5885
|
+
- Resolves: bz#1296044
|
5886
|
+
(qemu-kvm: insufficient loop termination conditions in start_xmit() and e1000_receive() [rhel-7.3])
|
5887
|
+
- Resolves: bz#1314153
|
5888
|
+
(Disable building of libcacard)
|
5889
|
+
|
5890
|
+
* Mon Feb 08 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-108.el7
|
5891
|
+
- kvm-net-Make-qmp_query_rx_filter-with-name-argument-more.patch [bz#1269738]
|
5892
|
+
- kvm-fw_cfg-add-check-to-validate-current-entry-value-CVE.patch [bz#1298048]
|
5893
|
+
- Resolves: bz#1269738
|
5894
|
+
(Vlan table display repeat four times in qmp when queues=4)
|
5895
|
+
- Resolves: bz#1298048
|
5896
|
+
(CVE-2016-1714 qemu-kvm: Qemu: nvram: OOB r/w access in processing firmware configurations [rhel-7.3])
|
5897
|
+
|
5898
|
+
* Wed Jan 20 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-107.el7
|
5899
|
+
- kvm-raw-posix-Fix-.bdrv_co_get_block_status-for-unaligne.patch [bz#1283116]
|
5900
|
+
- Resolves: bz#1283116
|
5458
5901
|
([abrt] qemu-img: get_block_status(): qemu-img killed by SIGABRT)
|
5459
5902
|
|
5460
|
-
*
|
5461
|
-
- kvm-
|
5462
|
-
- kvm-rbd-
|
5463
|
-
-
|
5903
|
+
* Wed Jan 13 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-106.el7
|
5904
|
+
- kvm-ehci-clear-suspend-bit-on-detach.patch [bz#1268879]
|
5905
|
+
- kvm-rbd-make-qemu-s-cache-setting-override-any-ceph-sett.patch [bz#1277248]
|
5906
|
+
- kvm-rbd-fix-ceph-settings-precedence.patch [bz#1277248]
|
5907
|
+
- kvm-target-i386-get-put-MSR_TSC_AUX-across-reset-and-mig.patch [bz#1265427]
|
5908
|
+
- kvm-rtl8139-Fix-receive-buffer-overflow-check.patch [bz#1252757]
|
5909
|
+
- kvm-rtl8139-Do-not-consume-the-packet-during-overflow-in.patch [bz#1252757]
|
5910
|
+
- Resolves: bz#1252757
|
5911
|
+
([RHEL-7.2-qmu-kvm] Package is 100% lost when ping from host to Win2012r2 guest with 64000 size)
|
5912
|
+
- Resolves: bz#1265427
|
5913
|
+
(contents of MSR_TSC_AUX are not migrated)
|
5914
|
+
- Resolves: bz#1268879
|
5915
|
+
(Camera stops work after remote-viewer re-connection [qemu-kvm])
|
5916
|
+
- Resolves: bz#1277248
|
5464
5917
|
(ceph.conf properties override qemu's command-line properties)
|
5465
5918
|
|
5466
5919
|
* Fri Oct 16 2015 Jeff E. Nelson <jen@redhat.com> - 1.5.3-105.el7
|