master
c 1,082 lines 35.6 KB
Raw
1 /*
2 * Block layer qmp and info dump related functions
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25 #include "qemu/osdep.h"
26 #include "qemu/cutils.h"
27 #include "block/qapi.h"
28 #include "block/block_int.h"
29 #include "block/dirty-bitmap.h"
30 #include "block/throttle-groups.h"
31 #include "block/write-threshold.h"
32 #include "qapi/error.h"
33 #include "qapi/qapi-commands-block-core.h"
34 #include "qapi/qobject-output-visitor.h"
35 #include "qapi/qapi-visit-block-core.h"
36 #include "qobject/qbool.h"
37 #include "qobject/qdict.h"
38 #include "qobject/qlist.h"
39 #include "qobject/qnum.h"
40 #include "qobject/qstring.h"
41 #include "qemu/qemu-print.h"
42 #include "system/block-backend.h"
43
44 BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
45 BlockDriverState *bs,
46 bool flat,
47 Error **errp)
48 {
49 ERRP_GUARD();
50 ImageInfo **p_image_info;
51 ImageInfo *backing_info;
52 BlockDriverState *backing;
53 BlockDeviceInfo *info;
54 BlockdevChildList **children_list_tail;
55 BdrvChild *child;
56
57 if (!bs->drv) {
58 error_setg(errp, "Block device %s is ejected", bs->node_name);
59 return NULL;
60 }
61
62 bdrv_refresh_filename(bs);
63
64 info = g_malloc0(sizeof(*info));
65 info->file = g_strdup(bs->filename);
66 info->ro = bdrv_is_read_only(bs);
67 info->drv = g_strdup(bs->drv->format_name);
68 info->active = !bdrv_is_inactive(bs);
69 info->encrypted = bs->encrypted;
70
71 info->cache = g_new(BlockdevCacheInfo, 1);
72 *info->cache = (BlockdevCacheInfo) {
73 .writeback = blk ? blk_enable_write_cache(blk) : true,
74 .direct = !!(bs->open_flags & BDRV_O_NOCACHE),
75 .no_flush = !!(bs->open_flags & BDRV_O_NO_FLUSH),
76 };
77
78 info->node_name = g_strdup(bs->node_name);
79
80 children_list_tail = &info->children;
81 QLIST_FOREACH(child, &bs->children, next) {
82 BlockdevChild *child_ref = g_new0(BlockdevChild, 1);
83 child_ref->child = g_strdup(child->name);
84 child_ref->node_name = g_strdup(child->bs->node_name);
85 QAPI_LIST_APPEND(children_list_tail, child_ref);
86 }
87
88 backing = bdrv_cow_bs(bs);
89 if (backing) {
90 info->backing_file = g_strdup(backing->filename);
91 }
92
93 if (!QLIST_EMPTY(&bs->dirty_bitmaps)) {
94 info->has_dirty_bitmaps = true;
95 info->dirty_bitmaps = bdrv_query_dirty_bitmaps(bs);
96 }
97
98 info->detect_zeroes = bs->detect_zeroes;
99
100 if (blk && blk_get_public(blk)->throttle_group_member.throttle_state) {
101 ThrottleConfig cfg;
102 BlockBackendPublic *blkp = blk_get_public(blk);
103
104 throttle_group_get_config(&blkp->throttle_group_member, &cfg);
105
106 info->bps = cfg.buckets[THROTTLE_BPS_TOTAL].avg;
107 info->bps_rd = cfg.buckets[THROTTLE_BPS_READ].avg;
108 info->bps_wr = cfg.buckets[THROTTLE_BPS_WRITE].avg;
109
110 info->iops = cfg.buckets[THROTTLE_OPS_TOTAL].avg;
111 info->iops_rd = cfg.buckets[THROTTLE_OPS_READ].avg;
112 info->iops_wr = cfg.buckets[THROTTLE_OPS_WRITE].avg;
113
114 info->has_bps_max = cfg.buckets[THROTTLE_BPS_TOTAL].max;
115 info->bps_max = cfg.buckets[THROTTLE_BPS_TOTAL].max;
116 info->has_bps_rd_max = cfg.buckets[THROTTLE_BPS_READ].max;
117 info->bps_rd_max = cfg.buckets[THROTTLE_BPS_READ].max;
118 info->has_bps_wr_max = cfg.buckets[THROTTLE_BPS_WRITE].max;
119 info->bps_wr_max = cfg.buckets[THROTTLE_BPS_WRITE].max;
120
121 info->has_iops_max = cfg.buckets[THROTTLE_OPS_TOTAL].max;
122 info->iops_max = cfg.buckets[THROTTLE_OPS_TOTAL].max;
123 info->has_iops_rd_max = cfg.buckets[THROTTLE_OPS_READ].max;
124 info->iops_rd_max = cfg.buckets[THROTTLE_OPS_READ].max;
125 info->has_iops_wr_max = cfg.buckets[THROTTLE_OPS_WRITE].max;
126 info->iops_wr_max = cfg.buckets[THROTTLE_OPS_WRITE].max;
127
128 info->has_bps_max_length = info->has_bps_max;
129 info->bps_max_length =
130 cfg.buckets[THROTTLE_BPS_TOTAL].burst_length;
131 info->has_bps_rd_max_length = info->has_bps_rd_max;
132 info->bps_rd_max_length =
133 cfg.buckets[THROTTLE_BPS_READ].burst_length;
134 info->has_bps_wr_max_length = info->has_bps_wr_max;
135 info->bps_wr_max_length =
136 cfg.buckets[THROTTLE_BPS_WRITE].burst_length;
137
138 info->has_iops_max_length = info->has_iops_max;
139 info->iops_max_length =
140 cfg.buckets[THROTTLE_OPS_TOTAL].burst_length;
141 info->has_iops_rd_max_length = info->has_iops_rd_max;
142 info->iops_rd_max_length =
143 cfg.buckets[THROTTLE_OPS_READ].burst_length;
144 info->has_iops_wr_max_length = info->has_iops_wr_max;
145 info->iops_wr_max_length =
146 cfg.buckets[THROTTLE_OPS_WRITE].burst_length;
147
148 info->has_iops_size = cfg.op_size;
149 info->iops_size = cfg.op_size;
150
151 info->group =
152 g_strdup(throttle_group_get_name(&blkp->throttle_group_member));
153 }
154
155 info->write_threshold = bdrv_write_threshold_get(bs);
156
157 p_image_info = &info->image;
158 info->backing_file_depth = 0;
159
160 /*
161 * Skip automatically inserted nodes that the user isn't aware of for
162 * query-block (blk != NULL), but not for query-named-block-nodes
163 */
164 bdrv_query_image_info(bs, p_image_info, flat, blk != NULL, errp);
165 if (*errp) {
166 qapi_free_BlockDeviceInfo(info);
167 return NULL;
168 }
169
170 backing_info = info->image->backing_image;
171 while (backing_info) {
172 info->backing_file_depth++;
173 backing_info = backing_info->backing_image;
174 }
175
176 return info;
177 }
178
179 /*
180 * Returns 0 on success, with *p_list either set to describe snapshot
181 * information, or NULL because there are no snapshots. Returns -errno on
182 * error, with *p_list untouched.
183 */
184 int bdrv_query_snapshot_info_list(BlockDriverState *bs,
185 SnapshotInfoList **p_list,
186 Error **errp)
187 {
188 int i, sn_count;
189 QEMUSnapshotInfo *sn_tab = NULL;
190 SnapshotInfoList *head = NULL, **tail = &head;
191 SnapshotInfo *info;
192
193 sn_count = bdrv_snapshot_list(bs, &sn_tab);
194 if (sn_count < 0) {
195 const char *dev = bdrv_get_device_name(bs);
196 switch (sn_count) {
197 case -ENOMEDIUM:
198 error_setg(errp, "Device '%s' is not inserted", dev);
199 break;
200 case -ENOTSUP:
201 error_setg(errp,
202 "Device '%s' does not support internal snapshots",
203 dev);
204 break;
205 default:
206 error_setg_errno(errp, -sn_count,
207 "Can't list snapshots of device '%s'", dev);
208 break;
209 }
210 return sn_count;
211 }
212
213 for (i = 0; i < sn_count; i++) {
214 info = g_new0(SnapshotInfo, 1);
215 info->id = g_strdup(sn_tab[i].id_str);
216 info->name = g_strdup(sn_tab[i].name);
217 info->vm_state_size = sn_tab[i].vm_state_size;
218 info->date_sec = sn_tab[i].date_sec;
219 info->date_nsec = sn_tab[i].date_nsec;
220 info->vm_clock_sec = sn_tab[i].vm_clock_nsec / 1000000000;
221 info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
222 info->icount = sn_tab[i].icount;
223 info->has_icount = sn_tab[i].icount != -1ULL;
224
225 QAPI_LIST_APPEND(tail, info);
226 }
227
228 g_free(sn_tab);
229 *p_list = head;
230 return 0;
231 }
232
233 /**
234 * Helper function for other query info functions. Store information about @bs
235 * in @info, setting @errp on error.
236 */
237 static void GRAPH_RDLOCK
238 bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, bool limits,
239 Error **errp)
240 {
241 int64_t size;
242 const char *backing_filename;
243 BlockDriverInfo bdi;
244 int ret;
245 Error *err = NULL;
246
247 size = bdrv_getlength(bs);
248 if (size < 0) {
249 error_setg_errno(errp, -size, "Can't get image size '%s'",
250 bs->exact_filename);
251 return;
252 }
253
254 bdrv_refresh_filename(bs);
255
256 info->filename = g_strdup(bs->filename);
257 info->format = g_strdup(bdrv_get_format_name(bs));
258 info->virtual_size = size;
259 info->actual_size = bdrv_get_allocated_file_size(bs);
260 info->has_actual_size = info->actual_size >= 0;
261 if (bs->encrypted) {
262 info->encrypted = true;
263 info->has_encrypted = true;
264 }
265 if (bdrv_get_info(bs, &bdi) >= 0) {
266 if (bdi.cluster_size != 0) {
267 info->cluster_size = bdi.cluster_size;
268 info->has_cluster_size = true;
269 }
270 info->dirty_flag = bdi.is_dirty;
271 info->has_dirty_flag = true;
272 }
273
274 if (limits) {
275 info->limits = g_new(BlockLimitsInfo, 1);
276 *info->limits = (BlockLimitsInfo) {
277 .request_alignment = bs->bl.request_alignment,
278 .has_max_discard = bs->bl.max_pdiscard != 0,
279 .max_discard = bs->bl.max_pdiscard,
280 .has_discard_alignment = bs->bl.pdiscard_alignment != 0,
281 .discard_alignment = bs->bl.pdiscard_alignment,
282 .has_max_write_zeroes = bs->bl.max_pwrite_zeroes != 0,
283 .max_write_zeroes = bs->bl.max_pwrite_zeroes,
284 .has_write_zeroes_alignment = bs->bl.pwrite_zeroes_alignment != 0,
285 .write_zeroes_alignment = bs->bl.pwrite_zeroes_alignment,
286 .has_opt_transfer = bs->bl.opt_transfer != 0,
287 .opt_transfer = bs->bl.opt_transfer,
288 .has_max_transfer = bs->bl.max_transfer != 0,
289 .max_transfer = bs->bl.max_transfer,
290 .has_max_hw_transfer = bs->bl.max_hw_transfer != 0,
291 .max_hw_transfer = bs->bl.max_hw_transfer,
292 .max_iov = bs->bl.max_iov,
293 .has_max_hw_iov = bs->bl.max_hw_iov != 0,
294 .max_hw_iov = bs->bl.max_hw_iov,
295 .min_mem_alignment = bs->bl.min_mem_alignment,
296 .opt_mem_alignment = bs->bl.opt_mem_alignment,
297 };
298 }
299
300 info->format_specific = bdrv_get_specific_info(bs, &err);
301 if (err) {
302 error_propagate(errp, err);
303 return;
304 }
305 backing_filename = bs->backing_file;
306 if (backing_filename[0] != '\0') {
307 char *backing_filename2;
308
309 info->backing_filename = g_strdup(backing_filename);
310 backing_filename2 = bdrv_get_full_backing_filename(bs, NULL);
311
312 /* Always report the full_backing_filename if present, even if it's the
313 * same as backing_filename. That they are same is useful info. */
314 if (backing_filename2) {
315 info->full_backing_filename = g_strdup(backing_filename2);
316 }
317
318 if (bs->backing_format[0]) {
319 info->backing_filename_format = g_strdup(bs->backing_format);
320 }
321 g_free(backing_filename2);
322 }
323
324 ret = bdrv_query_snapshot_info_list(bs, &info->snapshots, &err);
325 switch (ret) {
326 case 0:
327 if (info->snapshots) {
328 info->has_snapshots = true;
329 }
330 break;
331 /* recoverable error */
332 case -ENOMEDIUM:
333 case -ENOTSUP:
334 error_free(err);
335 break;
336 default:
337 error_propagate(errp, err);
338 return;
339 }
340 }
341
342 /**
343 * bdrv_query_image_info:
344 * @bs: block node to examine
345 * @p_info: location to store image information
346 * @flat: skip backing node information
347 * @skip_implicit_filters: skip implicit filters in the backing chain
348 * @errp: location to store error information
349 *
350 * Store image information in @p_info, potentially recursively covering the
351 * backing chain.
352 *
353 * If @flat is true, do not query backing image information, i.e.
354 * (*p_info)->has_backing_image will be set to false and
355 * (*p_info)->backing_image to NULL even when the image does in fact have a
356 * backing image.
357 *
358 * If @skip_implicit_filters is true, implicit filter nodes in the backing chain
359 * will be skipped when querying backing image information.
360 * (@skip_implicit_filters is ignored when @flat is true.)
361 *
362 * @p_info will be set only on success. On error, store error in @errp.
363 */
364 void bdrv_query_image_info(BlockDriverState *bs,
365 ImageInfo **p_info,
366 bool flat,
367 bool skip_implicit_filters,
368 Error **errp)
369 {
370 ERRP_GUARD();
371 ImageInfo *info;
372
373 info = g_new0(ImageInfo, 1);
374 bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), true, errp);
375 if (*errp) {
376 goto fail;
377 }
378
379 if (!flat) {
380 BlockDriverState *backing;
381
382 /*
383 * Use any filtered child here (for backwards compatibility to when
384 * we always took bs->backing, which might be any filtered child).
385 */
386 backing = bdrv_filter_or_cow_bs(bs);
387 if (skip_implicit_filters) {
388 backing = bdrv_skip_implicit_filters(backing);
389 }
390
391 if (backing) {
392 bdrv_query_image_info(backing, &info->backing_image, false,
393 skip_implicit_filters, errp);
394 if (*errp) {
395 goto fail;
396 }
397 }
398 }
399
400 *p_info = info;
401 return;
402
403 fail:
404 assert(*errp);
405 qapi_free_ImageInfo(info);
406 }
407
408 /**
409 * bdrv_query_block_graph_info:
410 * @bs: root node to start from
411 * @p_info: location to store image information
412 * @errp: location to store error information
413 *
414 * Store image information about the graph starting from @bs in @p_info.
415 *
416 * @p_info will be set only on success. On error, store error in @errp.
417 */
418 void bdrv_query_block_graph_info(BlockDriverState *bs,
419 BlockGraphInfo **p_info,
420 bool limits,
421 Error **errp)
422 {
423 ERRP_GUARD();
424 BlockGraphInfo *info;
425 BlockChildInfoList **children_list_tail;
426 BdrvChild *c;
427
428 info = g_new0(BlockGraphInfo, 1);
429 bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), limits, errp);
430 if (*errp) {
431 goto fail;
432 }
433
434 children_list_tail = &info->children;
435
436 QLIST_FOREACH(c, &bs->children, next) {
437 BlockChildInfo *c_info;
438
439 c_info = g_new0(BlockChildInfo, 1);
440 QAPI_LIST_APPEND(children_list_tail, c_info);
441
442 c_info->name = g_strdup(c->name);
443 bdrv_query_block_graph_info(c->bs, &c_info->info, limits, errp);
444 if (*errp) {
445 goto fail;
446 }
447 }
448
449 *p_info = info;
450 return;
451
452 fail:
453 assert(*errp != NULL);
454 qapi_free_BlockGraphInfo(info);
455 }
456
457 /* @p_info will be set only on success. */
458 static void GRAPH_RDLOCK
459 bdrv_query_info(BlockBackend *blk, bool flat, BlockInfo **p_info, Error **errp)
460 {
461 BlockInfo *info = g_malloc0(sizeof(*info));
462 BlockDriverState *bs = blk_bs(blk);
463 char *qdev;
464
465 /* Skip automatically inserted nodes that the user isn't aware of */
466 bs = bdrv_skip_implicit_filters(bs);
467
468 info->device = g_strdup(blk_name(blk));
469 info->type = g_strdup("unknown");
470 info->locked = blk_dev_is_medium_locked(blk);
471 info->removable = blk_dev_has_removable_media(blk);
472
473 qdev = blk_get_attached_dev_id(blk);
474 if (qdev && *qdev) {
475 info->qdev = qdev;
476 } else {
477 g_free(qdev);
478 }
479
480 if (blk_dev_has_tray(blk)) {
481 info->has_tray_open = true;
482 info->tray_open = blk_dev_is_tray_open(blk);
483 }
484
485 if (blk_iostatus_is_enabled(blk)) {
486 info->has_io_status = true;
487 info->io_status = blk_iostatus(blk);
488 }
489
490 if (bs && bs->drv) {
491 info->inserted = bdrv_block_device_info(blk, bs, flat, errp);
492 if (info->inserted == NULL) {
493 goto err;
494 }
495 }
496
497 *p_info = info;
498 return;
499
500 err:
501 qapi_free_BlockInfo(info);
502 }
503
504 static uint64List *uint64_list(uint64_t *list, int size)
505 {
506 int i;
507 uint64List *out_list = NULL;
508 uint64List **tail = &out_list;
509
510 for (i = 0; i < size; i++) {
511 QAPI_LIST_APPEND(tail, list[i]);
512 }
513
514 return out_list;
515 }
516
517 static BlockLatencyHistogramInfo *
518 bdrv_latency_histogram_stats(BlockLatencyHistogram *hist)
519 {
520 BlockLatencyHistogramInfo *info;
521
522 if (!hist->bins) {
523 return NULL;
524 }
525
526 info = g_new0(BlockLatencyHistogramInfo, 1);
527 info->boundaries = uint64_list(hist->boundaries, hist->nbins - 1);
528 info->bins = uint64_list(hist->bins, hist->nbins);
529 return info;
530 }
531
532 static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
533 {
534 BlockAcctStats *stats = blk_get_stats(blk);
535 BlockAcctTimedStats *ts = NULL;
536 BlockLatencyHistogram *hgram;
537
538 qemu_mutex_lock(&stats->lock);
539
540 ds->rd_bytes = stats->nr_bytes[BLOCK_ACCT_READ];
541 ds->wr_bytes = stats->nr_bytes[BLOCK_ACCT_WRITE];
542 ds->zone_append_bytes = stats->nr_bytes[BLOCK_ACCT_ZONE_APPEND];
543 ds->unmap_bytes = stats->nr_bytes[BLOCK_ACCT_UNMAP];
544 ds->rd_operations = stats->nr_ops[BLOCK_ACCT_READ];
545 ds->wr_operations = stats->nr_ops[BLOCK_ACCT_WRITE];
546 ds->zone_append_operations = stats->nr_ops[BLOCK_ACCT_ZONE_APPEND];
547 ds->unmap_operations = stats->nr_ops[BLOCK_ACCT_UNMAP];
548
549 ds->failed_rd_operations = stats->failed_ops[BLOCK_ACCT_READ];
550 ds->failed_wr_operations = stats->failed_ops[BLOCK_ACCT_WRITE];
551 ds->failed_zone_append_operations =
552 stats->failed_ops[BLOCK_ACCT_ZONE_APPEND];
553 ds->failed_flush_operations = stats->failed_ops[BLOCK_ACCT_FLUSH];
554 ds->failed_unmap_operations = stats->failed_ops[BLOCK_ACCT_UNMAP];
555
556 ds->invalid_rd_operations = stats->invalid_ops[BLOCK_ACCT_READ];
557 ds->invalid_wr_operations = stats->invalid_ops[BLOCK_ACCT_WRITE];
558 ds->invalid_zone_append_operations =
559 stats->invalid_ops[BLOCK_ACCT_ZONE_APPEND];
560 ds->invalid_flush_operations =
561 stats->invalid_ops[BLOCK_ACCT_FLUSH];
562 ds->invalid_unmap_operations = stats->invalid_ops[BLOCK_ACCT_UNMAP];
563
564 ds->rd_merged = stats->merged[BLOCK_ACCT_READ];
565 ds->wr_merged = stats->merged[BLOCK_ACCT_WRITE];
566 ds->zone_append_merged = stats->merged[BLOCK_ACCT_ZONE_APPEND];
567 ds->unmap_merged = stats->merged[BLOCK_ACCT_UNMAP];
568 ds->flush_operations = stats->nr_ops[BLOCK_ACCT_FLUSH];
569 ds->wr_total_time_ns = stats->total_time_ns[BLOCK_ACCT_WRITE];
570 ds->zone_append_total_time_ns =
571 stats->total_time_ns[BLOCK_ACCT_ZONE_APPEND];
572 ds->rd_total_time_ns = stats->total_time_ns[BLOCK_ACCT_READ];
573 ds->flush_total_time_ns = stats->total_time_ns[BLOCK_ACCT_FLUSH];
574 ds->unmap_total_time_ns = stats->total_time_ns[BLOCK_ACCT_UNMAP];
575
576 ds->has_idle_time_ns = stats->last_access_time_ns > 0;
577 if (ds->has_idle_time_ns) {
578 ds->idle_time_ns = block_acct_idle_time_ns(stats);
579 }
580
581 ds->account_invalid = stats->account_invalid;
582 ds->account_failed = stats->account_failed;
583
584 while ((ts = block_acct_interval_next(stats, ts))) {
585 BlockDeviceTimedStats *dev_stats = g_malloc0(sizeof(*dev_stats));
586
587 TimedAverage *rd = &ts->latency[BLOCK_ACCT_READ];
588 TimedAverage *wr = &ts->latency[BLOCK_ACCT_WRITE];
589 TimedAverage *zap = &ts->latency[BLOCK_ACCT_ZONE_APPEND];
590 TimedAverage *fl = &ts->latency[BLOCK_ACCT_FLUSH];
591
592 dev_stats->interval_length = ts->interval_length;
593
594 dev_stats->min_rd_latency_ns = timed_average_min(rd);
595 dev_stats->max_rd_latency_ns = timed_average_max(rd);
596 dev_stats->avg_rd_latency_ns = timed_average_avg(rd);
597
598 dev_stats->min_wr_latency_ns = timed_average_min(wr);
599 dev_stats->max_wr_latency_ns = timed_average_max(wr);
600 dev_stats->avg_wr_latency_ns = timed_average_avg(wr);
601
602 dev_stats->min_zone_append_latency_ns = timed_average_min(zap);
603 dev_stats->max_zone_append_latency_ns = timed_average_max(zap);
604 dev_stats->avg_zone_append_latency_ns = timed_average_avg(zap);
605
606 dev_stats->min_flush_latency_ns = timed_average_min(fl);
607 dev_stats->max_flush_latency_ns = timed_average_max(fl);
608 dev_stats->avg_flush_latency_ns = timed_average_avg(fl);
609
610 dev_stats->avg_rd_queue_depth =
611 block_acct_queue_depth(ts, BLOCK_ACCT_READ);
612 dev_stats->avg_wr_queue_depth =
613 block_acct_queue_depth(ts, BLOCK_ACCT_WRITE);
614 dev_stats->avg_zone_append_queue_depth =
615 block_acct_queue_depth(ts, BLOCK_ACCT_ZONE_APPEND);
616
617 QAPI_LIST_PREPEND(ds->timed_stats, dev_stats);
618 }
619
620 hgram = stats->latency_histogram;
621 ds->rd_latency_histogram
622 = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_READ]);
623 ds->wr_latency_histogram
624 = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_WRITE]);
625 ds->zone_append_latency_histogram
626 = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_ZONE_APPEND]);
627 ds->flush_latency_histogram
628 = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_FLUSH]);
629 qemu_mutex_unlock(&stats->lock);
630 }
631
632 static BlockStats * GRAPH_RDLOCK
633 bdrv_query_bds_stats(BlockDriverState *bs, bool blk_level)
634 {
635 BdrvChild *parent_child;
636 BlockDriverState *filter_or_cow_bs;
637 BlockStats *s = NULL;
638
639 s = g_malloc0(sizeof(*s));
640 s->stats = g_malloc0(sizeof(*s->stats));
641
642 if (!bs) {
643 return s;
644 }
645
646 /* Skip automatically inserted nodes that the user isn't aware of in
647 * a BlockBackend-level command. Stay at the exact node for a node-level
648 * command. */
649 if (blk_level) {
650 bs = bdrv_skip_implicit_filters(bs);
651 }
652
653 if (bdrv_get_node_name(bs)[0]) {
654 s->node_name = g_strdup(bdrv_get_node_name(bs));
655 }
656
657 s->stats->wr_highest_offset = qatomic_read(&bs->wr_highest_offset);
658
659 s->driver_specific = bdrv_get_specific_stats(bs);
660
661 parent_child = bdrv_primary_child(bs);
662 if (!parent_child ||
663 !(parent_child->role & (BDRV_CHILD_DATA | BDRV_CHILD_FILTERED)))
664 {
665 BdrvChild *c;
666
667 /*
668 * Look for a unique data-storing child. We do not need to look for
669 * filtered children, as there would be only one and it would have been
670 * the primary child.
671 */
672 parent_child = NULL;
673 QLIST_FOREACH(c, &bs->children, next) {
674 if (c->role & BDRV_CHILD_DATA) {
675 if (parent_child) {
676 /*
677 * There are multiple data-storing children and we cannot
678 * choose between them.
679 */
680 parent_child = NULL;
681 break;
682 }
683 parent_child = c;
684 }
685 }
686 }
687 if (parent_child) {
688 s->parent = bdrv_query_bds_stats(parent_child->bs, blk_level);
689 }
690
691 filter_or_cow_bs = bdrv_filter_or_cow_bs(bs);
692 if (blk_level && filter_or_cow_bs) {
693 /*
694 * Put any filtered or COW child here (for backwards
695 * compatibility to when we put bs0->backing here, which might
696 * be either)
697 */
698 s->backing = bdrv_query_bds_stats(filter_or_cow_bs, blk_level);
699 }
700
701 return s;
702 }
703
704 BlockInfoList *qmp_query_block(bool has_flat, bool flat, Error **errp)
705 {
706 BlockInfoList *head = NULL, **p_next = &head;
707 BlockBackend *blk;
708 Error *local_err = NULL;
709
710 GRAPH_RDLOCK_GUARD_MAINLOOP();
711
712 for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
713 BlockInfoList *info;
714
715 if (!*blk_name(blk) && !blk_get_attached_dev(blk)) {
716 continue;
717 }
718
719 info = g_malloc0(sizeof(*info));
720 bdrv_query_info(blk, flat, &info->value, &local_err);
721 if (local_err) {
722 error_propagate(errp, local_err);
723 g_free(info);
724 qapi_free_BlockInfoList(head);
725 return NULL;
726 }
727
728 *p_next = info;
729 p_next = &info->next;
730 }
731
732 return head;
733 }
734
735 BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
736 bool query_nodes,
737 Error **errp)
738 {
739 BlockStatsList *head = NULL, **tail = &head;
740 BlockBackend *blk;
741 BlockDriverState *bs;
742
743 GRAPH_RDLOCK_GUARD_MAINLOOP();
744
745 /* Just to be safe if query_nodes is not always initialized */
746 if (has_query_nodes && query_nodes) {
747 for (bs = bdrv_next_node(NULL); bs; bs = bdrv_next_node(bs)) {
748 QAPI_LIST_APPEND(tail, bdrv_query_bds_stats(bs, false));
749 }
750 } else {
751 for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
752 BlockStats *s;
753 char *qdev;
754
755 if (!*blk_name(blk) && !blk_get_attached_dev(blk)) {
756 continue;
757 }
758
759 s = bdrv_query_bds_stats(blk_bs(blk), true);
760 s->device = g_strdup(blk_name(blk));
761
762 qdev = blk_get_attached_dev_id(blk);
763 if (qdev && *qdev) {
764 s->qdev = qdev;
765 } else {
766 g_free(qdev);
767 }
768
769 bdrv_query_blk_stats(s->stats, blk);
770
771 QAPI_LIST_APPEND(tail, s);
772 }
773 }
774
775 return head;
776 }
777
778 void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
779 {
780 char clock_buf[128];
781 char icount_buf[128] = {0};
782 int64_t secs;
783 char *sizing = NULL;
784
785 if (!sn) {
786 qemu_printf("%-7s %-16s %8s %19s %15s %10s",
787 "ID", "TAG", "VM_SIZE", "DATE", "VM_CLOCK", "ICOUNT");
788 } else {
789 g_autoptr(GDateTime) date = g_date_time_new_from_unix_local(sn->date_sec);
790 g_autofree char *date_buf = g_date_time_format(date, "%Y-%m-%d %H:%M:%S");
791
792 secs = sn->vm_clock_nsec / 1000000000;
793 snprintf(clock_buf, sizeof(clock_buf),
794 "%04d:%02d:%02d.%03d",
795 (int)(secs / 3600),
796 (int)((secs / 60) % 60),
797 (int)(secs % 60),
798 (int)((sn->vm_clock_nsec / 1000000) % 1000));
799 sizing = size_to_str(sn->vm_state_size);
800 if (sn->icount != -1ULL) {
801 snprintf(icount_buf, sizeof(icount_buf),
802 "%"PRId64, sn->icount);
803 } else {
804 snprintf(icount_buf, sizeof(icount_buf), "--");
805 }
806 qemu_printf("%-7s %-16s %8s %19s %15s %10s",
807 sn->id_str, sn->name,
808 sizing,
809 date_buf,
810 clock_buf,
811 icount_buf);
812 }
813 g_free(sizing);
814 }
815
816 static void dump_qdict(int indentation, QDict *dict);
817 static void dump_qlist(int indentation, QList *list);
818
819 static void dump_qobject(int comp_indent, QObject *obj)
820 {
821 switch (qobject_type(obj)) {
822 case QTYPE_QNUM: {
823 QNum *value = qobject_to(QNum, obj);
824 char *tmp = qnum_to_string(value);
825 qemu_printf("%s", tmp);
826 g_free(tmp);
827 break;
828 }
829 case QTYPE_QSTRING: {
830 QString *value = qobject_to(QString, obj);
831 qemu_printf("%s", qstring_get_str(value));
832 break;
833 }
834 case QTYPE_QDICT: {
835 QDict *value = qobject_to(QDict, obj);
836 dump_qdict(comp_indent, value);
837 break;
838 }
839 case QTYPE_QLIST: {
840 QList *value = qobject_to(QList, obj);
841 dump_qlist(comp_indent, value);
842 break;
843 }
844 case QTYPE_QBOOL: {
845 QBool *value = qobject_to(QBool, obj);
846 qemu_printf("%s", qbool_get_bool(value) ? "true" : "false");
847 break;
848 }
849 default:
850 abort();
851 }
852 }
853
854 static void dump_qlist(int indentation, QList *list)
855 {
856 const QListEntry *entry;
857 int i = 0;
858
859 for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) {
860 QType type = qobject_type(entry->value);
861 bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
862 qemu_printf("%*s[%i]:%c", indentation * 4, "", i,
863 composite ? '\n' : ' ');
864 dump_qobject(indentation + 1, entry->value);
865 if (!composite) {
866 qemu_printf("\n");
867 }
868 }
869 }
870
871 static void dump_qdict(int indentation, QDict *dict)
872 {
873 const QDictEntry *entry;
874
875 for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) {
876 QType type = qobject_type(entry->value);
877 bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
878 char *key = g_malloc(strlen(entry->key) + 1);
879 int i;
880
881 /* replace dashes with spaces in key (variable) names */
882 for (i = 0; entry->key[i]; i++) {
883 key[i] = entry->key[i] == '-' ? ' ' : entry->key[i];
884 }
885 key[i] = 0;
886 qemu_printf("%*s%s:%c", indentation * 4, "", key,
887 composite ? '\n' : ' ');
888 dump_qobject(indentation + 1, entry->value);
889 if (!composite) {
890 qemu_printf("\n");
891 }
892 g_free(key);
893 }
894 }
895
896 /*
897 * Return whether dumping the given QObject with dump_qobject() would
898 * yield an empty dump, i.e. not print anything.
899 */
900 static bool qobject_is_empty_dump(const QObject *obj)
901 {
902 switch (qobject_type(obj)) {
903 case QTYPE_QNUM:
904 case QTYPE_QSTRING:
905 case QTYPE_QBOOL:
906 return false;
907
908 case QTYPE_QDICT:
909 return qdict_size(qobject_to(QDict, obj)) == 0;
910
911 case QTYPE_QLIST:
912 return qlist_empty(qobject_to(QList, obj));
913
914 default:
915 abort();
916 }
917 }
918
919 /**
920 * Dumps the given ImageInfoSpecific object in a human-readable form,
921 * prepending an optional prefix if the dump is not empty.
922 */
923 void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
924 const char *prefix,
925 int indentation)
926 {
927 QObject *obj, *data;
928 Visitor *v = qobject_output_visitor_new(&obj);
929
930 visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
931 visit_complete(v, &obj);
932 data = qdict_get(qobject_to(QDict, obj), "data");
933 if (!qobject_is_empty_dump(data)) {
934 if (prefix) {
935 qemu_printf("%*s%s", indentation * 4, "", prefix);
936 }
937 dump_qobject(indentation + 1, data);
938 }
939 qobject_unref(obj);
940 visit_free(v);
941 }
942
943 /**
944 * Dumps the given BlockLimitsInfo object in a human-readable form,
945 * prepending an optional prefix if the dump is not empty.
946 */
947 static void bdrv_image_info_limits_dump(BlockLimitsInfo *limits,
948 const char *prefix,
949 int indentation)
950 {
951 QObject *obj;
952 Visitor *v = qobject_output_visitor_new(&obj);
953
954 visit_type_BlockLimitsInfo(v, NULL, &limits, &error_abort);
955 visit_complete(v, &obj);
956 if (!qobject_is_empty_dump(obj)) {
957 if (prefix) {
958 qemu_printf("%*s%s", indentation * 4, "", prefix);
959 }
960 dump_qobject(indentation + 1, obj);
961 }
962 qobject_unref(obj);
963 visit_free(v);
964 }
965
966 /**
967 * Print the given @info object in human-readable form. Every field is indented
968 * using the given @indentation (four spaces per indentation level).
969 *
970 * When using this to print a whole block graph, @protocol can be set to true to
971 * signify that the given information is associated with a protocol node, i.e.
972 * just data storage for an image, such that the data it presents is not really
973 * a full VM disk. If so, several fields change name: For example, "virtual
974 * size" is printed as "file length".
975 * (Consider a qcow2 image, which is represented by a qcow2 node and a file
976 * node. Printing a "virtual size" for the file node does not make sense,
977 * because without the qcow2 node, it is not really a guest disk, so it does not
978 * have a "virtual size". Therefore, we call it "file length" instead.)
979 *
980 * @protocol is ignored when @indentation is 0, because we take that to mean
981 * that the associated node is the root node in the queried block graph, and
982 * thus is always to be interpreted as a standalone guest disk.
983 */
984 void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol)
985 {
986 char *size_buf, *dsize_buf;
987 g_autofree char *ind_s = g_strdup_printf("%*s", indentation * 4, "");
988
989 if (indentation == 0) {
990 /* Top level, consider this a normal image */
991 protocol = false;
992 }
993
994 if (!info->has_actual_size) {
995 dsize_buf = g_strdup("unavailable");
996 } else {
997 dsize_buf = size_to_str(info->actual_size);
998 }
999 size_buf = size_to_str(info->virtual_size);
1000 qemu_printf("%s%s: %s\n"
1001 "%s%s: %s\n"
1002 "%s%s: %s (%" PRId64 " bytes)\n"
1003 "%sdisk size: %s\n",
1004 ind_s, protocol ? "filename" : "image", info->filename,
1005 ind_s, protocol ? "protocol type" : "file format",
1006 info->format,
1007 ind_s, protocol ? "file length" : "virtual size",
1008 size_buf, info->virtual_size,
1009 ind_s, dsize_buf);
1010 g_free(size_buf);
1011 g_free(dsize_buf);
1012
1013 if (info->has_encrypted && info->encrypted) {
1014 qemu_printf("%sencrypted: yes\n", ind_s);
1015 }
1016
1017 if (info->has_cluster_size) {
1018 qemu_printf("%scluster_size: %" PRId64 "\n",
1019 ind_s, info->cluster_size);
1020 }
1021
1022 if (info->has_dirty_flag && info->dirty_flag) {
1023 qemu_printf("%scleanly shut down: no\n", ind_s);
1024 }
1025
1026 if (info->backing_filename) {
1027 qemu_printf("%sbacking file: %s", ind_s, info->backing_filename);
1028 if (!info->full_backing_filename) {
1029 qemu_printf(" (cannot determine actual path)");
1030 } else if (strcmp(info->backing_filename,
1031 info->full_backing_filename) != 0) {
1032 qemu_printf(" (actual path: %s)", info->full_backing_filename);
1033 }
1034 qemu_printf("\n");
1035 if (info->backing_filename_format) {
1036 qemu_printf("%sbacking file format: %s\n",
1037 ind_s, info->backing_filename_format);
1038 }
1039 }
1040
1041 if (info->limits) {
1042 bdrv_image_info_limits_dump(info->limits,
1043 "Block limits:\n",
1044 indentation);
1045 }
1046
1047 if (info->has_snapshots) {
1048 SnapshotInfoList *elem;
1049
1050 qemu_printf("%sSnapshot list:\n", ind_s);
1051 qemu_printf("%s", ind_s);
1052 bdrv_snapshot_dump(NULL);
1053 qemu_printf("\n");
1054
1055 /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but
1056 * we convert to the block layer's native QEMUSnapshotInfo for now.
1057 */
1058 for (elem = info->snapshots; elem; elem = elem->next) {
1059 QEMUSnapshotInfo sn = {
1060 .vm_state_size = elem->value->vm_state_size,
1061 .date_sec = elem->value->date_sec,
1062 .date_nsec = elem->value->date_nsec,
1063 .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL +
1064 elem->value->vm_clock_nsec,
1065 .icount = elem->value->has_icount ?
1066 elem->value->icount : -1ULL,
1067 };
1068
1069 pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
1070 pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
1071 qemu_printf("%s", ind_s);
1072 bdrv_snapshot_dump(&sn);
1073 qemu_printf("\n");
1074 }
1075 }
1076
1077 if (info->format_specific) {
1078 bdrv_image_info_specific_dump(info->format_specific,
1079 "Format specific information:\n",
1080 indentation);
1081 }
1082 }