1 | The following changes since commit 75e50c80e051423a6f55a34ee4a1eec842444a5b: | 1 | The following changes since commit 36609b4fa36f0ac934874371874416f7533a5408: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/armbru/tags/pull-misc-2018-10-10' into staging (2018-10-11 10:43:37 +0100) | 3 | Merge remote-tracking branch 'remotes/palmer/tags/palmer-for-master-4.2-sf1' into staging (2019-11-02 17:59:03 +0000) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | git://github.com/famz/qemu.git tags/block-pull-request | 7 | https://github.com/stefanha/qemu.git tags/block-pull-request |
8 | 8 | ||
9 | for you to fetch changes up to 6388147296cd4c841a7d4409ba622c200332a8c7: | 9 | for you to fetch changes up to 9fdd7860adec188ed50d2530e9a819e8d953f9bb: |
10 | 10 | ||
11 | nvme: correct locking around completion (2018-10-12 09:46:14 +0800) | 11 | image-fuzzer: Use OSerror.strerror instead of tuple subscript (2019-11-05 16:36:11 +0100) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block patches | 14 | Pull request |
15 | 15 | ||
16 | One fix from Marc-André for iothread. | 16 | Let's get the image fuzzer Python 3 changes merged in QEMU 4.2. |
17 | One fix from Paolo on nvme:// driver. | ||
18 | 17 | ||
19 | ---------------------------------------------------------------- | 18 | ---------------------------------------------------------------- |
20 | 19 | ||
21 | Marc-André Lureau (1): | 20 | Eduardo Habkost (11): |
22 | iothread: fix crash with invalid properties | 21 | image-fuzzer: Open image files in binary mode |
22 | image-fuzzer: Write bytes instead of string to image file | ||
23 | image-fuzzer: Explicitly use integer division operator | ||
24 | image-fuzzer: Use io.StringIO | ||
25 | image-fuzzer: Use %r for all fiels at Field.__repr__() | ||
26 | image-fuzzer: Return bytes objects on string fuzzing functions | ||
27 | image-fuzzer: Use bytes constant for field values | ||
28 | image-fuzzer: Encode file name and file format to bytes | ||
29 | image-fuzzer: Run using python3 | ||
30 | image-fuzzer: Use errors parameter of subprocess.Popen() | ||
31 | image-fuzzer: Use OSerror.strerror instead of tuple subscript | ||
23 | 32 | ||
24 | Paolo Bonzini (1): | 33 | tests/image-fuzzer/qcow2/__init__.py | 1 - |
25 | nvme: correct locking around completion | 34 | tests/image-fuzzer/qcow2/fuzz.py | 54 +++++++++++++------------- |
26 | 35 | tests/image-fuzzer/qcow2/layout.py | 57 ++++++++++++++-------------- | |
27 | block/nvme.c | 2 -- | 36 | tests/image-fuzzer/runner.py | 16 ++++---- |
28 | iothread.c | 9 ++++++--- | 37 | 4 files changed, 63 insertions(+), 65 deletions(-) |
29 | 2 files changed, 6 insertions(+), 5 deletions(-) | ||
30 | 38 | ||
31 | -- | 39 | -- |
32 | 2.17.1 | 40 | 2.23.0 |
33 | 41 | ||
34 | 42 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Eduardo Habkost <ehabkost@redhat.com> | ||
1 | 2 | ||
3 | This probably never caused problems because on Linux there's no | ||
4 | actual newline conversion happening, but on Python 3 the | ||
5 | binary/text distinction is stronger and we must explicitly open | ||
6 | the image file in binary mode. | ||
7 | |||
8 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
9 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
11 | Message-id: 20191016192430.25098-2-ehabkost@redhat.com | ||
12 | Message-Id: <20191016192430.25098-2-ehabkost@redhat.com> | ||
13 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
14 | --- | ||
15 | tests/image-fuzzer/qcow2/layout.py | 2 +- | ||
16 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
17 | |||
18 | diff --git a/tests/image-fuzzer/qcow2/layout.py b/tests/image-fuzzer/qcow2/layout.py | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/tests/image-fuzzer/qcow2/layout.py | ||
21 | +++ b/tests/image-fuzzer/qcow2/layout.py | ||
22 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
23 | |||
24 | def write(self, filename): | ||
25 | """Write an entire image to the file.""" | ||
26 | - image_file = open(filename, 'w') | ||
27 | + image_file = open(filename, 'wb') | ||
28 | for field in self: | ||
29 | image_file.seek(field.offset) | ||
30 | image_file.write(struct.pack(field.fmt, field.value)) | ||
31 | -- | ||
32 | 2.23.0 | ||
33 | |||
34 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Eduardo Habkost <ehabkost@redhat.com> | ||
1 | 2 | ||
3 | This is necessary for Python 3 compatibility. | ||
4 | |||
5 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
6 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
7 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
8 | Message-id: 20191016192430.25098-3-ehabkost@redhat.com | ||
9 | Message-Id: <20191016192430.25098-3-ehabkost@redhat.com> | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | tests/image-fuzzer/qcow2/layout.py | 2 +- | ||
13 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/tests/image-fuzzer/qcow2/layout.py b/tests/image-fuzzer/qcow2/layout.py | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/tests/image-fuzzer/qcow2/layout.py | ||
18 | +++ b/tests/image-fuzzer/qcow2/layout.py | ||
19 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
20 | rounded = (size + self.cluster_size - 1) & ~(self.cluster_size - 1) | ||
21 | if rounded > size: | ||
22 | image_file.seek(rounded - 1) | ||
23 | - image_file.write("\0") | ||
24 | + image_file.write(b'\x00') | ||
25 | image_file.close() | ||
26 | |||
27 | @staticmethod | ||
28 | -- | ||
29 | 2.23.0 | ||
30 | |||
31 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Eduardo Habkost <ehabkost@redhat.com> | |
2 | |||
3 | Most of the division expressions in image-fuzzer assume integer | ||
4 | division. Use the // operator to keep the same behavior when we | ||
5 | move to Python 3. | ||
6 | |||
7 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
8 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
9 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
10 | Message-id: 20191016192430.25098-4-ehabkost@redhat.com | ||
11 | Message-Id: <20191016192430.25098-4-ehabkost@redhat.com> | ||
12 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
13 | --- | ||
14 | tests/image-fuzzer/qcow2/fuzz.py | 12 ++++----- | ||
15 | tests/image-fuzzer/qcow2/layout.py | 40 +++++++++++++++--------------- | ||
16 | 2 files changed, 26 insertions(+), 26 deletions(-) | ||
17 | |||
18 | diff --git a/tests/image-fuzzer/qcow2/fuzz.py b/tests/image-fuzzer/qcow2/fuzz.py | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/tests/image-fuzzer/qcow2/fuzz.py | ||
21 | +++ b/tests/image-fuzzer/qcow2/fuzz.py | ||
22 | @@ -XXX,XX +XXX,XX @@ UINT64 = 0xffffffffffffffff | ||
23 | UINT32_M = 31 | ||
24 | UINT64_M = 63 | ||
25 | # Fuzz vectors | ||
26 | -UINT8_V = [0, 0x10, UINT8/4, UINT8/2 - 1, UINT8/2, UINT8/2 + 1, UINT8 - 1, | ||
27 | +UINT8_V = [0, 0x10, UINT8//4, UINT8//2 - 1, UINT8//2, UINT8//2 + 1, UINT8 - 1, | ||
28 | UINT8] | ||
29 | -UINT16_V = [0, 0x100, 0x1000, UINT16/4, UINT16/2 - 1, UINT16/2, UINT16/2 + 1, | ||
30 | +UINT16_V = [0, 0x100, 0x1000, UINT16//4, UINT16//2 - 1, UINT16//2, UINT16//2 + 1, | ||
31 | UINT16 - 1, UINT16] | ||
32 | -UINT32_V = [0, 0x100, 0x1000, 0x10000, 0x100000, UINT32/4, UINT32/2 - 1, | ||
33 | - UINT32/2, UINT32/2 + 1, UINT32 - 1, UINT32] | ||
34 | -UINT64_V = UINT32_V + [0x1000000, 0x10000000, 0x100000000, UINT64/4, | ||
35 | - UINT64/2 - 1, UINT64/2, UINT64/2 + 1, UINT64 - 1, | ||
36 | +UINT32_V = [0, 0x100, 0x1000, 0x10000, 0x100000, UINT32//4, UINT32//2 - 1, | ||
37 | + UINT32//2, UINT32//2 + 1, UINT32 - 1, UINT32] | ||
38 | +UINT64_V = UINT32_V + [0x1000000, 0x10000000, 0x100000000, UINT64//4, | ||
39 | + UINT64//2 - 1, UINT64//2, UINT64//2 + 1, UINT64 - 1, | ||
40 | UINT64] | ||
41 | STRING_V = ['%s%p%x%d', '.1024d', '%.2049d', '%p%p%p%p', '%x%x%x%x', | ||
42 | '%d%d%d%d', '%s%s%s%s', '%99999999999s', '%08x', '%%20d', '%%20n', | ||
43 | diff --git a/tests/image-fuzzer/qcow2/layout.py b/tests/image-fuzzer/qcow2/layout.py | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/tests/image-fuzzer/qcow2/layout.py | ||
46 | +++ b/tests/image-fuzzer/qcow2/layout.py | ||
47 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
48 | ['>I', self.ext_offset, 0x6803f857, 'ext_magic'], | ||
49 | # One feature table contains 3 fields and takes 48 bytes | ||
50 | ['>I', self.ext_offset + UINT32_S, | ||
51 | - len(feature_tables) / 3 * 48, 'ext_length'] | ||
52 | + len(feature_tables) // 3 * 48, 'ext_length'] | ||
53 | ] + feature_tables) | ||
54 | self.ext_offset = inner_offset | ||
55 | |||
56 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
57 | def create_l2_entry(host, guest, l2_cluster): | ||
58 | """Generate one L2 entry.""" | ||
59 | offset = l2_cluster * self.cluster_size | ||
60 | - l2_size = self.cluster_size / UINT64_S | ||
61 | + l2_size = self.cluster_size // UINT64_S | ||
62 | entry_offset = offset + UINT64_S * (guest % l2_size) | ||
63 | cluster_descriptor = host * self.cluster_size | ||
64 | if not self.header['version'][0].value == 2: | ||
65 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
66 | |||
67 | def create_l1_entry(l2_cluster, l1_offset, guest): | ||
68 | """Generate one L1 entry.""" | ||
69 | - l2_size = self.cluster_size / UINT64_S | ||
70 | - entry_offset = l1_offset + UINT64_S * (guest / l2_size) | ||
71 | + l2_size = self.cluster_size // UINT64_S | ||
72 | + entry_offset = l1_offset + UINT64_S * (guest // l2_size) | ||
73 | # While snapshots are not supported bit #63 = 1 | ||
74 | entry_val = (1 << 63) + l2_cluster * self.cluster_size | ||
75 | return ['>Q', entry_offset, entry_val, 'l1_entry'] | ||
76 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
77 | l2 = [] | ||
78 | else: | ||
79 | meta_data = self._get_metadata() | ||
80 | - guest_clusters = random.sample(range(self.image_size / | ||
81 | + guest_clusters = random.sample(range(self.image_size // | ||
82 | self.cluster_size), | ||
83 | len(self.data_clusters)) | ||
84 | # Number of entries in a L1/L2 table | ||
85 | - l_size = self.cluster_size / UINT64_S | ||
86 | + l_size = self.cluster_size // UINT64_S | ||
87 | # Number of clusters necessary for L1 table | ||
88 | l1_size = int(ceil((max(guest_clusters) + 1) / float(l_size**2))) | ||
89 | l1_start = self._get_adjacent_clusters(self.data_clusters | | ||
90 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
91 | # L2 entries | ||
92 | l2 = [] | ||
93 | for host, guest in zip(self.data_clusters, guest_clusters): | ||
94 | - l2_id = guest / l_size | ||
95 | + l2_id = guest // l_size | ||
96 | if l2_id not in l2_ids: | ||
97 | l2_ids.append(l2_id) | ||
98 | l2_clusters.append(self._get_adjacent_clusters( | ||
99 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
100 | def allocate_rfc_blocks(data, size): | ||
101 | """Return indices of clusters allocated for refcount blocks.""" | ||
102 | cluster_ids = set() | ||
103 | - diff = block_ids = set([x / size for x in data]) | ||
104 | + diff = block_ids = set([x // size for x in data]) | ||
105 | while len(diff) != 0: | ||
106 | # Allocate all yet not allocated clusters | ||
107 | new = self._get_available_clusters(data | cluster_ids, | ||
108 | len(diff)) | ||
109 | # Indices of new refcount blocks necessary to cover clusters | ||
110 | # in 'new' | ||
111 | - diff = set([x / size for x in new]) - block_ids | ||
112 | + diff = set([x // size for x in new]) - block_ids | ||
113 | cluster_ids |= new | ||
114 | block_ids |= diff | ||
115 | return cluster_ids, block_ids | ||
116 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
117 | blocks = set(init_blocks) | ||
118 | clusters = set() | ||
119 | # Number of entries in one cluster of the refcount table | ||
120 | - size = self.cluster_size / UINT64_S | ||
121 | + size = self.cluster_size // UINT64_S | ||
122 | # Number of clusters necessary for the refcount table based on | ||
123 | # the current number of refcount blocks | ||
124 | table_size = int(ceil((max(blocks) + 1) / float(size))) | ||
125 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
126 | table_size + 1)) | ||
127 | # New refcount blocks necessary for clusters occupied by the | ||
128 | # refcount table | ||
129 | - diff = set([c / block_size for c in table_clusters]) - blocks | ||
130 | + diff = set([c // block_size for c in table_clusters]) - blocks | ||
131 | blocks |= diff | ||
132 | while len(diff) != 0: | ||
133 | # Allocate clusters for new refcount blocks | ||
134 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
135 | len(diff)) | ||
136 | # Indices of new refcount blocks necessary to cover | ||
137 | # clusters in 'new' | ||
138 | - diff = set([x / block_size for x in new]) - blocks | ||
139 | + diff = set([x // block_size for x in new]) - blocks | ||
140 | clusters |= new | ||
141 | blocks |= diff | ||
142 | # Check if the refcount table needs one more cluster | ||
143 | if int(ceil((max(blocks) + 1) / float(size))) > table_size: | ||
144 | - new_block_id = (table_start + table_size) / block_size | ||
145 | + new_block_id = (table_start + table_size) // block_size | ||
146 | # Check if the additional table cluster needs | ||
147 | # one more refcount block | ||
148 | if new_block_id not in blocks: | ||
149 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
150 | def create_table_entry(table_offset, block_cluster, block_size, | ||
151 | cluster): | ||
152 | """Generate a refcount table entry.""" | ||
153 | - offset = table_offset + UINT64_S * (cluster / block_size) | ||
154 | + offset = table_offset + UINT64_S * (cluster // block_size) | ||
155 | return ['>Q', offset, block_cluster * self.cluster_size, | ||
156 | 'refcount_table_entry'] | ||
157 | |||
158 | def create_block_entry(block_cluster, block_size, cluster): | ||
159 | """Generate a list of entries for the current block.""" | ||
160 | - entry_size = self.cluster_size / block_size | ||
161 | + entry_size = self.cluster_size // block_size | ||
162 | offset = block_cluster * self.cluster_size | ||
163 | entry_offset = offset + entry_size * (cluster % block_size) | ||
164 | # While snapshots are not supported all refcounts are set to 1 | ||
165 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
166 | # Number of refcount entries per refcount block | ||
167 | # Convert self.cluster_size from bytes to bits to have the same | ||
168 | # base for the numerator and denominator | ||
169 | - block_size = self.cluster_size * 8 / refcount_bits | ||
170 | + block_size = self.cluster_size * 8 // refcount_bits | ||
171 | meta_data = self._get_metadata() | ||
172 | if len(self.data_clusters) == 0: | ||
173 | # All metadata for an empty guest image needs 4 clusters: | ||
174 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
175 | rfc_blocks = [] | ||
176 | |||
177 | for cluster in sorted(self.data_clusters | meta_data): | ||
178 | - if cluster / block_size != block_id: | ||
179 | - block_id = cluster / block_size | ||
180 | + if cluster // block_size != block_id: | ||
181 | + block_id = cluster // block_size | ||
182 | block_cluster = block_clusters[block_ids.index(block_id)] | ||
183 | rfc_table.append(create_table_entry(table_offset, | ||
184 | block_cluster, | ||
185 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
186 | def _alloc_data(img_size, cluster_size): | ||
187 | """Return a set of random indices of clusters allocated for guest data. | ||
188 | """ | ||
189 | - num_of_cls = img_size/cluster_size | ||
190 | + num_of_cls = img_size // cluster_size | ||
191 | return set(random.sample(range(1, num_of_cls + 1), | ||
192 | random.randint(0, num_of_cls))) | ||
193 | |||
194 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
195 | """Return indices of clusters allocated for image metadata.""" | ||
196 | ids = set() | ||
197 | for x in self: | ||
198 | - ids.add(x.offset/self.cluster_size) | ||
199 | + ids.add(x.offset // self.cluster_size) | ||
200 | return ids | ||
201 | |||
202 | |||
203 | -- | ||
204 | 2.23.0 | ||
205 | |||
206 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Eduardo Habkost <ehabkost@redhat.com> | ||
1 | 2 | ||
3 | StringIO.StringIO is not available on Python 3, but io.StringIO | ||
4 | is available on both Python 2 and 3. io.StringIO is slightly | ||
5 | different from the Python 2 StringIO module, though, so we need | ||
6 | bytes coming from subprocess.Popen() to be explicitly decoded. | ||
7 | |||
8 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
9 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
11 | Message-id: 20191016192430.25098-5-ehabkost@redhat.com | ||
12 | Message-Id: <20191016192430.25098-5-ehabkost@redhat.com> | ||
13 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
14 | --- | ||
15 | tests/image-fuzzer/runner.py | 14 +++++++++----- | ||
16 | 1 file changed, 9 insertions(+), 5 deletions(-) | ||
17 | |||
18 | diff --git a/tests/image-fuzzer/runner.py b/tests/image-fuzzer/runner.py | ||
19 | index XXXXXXX..XXXXXXX 100755 | ||
20 | --- a/tests/image-fuzzer/runner.py | ||
21 | +++ b/tests/image-fuzzer/runner.py | ||
22 | @@ -XXX,XX +XXX,XX @@ import shutil | ||
23 | from itertools import count | ||
24 | import time | ||
25 | import getopt | ||
26 | -import StringIO | ||
27 | +import io | ||
28 | import resource | ||
29 | |||
30 | try: | ||
31 | @@ -XXX,XX +XXX,XX @@ def run_app(fd, q_args): | ||
32 | try: | ||
33 | out, err = process.communicate() | ||
34 | signal.alarm(0) | ||
35 | - fd.write(out) | ||
36 | - fd.write(err) | ||
37 | + # fd is a text file, so we need to decode the process output before | ||
38 | + # writing to it. | ||
39 | + # We could be simply using the `errors` parameter of subprocess.Popen(), | ||
40 | + # but this will be possible only after migrating to Python 3 | ||
41 | + fd.write(out.decode(errors='replace')) | ||
42 | + fd.write(err.decode(errors='replace')) | ||
43 | fd.flush() | ||
44 | return process.returncode | ||
45 | |||
46 | @@ -XXX,XX +XXX,XX @@ class TestEnv(object): | ||
47 | MAX_BACKING_FILE_SIZE) * (1 << 20) | ||
48 | cmd = self.qemu_img + ['create', '-f', backing_file_fmt, | ||
49 | backing_file_name, str(backing_file_size)] | ||
50 | - temp_log = StringIO.StringIO() | ||
51 | + temp_log = io.StringIO() | ||
52 | retcode = run_app(temp_log, cmd) | ||
53 | if retcode == 0: | ||
54 | temp_log.close() | ||
55 | @@ -XXX,XX +XXX,XX @@ class TestEnv(object): | ||
56 | "Backing file: %s\n" \ | ||
57 | % (self.seed, " ".join(current_cmd), | ||
58 | self.current_dir, backing_file_name) | ||
59 | - temp_log = StringIO.StringIO() | ||
60 | + temp_log = io.StringIO() | ||
61 | try: | ||
62 | retcode = run_app(temp_log, current_cmd) | ||
63 | except OSError as e: | ||
64 | -- | ||
65 | 2.23.0 | ||
66 | |||
67 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Eduardo Habkost <ehabkost@redhat.com> | ||
1 | 2 | ||
3 | This makes the formatting code simpler, and safer if we change | ||
4 | the type of self.value from str to bytes. | ||
5 | |||
6 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
7 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
8 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
9 | Message-id: 20191016192430.25098-6-ehabkost@redhat.com | ||
10 | Message-Id: <20191016192430.25098-6-ehabkost@redhat.com> | ||
11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
12 | --- | ||
13 | tests/image-fuzzer/qcow2/layout.py | 4 ++-- | ||
14 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
15 | |||
16 | diff --git a/tests/image-fuzzer/qcow2/layout.py b/tests/image-fuzzer/qcow2/layout.py | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/tests/image-fuzzer/qcow2/layout.py | ||
19 | +++ b/tests/image-fuzzer/qcow2/layout.py | ||
20 | @@ -XXX,XX +XXX,XX @@ class Field(object): | ||
21 | return iter([self.fmt, self.offset, self.value, self.name]) | ||
22 | |||
23 | def __repr__(self): | ||
24 | - return "Field(fmt='%s', offset=%d, value=%s, name=%s)" % \ | ||
25 | - (self.fmt, self.offset, str(self.value), self.name) | ||
26 | + return "Field(fmt=%r, offset=%r, value=%r, name=%r)" % \ | ||
27 | + (self.fmt, self.offset, self.value, self.name) | ||
28 | |||
29 | |||
30 | class FieldsList(object): | ||
31 | -- | ||
32 | 2.23.0 | ||
33 | |||
34 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Eduardo Habkost <ehabkost@redhat.com> | ||
1 | 2 | ||
3 | No caller of fuzzer functions is interested in unicode string values, | ||
4 | so replace them with bytes sequences. | ||
5 | |||
6 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
7 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
8 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
9 | Message-id: 20191016192430.25098-7-ehabkost@redhat.com | ||
10 | Message-Id: <20191016192430.25098-7-ehabkost@redhat.com> | ||
11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
12 | --- | ||
13 | tests/image-fuzzer/qcow2/fuzz.py | 42 ++++++++++++++++---------------- | ||
14 | 1 file changed, 21 insertions(+), 21 deletions(-) | ||
15 | |||
16 | diff --git a/tests/image-fuzzer/qcow2/fuzz.py b/tests/image-fuzzer/qcow2/fuzz.py | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/tests/image-fuzzer/qcow2/fuzz.py | ||
19 | +++ b/tests/image-fuzzer/qcow2/fuzz.py | ||
20 | @@ -XXX,XX +XXX,XX @@ UINT32_V = [0, 0x100, 0x1000, 0x10000, 0x100000, UINT32//4, UINT32//2 - 1, | ||
21 | UINT64_V = UINT32_V + [0x1000000, 0x10000000, 0x100000000, UINT64//4, | ||
22 | UINT64//2 - 1, UINT64//2, UINT64//2 + 1, UINT64 - 1, | ||
23 | UINT64] | ||
24 | -STRING_V = ['%s%p%x%d', '.1024d', '%.2049d', '%p%p%p%p', '%x%x%x%x', | ||
25 | - '%d%d%d%d', '%s%s%s%s', '%99999999999s', '%08x', '%%20d', '%%20n', | ||
26 | - '%%20x', '%%20s', '%s%s%s%s%s%s%s%s%s%s', '%p%p%p%p%p%p%p%p%p%p', | ||
27 | - '%#0123456x%08x%x%s%p%d%n%o%u%c%h%l%q%j%z%Z%t%i%e%g%f%a%C%S%08x%%', | ||
28 | - '%s x 129', '%x x 257'] | ||
29 | +BYTES_V = [b'%s%p%x%d', b'.1024d', b'%.2049d', b'%p%p%p%p', b'%x%x%x%x', | ||
30 | + b'%d%d%d%d', b'%s%s%s%s', b'%99999999999s', b'%08x', b'%%20d', b'%%20n', | ||
31 | + b'%%20x', b'%%20s', b'%s%s%s%s%s%s%s%s%s%s', b'%p%p%p%p%p%p%p%p%p%p', | ||
32 | + b'%#0123456x%08x%x%s%p%d%n%o%u%c%h%l%q%j%z%Z%t%i%e%g%f%a%C%S%08x%%', | ||
33 | + b'%s x 129', b'%x x 257'] | ||
34 | |||
35 | |||
36 | def random_from_intervals(intervals): | ||
37 | @@ -XXX,XX +XXX,XX @@ def random_bits(bit_ranges): | ||
38 | return val | ||
39 | |||
40 | |||
41 | -def truncate_string(strings, length): | ||
42 | - """Return strings truncated to specified length.""" | ||
43 | - if type(strings) == list: | ||
44 | - return [s[:length] for s in strings] | ||
45 | +def truncate_bytes(sequences, length): | ||
46 | + """Return sequences truncated to specified length.""" | ||
47 | + if type(sequences) == list: | ||
48 | + return [s[:length] for s in sequences] | ||
49 | else: | ||
50 | - return strings[:length] | ||
51 | + return sequences[:length] | ||
52 | |||
53 | |||
54 | def validator(current, pick, choices): | ||
55 | @@ -XXX,XX +XXX,XX @@ def bit_validator(current, bit_ranges): | ||
56 | return validator(current, random_bits, bit_ranges) | ||
57 | |||
58 | |||
59 | -def string_validator(current, strings): | ||
60 | - """Return a random string value from the list not equal to the current. | ||
61 | +def bytes_validator(current, sequences): | ||
62 | + """Return a random bytes value from the list not equal to the current. | ||
63 | |||
64 | This function is useful for selection from valid values except current one. | ||
65 | """ | ||
66 | - return validator(current, random.choice, strings) | ||
67 | + return validator(current, random.choice, sequences) | ||
68 | |||
69 | |||
70 | def selector(current, constraints, validate=int_validator): | ||
71 | @@ -XXX,XX +XXX,XX @@ def header_length(current): | ||
72 | def bf_name(current): | ||
73 | """Fuzz the backing file name.""" | ||
74 | constraints = [ | ||
75 | - truncate_string(STRING_V, len(current)) | ||
76 | + truncate_bytes(BYTES_V, len(current)) | ||
77 | ] | ||
78 | - return selector(current, constraints, string_validator) | ||
79 | + return selector(current, constraints, bytes_validator) | ||
80 | |||
81 | |||
82 | def ext_magic(current): | ||
83 | @@ -XXX,XX +XXX,XX @@ def ext_length(current): | ||
84 | def bf_format(current): | ||
85 | """Fuzz backing file format in the corresponding header extension.""" | ||
86 | constraints = [ | ||
87 | - truncate_string(STRING_V, len(current)), | ||
88 | - truncate_string(STRING_V, (len(current) + 7) & ~7) # Fuzz padding | ||
89 | + truncate_bytes(BYTES_V, len(current)), | ||
90 | + truncate_bytes(BYTES_V, (len(current) + 7) & ~7) # Fuzz padding | ||
91 | ] | ||
92 | - return selector(current, constraints, string_validator) | ||
93 | + return selector(current, constraints, bytes_validator) | ||
94 | |||
95 | |||
96 | def feature_type(current): | ||
97 | @@ -XXX,XX +XXX,XX @@ def feature_bit_number(current): | ||
98 | def feature_name(current): | ||
99 | """Fuzz feature name field of a feature name table header extension.""" | ||
100 | constraints = [ | ||
101 | - truncate_string(STRING_V, len(current)), | ||
102 | - truncate_string(STRING_V, 46) # Fuzz padding (field length = 46) | ||
103 | + truncate_bytes(BYTES_V, len(current)), | ||
104 | + truncate_bytes(BYTES_V, 46) # Fuzz padding (field length = 46) | ||
105 | ] | ||
106 | - return selector(current, constraints, string_validator) | ||
107 | + return selector(current, constraints, bytes_validator) | ||
108 | |||
109 | |||
110 | def l1_entry(current): | ||
111 | -- | ||
112 | 2.23.0 | ||
113 | |||
114 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Eduardo Habkost <ehabkost@redhat.com> | ||
1 | 2 | ||
3 | Field values are supposed to be bytes objects, not unicode | ||
4 | strings. Change two constants that were declared as strings. | ||
5 | |||
6 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
7 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
8 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
9 | Message-id: 20191016192430.25098-8-ehabkost@redhat.com | ||
10 | Message-Id: <20191016192430.25098-8-ehabkost@redhat.com> | ||
11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
12 | --- | ||
13 | tests/image-fuzzer/qcow2/layout.py | 4 ++-- | ||
14 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
15 | |||
16 | diff --git a/tests/image-fuzzer/qcow2/layout.py b/tests/image-fuzzer/qcow2/layout.py | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/tests/image-fuzzer/qcow2/layout.py | ||
19 | +++ b/tests/image-fuzzer/qcow2/layout.py | ||
20 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
21 | def create_header(self, cluster_bits, backing_file_name=None): | ||
22 | """Generate a random valid header.""" | ||
23 | meta_header = [ | ||
24 | - ['>4s', 0, "QFI\xfb", 'magic'], | ||
25 | + ['>4s', 0, b"QFI\xfb", 'magic'], | ||
26 | ['>I', 4, random.randint(2, 3), 'version'], | ||
27 | ['>Q', 8, 0, 'backing_file_offset'], | ||
28 | ['>I', 16, 0, 'backing_file_size'], | ||
29 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
30 | feature_tables = [] | ||
31 | feature_ids = [] | ||
32 | inner_offset = self.ext_offset + ext_header_len | ||
33 | - feat_name = 'some cool feature' | ||
34 | + feat_name = b'some cool feature' | ||
35 | while len(feature_tables) < num_fnt_entries * 3: | ||
36 | feat_type, feat_bit = gen_feat_ids() | ||
37 | # Remove duplicates | ||
38 | -- | ||
39 | 2.23.0 | ||
40 | |||
41 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Eduardo Habkost <ehabkost@redhat.com> | ||
1 | 2 | ||
3 | Callers of create_image() will pass strings as arguments, but the | ||
4 | Image class will expect bytes objects to be provided. Encode | ||
5 | them inside create_image(). | ||
6 | |||
7 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
8 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
9 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
10 | Message-id: 20191016192430.25098-9-ehabkost@redhat.com | ||
11 | Message-Id: <20191016192430.25098-9-ehabkost@redhat.com> | ||
12 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
13 | --- | ||
14 | tests/image-fuzzer/qcow2/layout.py | 4 ++-- | ||
15 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
16 | |||
17 | diff --git a/tests/image-fuzzer/qcow2/layout.py b/tests/image-fuzzer/qcow2/layout.py | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/tests/image-fuzzer/qcow2/layout.py | ||
20 | +++ b/tests/image-fuzzer/qcow2/layout.py | ||
21 | @@ -XXX,XX +XXX,XX @@ class Image(object): | ||
22 | def create_image(test_img_path, backing_file_name=None, backing_file_fmt=None, | ||
23 | fields_to_fuzz=None): | ||
24 | """Create a fuzzed image and write it to the specified file.""" | ||
25 | - image = Image(backing_file_name) | ||
26 | - image.set_backing_file_format(backing_file_fmt) | ||
27 | + image = Image(backing_file_name.encode()) | ||
28 | + image.set_backing_file_format(backing_file_fmt.encode()) | ||
29 | image.create_feature_name_table() | ||
30 | image.set_end_of_extension_area() | ||
31 | image.create_l_structures() | ||
32 | -- | ||
33 | 2.23.0 | ||
34 | |||
35 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Eduardo Habkost <ehabkost@redhat.com> | ||
1 | 2 | ||
3 | image-fuzzer is now supposed to be ready to run using Python 3. | ||
4 | Remove the __future__ imports and change the interpreter line to | ||
5 | "#!/usr/bin/env python3". | ||
6 | |||
7 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
8 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
9 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
10 | Message-id: 20191016192430.25098-10-ehabkost@redhat.com | ||
11 | Message-Id: <20191016192430.25098-10-ehabkost@redhat.com> | ||
12 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
13 | --- | ||
14 | tests/image-fuzzer/qcow2/__init__.py | 1 - | ||
15 | tests/image-fuzzer/qcow2/layout.py | 1 - | ||
16 | tests/image-fuzzer/runner.py | 3 +-- | ||
17 | 3 files changed, 1 insertion(+), 4 deletions(-) | ||
18 | |||
19 | diff --git a/tests/image-fuzzer/qcow2/__init__.py b/tests/image-fuzzer/qcow2/__init__.py | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/tests/image-fuzzer/qcow2/__init__.py | ||
22 | +++ b/tests/image-fuzzer/qcow2/__init__.py | ||
23 | @@ -1,2 +1 @@ | ||
24 | -from __future__ import absolute_import | ||
25 | from .layout import create_image | ||
26 | diff --git a/tests/image-fuzzer/qcow2/layout.py b/tests/image-fuzzer/qcow2/layout.py | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/tests/image-fuzzer/qcow2/layout.py | ||
29 | +++ b/tests/image-fuzzer/qcow2/layout.py | ||
30 | @@ -XXX,XX +XXX,XX @@ | ||
31 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
32 | # | ||
33 | |||
34 | -from __future__ import absolute_import | ||
35 | import random | ||
36 | import struct | ||
37 | from . import fuzz | ||
38 | diff --git a/tests/image-fuzzer/runner.py b/tests/image-fuzzer/runner.py | ||
39 | index XXXXXXX..XXXXXXX 100755 | ||
40 | --- a/tests/image-fuzzer/runner.py | ||
41 | +++ b/tests/image-fuzzer/runner.py | ||
42 | @@ -XXX,XX +XXX,XX @@ | ||
43 | -#!/usr/bin/env python | ||
44 | +#!/usr/bin/env python3 | ||
45 | |||
46 | # Tool for running fuzz tests | ||
47 | # | ||
48 | @@ -XXX,XX +XXX,XX @@ | ||
49 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
50 | # | ||
51 | |||
52 | -from __future__ import print_function | ||
53 | import sys | ||
54 | import os | ||
55 | import signal | ||
56 | -- | ||
57 | 2.23.0 | ||
58 | |||
59 | diff view generated by jsdifflib |
1 | From: Paolo Bonzini <pbonzini@redhat.com> | 1 | From: Eduardo Habkost <ehabkost@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | nvme_poll_queues is already protected by q->lock, and | 3 | Instead of manually encoding stderr and stdout output, use |
4 | AIO callbacks are invoked outside the AioContext lock. | 4 | `errors` parameter of subprocess.Popen(). This will make |
5 | So remove the acquire/release pair in nvme_handle_event. | 5 | process.communicate() return unicode strings instead of bytes |
6 | objects. | ||
6 | 7 | ||
7 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | 8 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> |
8 | Message-Id: <20180814062739.19640-1-pbonzini@redhat.com> | 9 | Reviewed-by: John Snow <jsnow@redhat.com> |
9 | Signed-off-by: Fam Zheng <famz@redhat.com> | 10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
11 | Message-id: 20191016192430.25098-11-ehabkost@redhat.com | ||
12 | Message-Id: <20191016192430.25098-11-ehabkost@redhat.com> | ||
13 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
10 | --- | 14 | --- |
11 | block/nvme.c | 2 -- | 15 | tests/image-fuzzer/runner.py | 11 ++++------- |
12 | 1 file changed, 2 deletions(-) | 16 | 1 file changed, 4 insertions(+), 7 deletions(-) |
13 | 17 | ||
14 | diff --git a/block/nvme.c b/block/nvme.c | 18 | diff --git a/tests/image-fuzzer/runner.py b/tests/image-fuzzer/runner.py |
15 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100755 |
16 | --- a/block/nvme.c | 20 | --- a/tests/image-fuzzer/runner.py |
17 | +++ b/block/nvme.c | 21 | +++ b/tests/image-fuzzer/runner.py |
18 | @@ -XXX,XX +XXX,XX @@ static void nvme_handle_event(EventNotifier *n) | 22 | @@ -XXX,XX +XXX,XX @@ def run_app(fd, q_args): |
19 | BDRVNVMeState *s = container_of(n, BDRVNVMeState, irq_notifier); | 23 | devnull = open('/dev/null', 'r+') |
20 | 24 | process = subprocess.Popen(q_args, stdin=devnull, | |
21 | trace_nvme_handle_event(s); | 25 | stdout=subprocess.PIPE, |
22 | - aio_context_acquire(s->aio_context); | 26 | - stderr=subprocess.PIPE) |
23 | event_notifier_test_and_clear(n); | 27 | + stderr=subprocess.PIPE, |
24 | nvme_poll_queues(s); | 28 | + errors='replace') |
25 | - aio_context_release(s->aio_context); | 29 | try: |
26 | } | 30 | out, err = process.communicate() |
27 | 31 | signal.alarm(0) | |
28 | static bool nvme_add_io_queue(BlockDriverState *bs, Error **errp) | 32 | - # fd is a text file, so we need to decode the process output before |
33 | - # writing to it. | ||
34 | - # We could be simply using the `errors` parameter of subprocess.Popen(), | ||
35 | - # but this will be possible only after migrating to Python 3 | ||
36 | - fd.write(out.decode(errors='replace')) | ||
37 | - fd.write(err.decode(errors='replace')) | ||
38 | + fd.write(out) | ||
39 | + fd.write(err) | ||
40 | fd.flush() | ||
41 | return process.returncode | ||
42 | |||
29 | -- | 43 | -- |
30 | 2.17.1 | 44 | 2.23.0 |
31 | 45 | ||
32 | 46 | diff view generated by jsdifflib |
1 | From: Marc-André Lureau <marcandre.lureau@redhat.com> | 1 | From: Eduardo Habkost <ehabkost@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | -object iothread,id=foo,? will crash qemu: | 3 | OSError can't be used like a tuple on Python 3, so change the |
4 | code to use `e.sterror` instead of `e[1]`. | ||
4 | 5 | ||
5 | qemu-system-x86_64:qemu-thread-posix.c:128: qemu_cond_destroy: Assertion `cond->initialized' failed. | 6 | Reported-by: John Snow <jsnow@redhat.com> |
7 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | ||
8 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
9 | Message-id: 20191021214117.18091-1-ehabkost@redhat.com | ||
10 | Message-Id: <20191021214117.18091-1-ehabkost@redhat.com> | ||
11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
12 | --- | ||
13 | tests/image-fuzzer/runner.py | 4 ++-- | ||
14 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
6 | 15 | ||
7 | Use thread_id != -1 to check if iothread_complete() finished | 16 | diff --git a/tests/image-fuzzer/runner.py b/tests/image-fuzzer/runner.py |
8 | successfully and the mutex/cond have been initialized. | 17 | index XXXXXXX..XXXXXXX 100755 |
9 | 18 | --- a/tests/image-fuzzer/runner.py | |
10 | Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> | 19 | +++ b/tests/image-fuzzer/runner.py |
11 | Message-Id: <20180821100716.13803-1-marcandre.lureau@redhat.com> | 20 | @@ -XXX,XX +XXX,XX @@ class TestEnv(object): |
12 | Signed-off-by: Fam Zheng <famz@redhat.com> | 21 | os.makedirs(self.current_dir) |
13 | --- | 22 | except OSError as e: |
14 | iothread.c | 9 ++++++--- | 23 | print("Error: The working directory '%s' cannot be used. Reason: %s"\ |
15 | 1 file changed, 6 insertions(+), 3 deletions(-) | 24 | - % (self.work_dir, e[1]), file=sys.stderr) |
16 | 25 | + % (self.work_dir, e.strerror), file=sys.stderr) | |
17 | diff --git a/iothread.c b/iothread.c | 26 | raise TestException |
18 | index XXXXXXX..XXXXXXX 100644 | 27 | self.log = open(os.path.join(self.current_dir, "test.log"), "w") |
19 | --- a/iothread.c | 28 | self.parent_log = open(run_log, "a") |
20 | +++ b/iothread.c | 29 | @@ -XXX,XX +XXX,XX @@ class TestEnv(object): |
21 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_init(Object *obj) | 30 | except OSError as e: |
22 | IOThread *iothread = IOTHREAD(obj); | 31 | multilog("%sError: Start of '%s' failed. Reason: %s\n\n" |
23 | 32 | % (test_summary, os.path.basename(current_cmd[0]), | |
24 | iothread->poll_max_ns = IOTHREAD_POLL_MAX_NS_DEFAULT; | 33 | - e[1]), |
25 | + iothread->thread_id = -1; | 34 | + e.strerror), |
26 | } | 35 | sys.stderr, self.log, self.parent_log) |
27 | 36 | raise TestException | |
28 | static void iothread_instance_finalize(Object *obj) | 37 | |
29 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | ||
30 | IOThread *iothread = IOTHREAD(obj); | ||
31 | |||
32 | iothread_stop(iothread); | ||
33 | + | ||
34 | + if (iothread->thread_id != -1) { | ||
35 | + qemu_cond_destroy(&iothread->init_done_cond); | ||
36 | + qemu_mutex_destroy(&iothread->init_done_lock); | ||
37 | + } | ||
38 | /* | ||
39 | * Before glib2 2.33.10, there is a glib2 bug that GSource context | ||
40 | * pointer may not be cleared even if the context has already been | ||
41 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | ||
42 | g_main_context_unref(iothread->worker_context); | ||
43 | iothread->worker_context = NULL; | ||
44 | } | ||
45 | - qemu_cond_destroy(&iothread->init_done_cond); | ||
46 | - qemu_mutex_destroy(&iothread->init_done_lock); | ||
47 | } | ||
48 | |||
49 | static void iothread_complete(UserCreatable *obj, Error **errp) | ||
50 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) | ||
51 | |||
52 | iothread->stopping = false; | ||
53 | iothread->running = true; | ||
54 | - iothread->thread_id = -1; | ||
55 | iothread->ctx = aio_context_new(&local_error); | ||
56 | if (!iothread->ctx) { | ||
57 | error_propagate(errp, local_error); | ||
58 | -- | 38 | -- |
59 | 2.17.1 | 39 | 2.23.0 |
60 | 40 | ||
61 | 41 | diff view generated by jsdifflib |