Statistics
| Branch: | Revision:

root / hmp.c @ ee77854f

History | View | Annotate | Download (44.1 kB)

1
/*
2
 * Human Monitor Interface
3
 *
4
 * Copyright IBM, Corp. 2011
5
 *
6
 * Authors:
7
 *  Anthony Liguori   <aliguori@us.ibm.com>
8
 *
9
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10
 * the COPYING file in the top-level directory.
11
 *
12
 * Contributions after 2012-01-13 are licensed under the terms of the
13
 * GNU GPL, version 2 or (at your option) any later version.
14
 */
15

    
16
#include "hmp.h"
17
#include "net/net.h"
18
#include "sysemu/char.h"
19
#include "qemu/option.h"
20
#include "qemu/timer.h"
21
#include "qmp-commands.h"
22
#include "qemu/sockets.h"
23
#include "monitor/monitor.h"
24
#include "ui/console.h"
25
#include "block/qapi.h"
26
#include "qemu-io.h"
27

    
28
static void hmp_handle_error(Monitor *mon, Error **errp)
29
{
30
    if (error_is_set(errp)) {
31
        monitor_printf(mon, "%s\n", error_get_pretty(*errp));
32
        error_free(*errp);
33
    }
34
}
35

    
36
void hmp_info_name(Monitor *mon, const QDict *qdict)
37
{
38
    NameInfo *info;
39

    
40
    info = qmp_query_name(NULL);
41
    if (info->has_name) {
42
        monitor_printf(mon, "%s\n", info->name);
43
    }
44
    qapi_free_NameInfo(info);
45
}
46

    
47
void hmp_info_version(Monitor *mon, const QDict *qdict)
48
{
49
    VersionInfo *info;
50

    
51
    info = qmp_query_version(NULL);
52

    
53
    monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
54
                   info->qemu.major, info->qemu.minor, info->qemu.micro,
55
                   info->package);
56

    
57
    qapi_free_VersionInfo(info);
58
}
59

    
60
void hmp_info_kvm(Monitor *mon, const QDict *qdict)
61
{
62
    KvmInfo *info;
63

    
64
    info = qmp_query_kvm(NULL);
65
    monitor_printf(mon, "kvm support: ");
66
    if (info->present) {
67
        monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled");
68
    } else {
69
        monitor_printf(mon, "not compiled\n");
70
    }
71

    
72
    qapi_free_KvmInfo(info);
73
}
74

    
75
void hmp_info_status(Monitor *mon, const QDict *qdict)
76
{
77
    StatusInfo *info;
78

    
79
    info = qmp_query_status(NULL);
80

    
81
    monitor_printf(mon, "VM status: %s%s",
82
                   info->running ? "running" : "paused",
83
                   info->singlestep ? " (single step mode)" : "");
84

    
85
    if (!info->running && info->status != RUN_STATE_PAUSED) {
86
        monitor_printf(mon, " (%s)", RunState_lookup[info->status]);
87
    }
88

    
89
    monitor_printf(mon, "\n");
90

    
91
    qapi_free_StatusInfo(info);
92
}
93

    
94
void hmp_info_uuid(Monitor *mon, const QDict *qdict)
95
{
96
    UuidInfo *info;
97

    
98
    info = qmp_query_uuid(NULL);
99
    monitor_printf(mon, "%s\n", info->UUID);
100
    qapi_free_UuidInfo(info);
101
}
102

    
103
void hmp_info_chardev(Monitor *mon, const QDict *qdict)
104
{
105
    ChardevInfoList *char_info, *info;
106

    
107
    char_info = qmp_query_chardev(NULL);
108
    for (info = char_info; info; info = info->next) {
109
        monitor_printf(mon, "%s: filename=%s\n", info->value->label,
110
                                                 info->value->filename);
111
    }
112

    
113
    qapi_free_ChardevInfoList(char_info);
114
}
115

    
116
void hmp_info_mice(Monitor *mon, const QDict *qdict)
117
{
118
    MouseInfoList *mice_list, *mouse;
119

    
120
    mice_list = qmp_query_mice(NULL);
121
    if (!mice_list) {
122
        monitor_printf(mon, "No mouse devices connected\n");
123
        return;
124
    }
125

    
126
    for (mouse = mice_list; mouse; mouse = mouse->next) {
127
        monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
128
                       mouse->value->current ? '*' : ' ',
129
                       mouse->value->index, mouse->value->name,
130
                       mouse->value->absolute ? " (absolute)" : "");
131
    }
132

    
133
    qapi_free_MouseInfoList(mice_list);
134
}
135

    
136
void hmp_info_migrate(Monitor *mon, const QDict *qdict)
137
{
138
    MigrationInfo *info;
139
    MigrationCapabilityStatusList *caps, *cap;
140

    
141
    info = qmp_query_migrate(NULL);
142
    caps = qmp_query_migrate_capabilities(NULL);
143

    
144
    /* do not display parameters during setup */
145
    if (info->has_status && caps) {
146
        monitor_printf(mon, "capabilities: ");
147
        for (cap = caps; cap; cap = cap->next) {
148
            monitor_printf(mon, "%s: %s ",
149
                           MigrationCapability_lookup[cap->value->capability],
150
                           cap->value->state ? "on" : "off");
151
        }
152
        monitor_printf(mon, "\n");
153
    }
154

    
155
    if (info->has_status) {
156
        monitor_printf(mon, "Migration status: %s\n", info->status);
157
        monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
158
                       info->total_time);
159
        if (info->has_expected_downtime) {
160
            monitor_printf(mon, "expected downtime: %" PRIu64 " milliseconds\n",
161
                           info->expected_downtime);
162
        }
163
        if (info->has_downtime) {
164
            monitor_printf(mon, "downtime: %" PRIu64 " milliseconds\n",
165
                           info->downtime);
166
        }
167
        if (info->has_setup_time) {
168
            monitor_printf(mon, "setup: %" PRIu64 " milliseconds\n",
169
                           info->setup_time);
170
        }
171
    }
172

    
173
    if (info->has_ram) {
174
        monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n",
175
                       info->ram->transferred >> 10);
176
        monitor_printf(mon, "throughput: %0.2f mbps\n",
177
                       info->ram->mbps);
178
        monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n",
179
                       info->ram->remaining >> 10);
180
        monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n",
181
                       info->ram->total >> 10);
182
        monitor_printf(mon, "duplicate: %" PRIu64 " pages\n",
183
                       info->ram->duplicate);
184
        monitor_printf(mon, "skipped: %" PRIu64 " pages\n",
185
                       info->ram->skipped);
186
        monitor_printf(mon, "normal: %" PRIu64 " pages\n",
187
                       info->ram->normal);
188
        monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
189
                       info->ram->normal_bytes >> 10);
190
        if (info->ram->dirty_pages_rate) {
191
            monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
192
                           info->ram->dirty_pages_rate);
193
        }
194
    }
195

    
196
    if (info->has_disk) {
197
        monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n",
198
                       info->disk->transferred >> 10);
199
        monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n",
200
                       info->disk->remaining >> 10);
201
        monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n",
202
                       info->disk->total >> 10);
203
    }
204

    
205
    if (info->has_xbzrle_cache) {
206
        monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
207
                       info->xbzrle_cache->cache_size);
208
        monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
209
                       info->xbzrle_cache->bytes >> 10);
210
        monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
211
                       info->xbzrle_cache->pages);
212
        monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
213
                       info->xbzrle_cache->cache_miss);
214
        monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n",
215
                       info->xbzrle_cache->overflow);
216
    }
217

    
218
    qapi_free_MigrationInfo(info);
219
    qapi_free_MigrationCapabilityStatusList(caps);
220
}
221

    
222
void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
223
{
224
    MigrationCapabilityStatusList *caps, *cap;
225

    
226
    caps = qmp_query_migrate_capabilities(NULL);
227

    
228
    if (caps) {
229
        monitor_printf(mon, "capabilities: ");
230
        for (cap = caps; cap; cap = cap->next) {
231
            monitor_printf(mon, "%s: %s ",
232
                           MigrationCapability_lookup[cap->value->capability],
233
                           cap->value->state ? "on" : "off");
234
        }
235
        monitor_printf(mon, "\n");
236
    }
237

    
238
    qapi_free_MigrationCapabilityStatusList(caps);
239
}
240

    
241
void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
242
{
243
    monitor_printf(mon, "xbzrel cache size: %" PRId64 " kbytes\n",
244
                   qmp_query_migrate_cache_size(NULL) >> 10);
245
}
246

    
247
void hmp_info_cpus(Monitor *mon, const QDict *qdict)
248
{
249
    CpuInfoList *cpu_list, *cpu;
250

    
251
    cpu_list = qmp_query_cpus(NULL);
252

    
253
    for (cpu = cpu_list; cpu; cpu = cpu->next) {
254
        int active = ' ';
255

    
256
        if (cpu->value->CPU == monitor_get_cpu_index()) {
257
            active = '*';
258
        }
259

    
260
        monitor_printf(mon, "%c CPU #%" PRId64 ":", active, cpu->value->CPU);
261

    
262
        if (cpu->value->has_pc) {
263
            monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->pc);
264
        }
265
        if (cpu->value->has_nip) {
266
            monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->nip);
267
        }
268
        if (cpu->value->has_npc) {
269
            monitor_printf(mon, " npc=0x%016" PRIx64, cpu->value->npc);
270
        }
271
        if (cpu->value->has_PC) {
272
            monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->PC);
273
        }
274

    
275
        if (cpu->value->halted) {
276
            monitor_printf(mon, " (halted)");
277
        }
278

    
279
        monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id);
280
    }
281

    
282
    qapi_free_CpuInfoList(cpu_list);
283
}
284

    
285
void hmp_info_block(Monitor *mon, const QDict *qdict)
286
{
287
    BlockInfoList *block_list, *info;
288
    ImageInfo *image_info;
289
    const char *device = qdict_get_try_str(qdict, "device");
290
    bool verbose = qdict_get_try_bool(qdict, "verbose", 0);
291

    
292
    block_list = qmp_query_block(NULL);
293

    
294
    for (info = block_list; info; info = info->next) {
295
        if (device && strcmp(device, info->value->device)) {
296
            continue;
297
        }
298

    
299
        if (info != block_list) {
300
            monitor_printf(mon, "\n");
301
        }
302

    
303
        monitor_printf(mon, "%s", info->value->device);
304
        if (info->value->has_inserted) {
305
            monitor_printf(mon, ": %s (%s%s%s)\n",
306
                           info->value->inserted->file,
307
                           info->value->inserted->drv,
308
                           info->value->inserted->ro ? ", read-only" : "",
309
                           info->value->inserted->encrypted ? ", encrypted" : "");
310
        } else {
311
            monitor_printf(mon, ": [not inserted]\n");
312
        }
313

    
314
        if (info->value->has_io_status && info->value->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
315
            monitor_printf(mon, "    I/O status:       %s\n",
316
                           BlockDeviceIoStatus_lookup[info->value->io_status]);
317
        }
318

    
319
        if (info->value->removable) {
320
            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",
321
                           info->value->locked ? "" : "not ",
322
                           info->value->tray_open ? "open" : "closed");
323
        }
324

    
325

    
326
        if (!info->value->has_inserted) {
327
            continue;
328
        }
329

    
330
        if (info->value->inserted->has_backing_file) {
331
            monitor_printf(mon,
332
                           "    Backing file:     %s "
333
                           "(chain depth: %" PRId64 ")\n",
334
                           info->value->inserted->backing_file,
335
                           info->value->inserted->backing_file_depth);
336
        }
337

    
338
        if (info->value->inserted->bps
339
            || info->value->inserted->bps_rd
340
            || info->value->inserted->bps_wr
341
            || info->value->inserted->iops
342
            || info->value->inserted->iops_rd
343
            || info->value->inserted->iops_wr)
344
        {
345
            monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
346
                            " bps_rd=%" PRId64  " bps_wr=%" PRId64
347
                            " iops=%" PRId64 " iops_rd=%" PRId64
348
                            " iops_wr=%" PRId64 "\n",
349
                            info->value->inserted->bps,
350
                            info->value->inserted->bps_rd,
351
                            info->value->inserted->bps_wr,
352
                            info->value->inserted->iops,
353
                            info->value->inserted->iops_rd,
354
                            info->value->inserted->iops_wr);
355
        }
356

    
357
        if (verbose) {
358
            monitor_printf(mon, "\nImages:\n");
359
            image_info = info->value->inserted->image;
360
            while (1) {
361
                    bdrv_image_info_dump((fprintf_function)monitor_printf,
362
                                         mon, image_info);
363
                if (image_info->has_backing_image) {
364
                    image_info = image_info->backing_image;
365
                } else {
366
                    break;
367
                }
368
            }
369
        }
370
    }
371

    
372
    qapi_free_BlockInfoList(block_list);
373
}
374

    
375
void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
376
{
377
    BlockStatsList *stats_list, *stats;
378

    
379
    stats_list = qmp_query_blockstats(NULL);
380

    
381
    for (stats = stats_list; stats; stats = stats->next) {
382
        if (!stats->value->has_device) {
383
            continue;
384
        }
385

    
386
        monitor_printf(mon, "%s:", stats->value->device);
387
        monitor_printf(mon, " rd_bytes=%" PRId64
388
                       " wr_bytes=%" PRId64
389
                       " rd_operations=%" PRId64
390
                       " wr_operations=%" PRId64
391
                       " flush_operations=%" PRId64
392
                       " wr_total_time_ns=%" PRId64
393
                       " rd_total_time_ns=%" PRId64
394
                       " flush_total_time_ns=%" PRId64
395
                       "\n",
396
                       stats->value->stats->rd_bytes,
397
                       stats->value->stats->wr_bytes,
398
                       stats->value->stats->rd_operations,
399
                       stats->value->stats->wr_operations,
400
                       stats->value->stats->flush_operations,
401
                       stats->value->stats->wr_total_time_ns,
402
                       stats->value->stats->rd_total_time_ns,
403
                       stats->value->stats->flush_total_time_ns);
404
    }
405

    
406
    qapi_free_BlockStatsList(stats_list);
407
}
408

    
409
void hmp_info_vnc(Monitor *mon, const QDict *qdict)
410
{
411
    VncInfo *info;
412
    Error *err = NULL;
413
    VncClientInfoList *client;
414

    
415
    info = qmp_query_vnc(&err);
416
    if (err) {
417
        monitor_printf(mon, "%s\n", error_get_pretty(err));
418
        error_free(err);
419
        return;
420
    }
421

    
422
    if (!info->enabled) {
423
        monitor_printf(mon, "Server: disabled\n");
424
        goto out;
425
    }
426

    
427
    monitor_printf(mon, "Server:\n");
428
    if (info->has_host && info->has_service) {
429
        monitor_printf(mon, "     address: %s:%s\n", info->host, info->service);
430
    }
431
    if (info->has_auth) {
432
        monitor_printf(mon, "        auth: %s\n", info->auth);
433
    }
434

    
435
    if (!info->has_clients || info->clients == NULL) {
436
        monitor_printf(mon, "Client: none\n");
437
    } else {
438
        for (client = info->clients; client; client = client->next) {
439
            monitor_printf(mon, "Client:\n");
440
            monitor_printf(mon, "     address: %s:%s\n",
441
                           client->value->host, client->value->service);
442
            monitor_printf(mon, "  x509_dname: %s\n",
443
                           client->value->x509_dname ?
444
                           client->value->x509_dname : "none");
445
            monitor_printf(mon, "    username: %s\n",
446
                           client->value->has_sasl_username ?
447
                           client->value->sasl_username : "none");
448
        }
449
    }
450

    
451
out:
452
    qapi_free_VncInfo(info);
453
}
454

    
455
void hmp_info_spice(Monitor *mon, const QDict *qdict)
456
{
457
    SpiceChannelList *chan;
458
    SpiceInfo *info;
459

    
460
    info = qmp_query_spice(NULL);
461

    
462
    if (!info->enabled) {
463
        monitor_printf(mon, "Server: disabled\n");
464
        goto out;
465
    }
466

    
467
    monitor_printf(mon, "Server:\n");
468
    if (info->has_port) {
469
        monitor_printf(mon, "     address: %s:%" PRId64 "\n",
470
                       info->host, info->port);
471
    }
472
    if (info->has_tls_port) {
473
        monitor_printf(mon, "     address: %s:%" PRId64 " [tls]\n",
474
                       info->host, info->tls_port);
475
    }
476
    monitor_printf(mon, "    migrated: %s\n",
477
                   info->migrated ? "true" : "false");
478
    monitor_printf(mon, "        auth: %s\n", info->auth);
479
    monitor_printf(mon, "    compiled: %s\n", info->compiled_version);
480
    monitor_printf(mon, "  mouse-mode: %s\n",
481
                   SpiceQueryMouseMode_lookup[info->mouse_mode]);
482

    
483
    if (!info->has_channels || info->channels == NULL) {
484
        monitor_printf(mon, "Channels: none\n");
485
    } else {
486
        for (chan = info->channels; chan; chan = chan->next) {
487
            monitor_printf(mon, "Channel:\n");
488
            monitor_printf(mon, "     address: %s:%s%s\n",
489
                           chan->value->host, chan->value->port,
490
                           chan->value->tls ? " [tls]" : "");
491
            monitor_printf(mon, "     session: %" PRId64 "\n",
492
                           chan->value->connection_id);
493
            monitor_printf(mon, "     channel: %" PRId64 ":%" PRId64 "\n",
494
                           chan->value->channel_type, chan->value->channel_id);
495
        }
496
    }
497

    
498
out:
499
    qapi_free_SpiceInfo(info);
500
}
501

    
502
void hmp_info_balloon(Monitor *mon, const QDict *qdict)
503
{
504
    BalloonInfo *info;
505
    Error *err = NULL;
506

    
507
    info = qmp_query_balloon(&err);
508
    if (err) {
509
        monitor_printf(mon, "%s\n", error_get_pretty(err));
510
        error_free(err);
511
        return;
512
    }
513

    
514
    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
515

    
516
    qapi_free_BalloonInfo(info);
517
}
518

    
519
static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
520
{
521
    PciMemoryRegionList *region;
522

    
523
    monitor_printf(mon, "  Bus %2" PRId64 ", ", dev->bus);
524
    monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n",
525
                   dev->slot, dev->function);
526
    monitor_printf(mon, "    ");
527

    
528
    if (dev->class_info.has_desc) {
529
        monitor_printf(mon, "%s", dev->class_info.desc);
530
    } else {
531
        monitor_printf(mon, "Class %04" PRId64, dev->class_info.class);
532
    }
533

    
534
    monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
535
                   dev->id.vendor, dev->id.device);
536

    
537
    if (dev->has_irq) {
538
        monitor_printf(mon, "      IRQ %" PRId64 ".\n", dev->irq);
539
    }
540

    
541
    if (dev->has_pci_bridge) {
542
        monitor_printf(mon, "      BUS %" PRId64 ".\n",
543
                       dev->pci_bridge->bus.number);
544
        monitor_printf(mon, "      secondary bus %" PRId64 ".\n",
545
                       dev->pci_bridge->bus.secondary);
546
        monitor_printf(mon, "      subordinate bus %" PRId64 ".\n",
547
                       dev->pci_bridge->bus.subordinate);
548

    
549
        monitor_printf(mon, "      IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n",
550
                       dev->pci_bridge->bus.io_range->base,
551
                       dev->pci_bridge->bus.io_range->limit);
552

    
553
        monitor_printf(mon,
554
                       "      memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n",
555
                       dev->pci_bridge->bus.memory_range->base,
556
                       dev->pci_bridge->bus.memory_range->limit);
557

    
558
        monitor_printf(mon, "      prefetchable memory range "
559
                       "[0x%08"PRIx64", 0x%08"PRIx64"]\n",
560
                       dev->pci_bridge->bus.prefetchable_range->base,
561
                       dev->pci_bridge->bus.prefetchable_range->limit);
562
    }
563

    
564
    for (region = dev->regions; region; region = region->next) {
565
        uint64_t addr, size;
566

    
567
        addr = region->value->address;
568
        size = region->value->size;
569

    
570
        monitor_printf(mon, "      BAR%" PRId64 ": ", region->value->bar);
571

    
572
        if (!strcmp(region->value->type, "io")) {
573
            monitor_printf(mon, "I/O at 0x%04" PRIx64
574
                                " [0x%04" PRIx64 "].\n",
575
                           addr, addr + size - 1);
576
        } else {
577
            monitor_printf(mon, "%d bit%s memory at 0x%08" PRIx64
578
                               " [0x%08" PRIx64 "].\n",
579
                           region->value->mem_type_64 ? 64 : 32,
580
                           region->value->prefetch ? " prefetchable" : "",
581
                           addr, addr + size - 1);
582
        }
583
    }
584

    
585
    monitor_printf(mon, "      id \"%s\"\n", dev->qdev_id);
586

    
587
    if (dev->has_pci_bridge) {
588
        if (dev->pci_bridge->has_devices) {
589
            PciDeviceInfoList *cdev;
590
            for (cdev = dev->pci_bridge->devices; cdev; cdev = cdev->next) {
591
                hmp_info_pci_device(mon, cdev->value);
592
            }
593
        }
594
    }
595
}
596

    
597
void hmp_info_pci(Monitor *mon, const QDict *qdict)
598
{
599
    PciInfoList *info_list, *info;
600
    Error *err = NULL;
601

    
602
    info_list = qmp_query_pci(&err);
603
    if (err) {
604
        monitor_printf(mon, "PCI devices not supported\n");
605
        error_free(err);
606
        return;
607
    }
608

    
609
    for (info = info_list; info; info = info->next) {
610
        PciDeviceInfoList *dev;
611

    
612
        for (dev = info->value->devices; dev; dev = dev->next) {
613
            hmp_info_pci_device(mon, dev->value);
614
        }
615
    }
616

    
617
    qapi_free_PciInfoList(info_list);
618
}
619

    
620
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
621
{
622
    BlockJobInfoList *list;
623
    Error *err = NULL;
624

    
625
    list = qmp_query_block_jobs(&err);
626
    assert(!err);
627

    
628
    if (!list) {
629
        monitor_printf(mon, "No active jobs\n");
630
        return;
631
    }
632

    
633
    while (list) {
634
        if (strcmp(list->value->type, "stream") == 0) {
635
            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
636
                           " of %" PRId64 " bytes, speed limit %" PRId64
637
                           " bytes/s\n",
638
                           list->value->device,
639
                           list->value->offset,
640
                           list->value->len,
641
                           list->value->speed);
642
        } else {
643
            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
644
                           " of %" PRId64 " bytes, speed limit %" PRId64
645
                           " bytes/s\n",
646
                           list->value->type,
647
                           list->value->device,
648
                           list->value->offset,
649
                           list->value->len,
650
                           list->value->speed);
651
        }
652
        list = list->next;
653
    }
654
}
655

    
656
void hmp_info_tpm(Monitor *mon, const QDict *qdict)
657
{
658
    TPMInfoList *info_list, *info;
659
    Error *err = NULL;
660
    unsigned int c = 0;
661
    TPMPassthroughOptions *tpo;
662

    
663
    info_list = qmp_query_tpm(&err);
664
    if (err) {
665
        monitor_printf(mon, "TPM device not supported\n");
666
        error_free(err);
667
        return;
668
    }
669

    
670
    if (info_list) {
671
        monitor_printf(mon, "TPM device:\n");
672
    }
673

    
674
    for (info = info_list; info; info = info->next) {
675
        TPMInfo *ti = info->value;
676
        monitor_printf(mon, " tpm%d: model=%s\n",
677
                       c, TpmModel_lookup[ti->model]);
678

    
679
        monitor_printf(mon, "  \\ %s: type=%s",
680
                       ti->id, TpmTypeOptionsKind_lookup[ti->options->kind]);
681

    
682
        switch (ti->options->kind) {
683
        case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:
684
            tpo = ti->options->passthrough;
685
            monitor_printf(mon, "%s%s%s%s",
686
                           tpo->has_path ? ",path=" : "",
687
                           tpo->has_path ? tpo->path : "",
688
                           tpo->has_cancel_path ? ",cancel-path=" : "",
689
                           tpo->has_cancel_path ? tpo->cancel_path : "");
690
            break;
691
        case TPM_TYPE_OPTIONS_KIND_MAX:
692
            break;
693
        }
694
        monitor_printf(mon, "\n");
695
        c++;
696
    }
697
    qapi_free_TPMInfoList(info_list);
698
}
699

    
700
void hmp_quit(Monitor *mon, const QDict *qdict)
701
{
702
    monitor_suspend(mon);
703
    qmp_quit(NULL);
704
}
705

    
706
void hmp_stop(Monitor *mon, const QDict *qdict)
707
{
708
    qmp_stop(NULL);
709
}
710

    
711
void hmp_system_reset(Monitor *mon, const QDict *qdict)
712
{
713
    qmp_system_reset(NULL);
714
}
715

    
716
void hmp_system_powerdown(Monitor *mon, const QDict *qdict)
717
{
718
    qmp_system_powerdown(NULL);
719
}
720

    
721
void hmp_cpu(Monitor *mon, const QDict *qdict)
722
{
723
    int64_t cpu_index;
724

    
725
    /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
726
            use it are converted to the QAPI */
727
    cpu_index = qdict_get_int(qdict, "index");
728
    if (monitor_set_cpu(cpu_index) < 0) {
729
        monitor_printf(mon, "invalid CPU index\n");
730
    }
731
}
732

    
733
void hmp_memsave(Monitor *mon, const QDict *qdict)
734
{
735
    uint32_t size = qdict_get_int(qdict, "size");
736
    const char *filename = qdict_get_str(qdict, "filename");
737
    uint64_t addr = qdict_get_int(qdict, "val");
738
    Error *errp = NULL;
739

    
740
    qmp_memsave(addr, size, filename, true, monitor_get_cpu_index(), &errp);
741
    hmp_handle_error(mon, &errp);
742
}
743

    
744
void hmp_pmemsave(Monitor *mon, const QDict *qdict)
745
{
746
    uint32_t size = qdict_get_int(qdict, "size");
747
    const char *filename = qdict_get_str(qdict, "filename");
748
    uint64_t addr = qdict_get_int(qdict, "val");
749
    Error *errp = NULL;
750

    
751
    qmp_pmemsave(addr, size, filename, &errp);
752
    hmp_handle_error(mon, &errp);
753
}
754

    
755
void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
756
{
757
    const char *chardev = qdict_get_str(qdict, "device");
758
    const char *data = qdict_get_str(qdict, "data");
759
    Error *errp = NULL;
760

    
761
    qmp_ringbuf_write(chardev, data, false, 0, &errp);
762

    
763
    hmp_handle_error(mon, &errp);
764
}
765

    
766
void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
767
{
768
    uint32_t size = qdict_get_int(qdict, "size");
769
    const char *chardev = qdict_get_str(qdict, "device");
770
    char *data;
771
    Error *errp = NULL;
772
    int i;
773

    
774
    data = qmp_ringbuf_read(chardev, size, false, 0, &errp);
775
    if (errp) {
776
        monitor_printf(mon, "%s\n", error_get_pretty(errp));
777
        error_free(errp);
778
        return;
779
    }
780

    
781
    for (i = 0; data[i]; i++) {
782
        unsigned char ch = data[i];
783

    
784
        if (ch == '\\') {
785
            monitor_printf(mon, "\\\\");
786
        } else if ((ch < 0x20 && ch != '\n' && ch != '\t') || ch == 0x7F) {
787
            monitor_printf(mon, "\\u%04X", ch);
788
        } else {
789
            monitor_printf(mon, "%c", ch);
790
        }
791

    
792
    }
793
    monitor_printf(mon, "\n");
794
    g_free(data);
795
}
796

    
797
static void hmp_cont_cb(void *opaque, int err)
798
{
799
    if (!err) {
800
        qmp_cont(NULL);
801
    }
802
}
803

    
804
static bool key_is_missing(const BlockInfo *bdev)
805
{
806
    return (bdev->inserted && bdev->inserted->encryption_key_missing);
807
}
808

    
809
void hmp_cont(Monitor *mon, const QDict *qdict)
810
{
811
    BlockInfoList *bdev_list, *bdev;
812
    Error *errp = NULL;
813

    
814
    bdev_list = qmp_query_block(NULL);
815
    for (bdev = bdev_list; bdev; bdev = bdev->next) {
816
        if (key_is_missing(bdev->value)) {
817
            monitor_read_block_device_key(mon, bdev->value->device,
818
                                          hmp_cont_cb, NULL);
819
            goto out;
820
        }
821
    }
822

    
823
    qmp_cont(&errp);
824
    hmp_handle_error(mon, &errp);
825

    
826
out:
827
    qapi_free_BlockInfoList(bdev_list);
828
}
829

    
830
void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
831
{
832
    qmp_system_wakeup(NULL);
833
}
834

    
835
void hmp_inject_nmi(Monitor *mon, const QDict *qdict)
836
{
837
    Error *errp = NULL;
838

    
839
    qmp_inject_nmi(&errp);
840
    hmp_handle_error(mon, &errp);
841
}
842

    
843
void hmp_set_link(Monitor *mon, const QDict *qdict)
844
{
845
    const char *name = qdict_get_str(qdict, "name");
846
    int up = qdict_get_bool(qdict, "up");
847
    Error *errp = NULL;
848

    
849
    qmp_set_link(name, up, &errp);
850
    hmp_handle_error(mon, &errp);
851
}
852

    
853
void hmp_block_passwd(Monitor *mon, const QDict *qdict)
854
{
855
    const char *device = qdict_get_str(qdict, "device");
856
    const char *password = qdict_get_str(qdict, "password");
857
    Error *errp = NULL;
858

    
859
    qmp_block_passwd(device, password, &errp);
860
    hmp_handle_error(mon, &errp);
861
}
862

    
863
void hmp_balloon(Monitor *mon, const QDict *qdict)
864
{
865
    int64_t value = qdict_get_int(qdict, "value");
866
    Error *errp = NULL;
867

    
868
    qmp_balloon(value, &errp);
869
    if (error_is_set(&errp)) {
870
        monitor_printf(mon, "balloon: %s\n", error_get_pretty(errp));
871
        error_free(errp);
872
    }
873
}
874

    
875
void hmp_block_resize(Monitor *mon, const QDict *qdict)
876
{
877
    const char *device = qdict_get_str(qdict, "device");
878
    int64_t size = qdict_get_int(qdict, "size");
879
    Error *errp = NULL;
880

    
881
    qmp_block_resize(device, size, &errp);
882
    hmp_handle_error(mon, &errp);
883
}
884

    
885
void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
886
{
887
    const char *device = qdict_get_str(qdict, "device");
888
    const char *filename = qdict_get_str(qdict, "target");
889
    const char *format = qdict_get_try_str(qdict, "format");
890
    int reuse = qdict_get_try_bool(qdict, "reuse", 0);
891
    int full = qdict_get_try_bool(qdict, "full", 0);
892
    enum NewImageMode mode;
893
    Error *errp = NULL;
894

    
895
    if (!filename) {
896
        error_set(&errp, QERR_MISSING_PARAMETER, "target");
897
        hmp_handle_error(mon, &errp);
898
        return;
899
    }
900

    
901
    if (reuse) {
902
        mode = NEW_IMAGE_MODE_EXISTING;
903
    } else {
904
        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
905
    }
906

    
907
    qmp_drive_mirror(device, filename, !!format, format,
908
                     full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
909
                     true, mode, false, 0, false, 0, false, 0,
910
                     false, 0, false, 0, &errp);
911
    hmp_handle_error(mon, &errp);
912
}
913

    
914
void hmp_drive_backup(Monitor *mon, const QDict *qdict)
915
{
916
    const char *device = qdict_get_str(qdict, "device");
917
    const char *filename = qdict_get_str(qdict, "target");
918
    const char *format = qdict_get_try_str(qdict, "format");
919
    int reuse = qdict_get_try_bool(qdict, "reuse", 0);
920
    int full = qdict_get_try_bool(qdict, "full", 0);
921
    enum NewImageMode mode;
922
    Error *errp = NULL;
923

    
924
    if (!filename) {
925
        error_set(&errp, QERR_MISSING_PARAMETER, "target");
926
        hmp_handle_error(mon, &errp);
927
        return;
928
    }
929

    
930
    if (reuse) {
931
        mode = NEW_IMAGE_MODE_EXISTING;
932
    } else {
933
        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
934
    }
935

    
936
    qmp_drive_backup(device, filename, !!format, format,
937
                     full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
938
                     true, mode, false, 0, false, 0, false, 0, &errp);
939
    hmp_handle_error(mon, &errp);
940
}
941

    
942
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
943
{
944
    const char *device = qdict_get_str(qdict, "device");
945
    const char *filename = qdict_get_try_str(qdict, "snapshot-file");
946
    const char *format = qdict_get_try_str(qdict, "format");
947
    int reuse = qdict_get_try_bool(qdict, "reuse", 0);
948
    enum NewImageMode mode;
949
    Error *errp = NULL;
950

    
951
    if (!filename) {
952
        /* In the future, if 'snapshot-file' is not specified, the snapshot
953
           will be taken internally. Today it's actually required. */
954
        error_set(&errp, QERR_MISSING_PARAMETER, "snapshot-file");
955
        hmp_handle_error(mon, &errp);
956
        return;
957
    }
958

    
959
    mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
960
    qmp_blockdev_snapshot_sync(device, filename, !!format, format,
961
                               true, mode, &errp);
962
    hmp_handle_error(mon, &errp);
963
}
964

    
965
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
966
{
967
    qmp_migrate_cancel(NULL);
968
}
969

    
970
void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
971
{
972
    double value = qdict_get_double(qdict, "value");
973
    qmp_migrate_set_downtime(value, NULL);
974
}
975

    
976
void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict)
977
{
978
    int64_t value = qdict_get_int(qdict, "value");
979
    Error *err = NULL;
980

    
981
    qmp_migrate_set_cache_size(value, &err);
982
    if (err) {
983
        monitor_printf(mon, "%s\n", error_get_pretty(err));
984
        error_free(err);
985
        return;
986
    }
987
}
988

    
989
void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
990
{
991
    int64_t value = qdict_get_int(qdict, "value");
992
    qmp_migrate_set_speed(value, NULL);
993
}
994

    
995
void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
996
{
997
    const char *cap = qdict_get_str(qdict, "capability");
998
    bool state = qdict_get_bool(qdict, "state");
999
    Error *err = NULL;
1000
    MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
1001
    int i;
1002

    
1003
    for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
1004
        if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
1005
            caps->value = g_malloc0(sizeof(*caps->value));
1006
            caps->value->capability = i;
1007
            caps->value->state = state;
1008
            caps->next = NULL;
1009
            qmp_migrate_set_capabilities(caps, &err);
1010
            break;
1011
        }
1012
    }
1013

    
1014
    if (i == MIGRATION_CAPABILITY_MAX) {
1015
        error_set(&err, QERR_INVALID_PARAMETER, cap);
1016
    }
1017

    
1018
    qapi_free_MigrationCapabilityStatusList(caps);
1019

    
1020
    if (err) {
1021
        monitor_printf(mon, "migrate_set_capability: %s\n",
1022
                       error_get_pretty(err));
1023
        error_free(err);
1024
    }
1025
}
1026

    
1027
void hmp_set_password(Monitor *mon, const QDict *qdict)
1028
{
1029
    const char *protocol  = qdict_get_str(qdict, "protocol");
1030
    const char *password  = qdict_get_str(qdict, "password");
1031
    const char *connected = qdict_get_try_str(qdict, "connected");
1032
    Error *err = NULL;
1033

    
1034
    qmp_set_password(protocol, password, !!connected, connected, &err);
1035
    hmp_handle_error(mon, &err);
1036
}
1037

    
1038
void hmp_expire_password(Monitor *mon, const QDict *qdict)
1039
{
1040
    const char *protocol  = qdict_get_str(qdict, "protocol");
1041
    const char *whenstr = qdict_get_str(qdict, "time");
1042
    Error *err = NULL;
1043

    
1044
    qmp_expire_password(protocol, whenstr, &err);
1045
    hmp_handle_error(mon, &err);
1046
}
1047

    
1048
void hmp_eject(Monitor *mon, const QDict *qdict)
1049
{
1050
    int force = qdict_get_try_bool(qdict, "force", 0);
1051
    const char *device = qdict_get_str(qdict, "device");
1052
    Error *err = NULL;
1053

    
1054
    qmp_eject(device, true, force, &err);
1055
    hmp_handle_error(mon, &err);
1056
}
1057

    
1058
static void hmp_change_read_arg(Monitor *mon, const char *password,
1059
                                void *opaque)
1060
{
1061
    qmp_change_vnc_password(password, NULL);
1062
    monitor_read_command(mon, 1);
1063
}
1064

    
1065
void hmp_change(Monitor *mon, const QDict *qdict)
1066
{
1067
    const char *device = qdict_get_str(qdict, "device");
1068
    const char *target = qdict_get_str(qdict, "target");
1069
    const char *arg = qdict_get_try_str(qdict, "arg");
1070
    Error *err = NULL;
1071

    
1072
    if (strcmp(device, "vnc") == 0 &&
1073
            (strcmp(target, "passwd") == 0 ||
1074
             strcmp(target, "password") == 0)) {
1075
        if (!arg) {
1076
            monitor_read_password(mon, hmp_change_read_arg, NULL);
1077
            return;
1078
        }
1079
    }
1080

    
1081
    qmp_change(device, target, !!arg, arg, &err);
1082
    if (error_is_set(&err) &&
1083
        error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
1084
        error_free(err);
1085
        monitor_read_block_device_key(mon, device, NULL, NULL);
1086
        return;
1087
    }
1088
    hmp_handle_error(mon, &err);
1089
}
1090

    
1091
void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
1092
{
1093
    Error *err = NULL;
1094

    
1095
    qmp_block_set_io_throttle(qdict_get_str(qdict, "device"),
1096
                              qdict_get_int(qdict, "bps"),
1097
                              qdict_get_int(qdict, "bps_rd"),
1098
                              qdict_get_int(qdict, "bps_wr"),
1099
                              qdict_get_int(qdict, "iops"),
1100
                              qdict_get_int(qdict, "iops_rd"),
1101
                              qdict_get_int(qdict, "iops_wr"), &err);
1102
    hmp_handle_error(mon, &err);
1103
}
1104

    
1105
void hmp_block_stream(Monitor *mon, const QDict *qdict)
1106
{
1107
    Error *error = NULL;
1108
    const char *device = qdict_get_str(qdict, "device");
1109
    const char *base = qdict_get_try_str(qdict, "base");
1110
    int64_t speed = qdict_get_try_int(qdict, "speed", 0);
1111

    
1112
    qmp_block_stream(device, base != NULL, base,
1113
                     qdict_haskey(qdict, "speed"), speed,
1114
                     BLOCKDEV_ON_ERROR_REPORT, true, &error);
1115

    
1116
    hmp_handle_error(mon, &error);
1117
}
1118

    
1119
void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
1120
{
1121
    Error *error = NULL;
1122
    const char *device = qdict_get_str(qdict, "device");
1123
    int64_t value = qdict_get_int(qdict, "speed");
1124

    
1125
    qmp_block_job_set_speed(device, value, &error);
1126

    
1127
    hmp_handle_error(mon, &error);
1128
}
1129

    
1130
void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
1131
{
1132
    Error *error = NULL;
1133
    const char *device = qdict_get_str(qdict, "device");
1134
    bool force = qdict_get_try_bool(qdict, "force", 0);
1135

    
1136
    qmp_block_job_cancel(device, true, force, &error);
1137

    
1138
    hmp_handle_error(mon, &error);
1139
}
1140

    
1141
void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
1142
{
1143
    Error *error = NULL;
1144
    const char *device = qdict_get_str(qdict, "device");
1145

    
1146
    qmp_block_job_pause(device, &error);
1147

    
1148
    hmp_handle_error(mon, &error);
1149
}
1150

    
1151
void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
1152
{
1153
    Error *error = NULL;
1154
    const char *device = qdict_get_str(qdict, "device");
1155

    
1156
    qmp_block_job_resume(device, &error);
1157

    
1158
    hmp_handle_error(mon, &error);
1159
}
1160

    
1161
void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
1162
{
1163
    Error *error = NULL;
1164
    const char *device = qdict_get_str(qdict, "device");
1165

    
1166
    qmp_block_job_complete(device, &error);
1167

    
1168
    hmp_handle_error(mon, &error);
1169
}
1170

    
1171
typedef struct MigrationStatus
1172
{
1173
    QEMUTimer *timer;
1174
    Monitor *mon;
1175
    bool is_block_migration;
1176
} MigrationStatus;
1177

    
1178
static void hmp_migrate_status_cb(void *opaque)
1179
{
1180
    MigrationStatus *status = opaque;
1181
    MigrationInfo *info;
1182

    
1183
    info = qmp_query_migrate(NULL);
1184
    if (!info->has_status || strcmp(info->status, "active") == 0) {
1185
        if (info->has_disk) {
1186
            int progress;
1187

    
1188
            if (info->disk->remaining) {
1189
                progress = info->disk->transferred * 100 / info->disk->total;
1190
            } else {
1191
                progress = 100;
1192
            }
1193

    
1194
            monitor_printf(status->mon, "Completed %d %%\r", progress);
1195
            monitor_flush(status->mon);
1196
        }
1197

    
1198
        qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock) + 1000);
1199
    } else {
1200
        if (status->is_block_migration) {
1201
            monitor_printf(status->mon, "\n");
1202
        }
1203
        monitor_resume(status->mon);
1204
        qemu_del_timer(status->timer);
1205
        g_free(status);
1206
    }
1207

    
1208
    qapi_free_MigrationInfo(info);
1209
}
1210

    
1211
void hmp_migrate(Monitor *mon, const QDict *qdict)
1212
{
1213
    int detach = qdict_get_try_bool(qdict, "detach", 0);
1214
    int blk = qdict_get_try_bool(qdict, "blk", 0);
1215
    int inc = qdict_get_try_bool(qdict, "inc", 0);
1216
    const char *uri = qdict_get_str(qdict, "uri");
1217
    Error *err = NULL;
1218

    
1219
    qmp_migrate(uri, !!blk, blk, !!inc, inc, false, false, &err);
1220
    if (err) {
1221
        monitor_printf(mon, "migrate: %s\n", error_get_pretty(err));
1222
        error_free(err);
1223
        return;
1224
    }
1225

    
1226
    if (!detach) {
1227
        MigrationStatus *status;
1228

    
1229
        if (monitor_suspend(mon) < 0) {
1230
            monitor_printf(mon, "terminal does not allow synchronous "
1231
                           "migration, continuing detached\n");
1232
            return;
1233
        }
1234

    
1235
        status = g_malloc0(sizeof(*status));
1236
        status->mon = mon;
1237
        status->is_block_migration = blk || inc;
1238
        status->timer = qemu_new_timer_ms(rt_clock, hmp_migrate_status_cb,
1239
                                          status);
1240
        qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock));
1241
    }
1242
}
1243

    
1244
void hmp_device_del(Monitor *mon, const QDict *qdict)
1245
{
1246
    const char *id = qdict_get_str(qdict, "id");
1247
    Error *err = NULL;
1248

    
1249
    qmp_device_del(id, &err);
1250
    hmp_handle_error(mon, &err);
1251
}
1252

    
1253
void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
1254
{
1255
    Error *errp = NULL;
1256
    int paging = qdict_get_try_bool(qdict, "paging", 0);
1257
    const char *file = qdict_get_str(qdict, "filename");
1258
    bool has_begin = qdict_haskey(qdict, "begin");
1259
    bool has_length = qdict_haskey(qdict, "length");
1260
    int64_t begin = 0;
1261
    int64_t length = 0;
1262
    char *prot;
1263

    
1264
    if (has_begin) {
1265
        begin = qdict_get_int(qdict, "begin");
1266
    }
1267
    if (has_length) {
1268
        length = qdict_get_int(qdict, "length");
1269
    }
1270

    
1271
    prot = g_strconcat("file:", file, NULL);
1272

    
1273
    qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
1274
                          &errp);
1275
    hmp_handle_error(mon, &errp);
1276
    g_free(prot);
1277
}
1278

    
1279
void hmp_netdev_add(Monitor *mon, const QDict *qdict)
1280
{
1281
    Error *err = NULL;
1282
    QemuOpts *opts;
1283

    
1284
    opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
1285
    if (error_is_set(&err)) {
1286
        goto out;
1287
    }
1288

    
1289
    netdev_add(opts, &err);
1290
    if (error_is_set(&err)) {
1291
        qemu_opts_del(opts);
1292
    }
1293

    
1294
out:
1295
    hmp_handle_error(mon, &err);
1296
}
1297

    
1298
void hmp_netdev_del(Monitor *mon, const QDict *qdict)
1299
{
1300
    const char *id = qdict_get_str(qdict, "id");
1301
    Error *err = NULL;
1302

    
1303
    qmp_netdev_del(id, &err);
1304
    hmp_handle_error(mon, &err);
1305
}
1306

    
1307
void hmp_getfd(Monitor *mon, const QDict *qdict)
1308
{
1309
    const char *fdname = qdict_get_str(qdict, "fdname");
1310
    Error *errp = NULL;
1311

    
1312
    qmp_getfd(fdname, &errp);
1313
    hmp_handle_error(mon, &errp);
1314
}
1315

    
1316
void hmp_closefd(Monitor *mon, const QDict *qdict)
1317
{
1318
    const char *fdname = qdict_get_str(qdict, "fdname");
1319
    Error *errp = NULL;
1320

    
1321
    qmp_closefd(fdname, &errp);
1322
    hmp_handle_error(mon, &errp);
1323
}
1324

    
1325
void hmp_send_key(Monitor *mon, const QDict *qdict)
1326
{
1327
    const char *keys = qdict_get_str(qdict, "keys");
1328
    KeyValueList *keylist, *head = NULL, *tmp = NULL;
1329
    int has_hold_time = qdict_haskey(qdict, "hold-time");
1330
    int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
1331
    Error *err = NULL;
1332
    char keyname_buf[16];
1333
    char *separator;
1334
    int keyname_len;
1335

    
1336
    while (1) {
1337
        separator = strchr(keys, '-');
1338
        keyname_len = separator ? separator - keys : strlen(keys);
1339
        pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
1340

    
1341
        /* Be compatible with old interface, convert user inputted "<" */
1342
        if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
1343
            pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
1344
            keyname_len = 4;
1345
        }
1346
        keyname_buf[keyname_len] = 0;
1347

    
1348
        keylist = g_malloc0(sizeof(*keylist));
1349
        keylist->value = g_malloc0(sizeof(*keylist->value));
1350

    
1351
        if (!head) {
1352
            head = keylist;
1353
        }
1354
        if (tmp) {
1355
            tmp->next = keylist;
1356
        }
1357
        tmp = keylist;
1358

    
1359
        if (strstart(keyname_buf, "0x", NULL)) {
1360
            char *endp;
1361
            int value = strtoul(keyname_buf, &endp, 0);
1362
            if (*endp != '\0') {
1363
                goto err_out;
1364
            }
1365
            keylist->value->kind = KEY_VALUE_KIND_NUMBER;
1366
            keylist->value->number = value;
1367
        } else {
1368
            int idx = index_from_key(keyname_buf);
1369
            if (idx == Q_KEY_CODE_MAX) {
1370
                goto err_out;
1371
            }
1372
            keylist->value->kind = KEY_VALUE_KIND_QCODE;
1373
            keylist->value->qcode = idx;
1374
        }
1375

    
1376
        if (!separator) {
1377
            break;
1378
        }
1379
        keys = separator + 1;
1380
    }
1381

    
1382
    qmp_send_key(head, has_hold_time, hold_time, &err);
1383
    hmp_handle_error(mon, &err);
1384

    
1385
out:
1386
    qapi_free_KeyValueList(head);
1387
    return;
1388

    
1389
err_out:
1390
    monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
1391
    goto out;
1392
}
1393

    
1394
void hmp_screen_dump(Monitor *mon, const QDict *qdict)
1395
{
1396
    const char *filename = qdict_get_str(qdict, "filename");
1397
    Error *err = NULL;
1398

    
1399
    qmp_screendump(filename, &err);
1400
    hmp_handle_error(mon, &err);
1401
}
1402

    
1403
void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
1404
{
1405
    const char *uri = qdict_get_str(qdict, "uri");
1406
    int writable = qdict_get_try_bool(qdict, "writable", 0);
1407
    int all = qdict_get_try_bool(qdict, "all", 0);
1408
    Error *local_err = NULL;
1409
    BlockInfoList *block_list, *info;
1410
    SocketAddress *addr;
1411

    
1412
    if (writable && !all) {
1413
        error_setg(&local_err, "-w only valid together with -a");
1414
        goto exit;
1415
    }
1416

    
1417
    /* First check if the address is valid and start the server.  */
1418
    addr = socket_parse(uri, &local_err);
1419
    if (local_err != NULL) {
1420
        goto exit;
1421
    }
1422

    
1423
    qmp_nbd_server_start(addr, &local_err);
1424
    qapi_free_SocketAddress(addr);
1425
    if (local_err != NULL) {
1426
        goto exit;
1427
    }
1428

    
1429
    if (!all) {
1430
        return;
1431
    }
1432

    
1433
    /* Then try adding all block devices.  If one fails, close all and
1434
     * exit.
1435
     */
1436
    block_list = qmp_query_block(NULL);
1437

    
1438
    for (info = block_list; info; info = info->next) {
1439
        if (!info->value->has_inserted) {
1440
            continue;
1441
        }
1442

    
1443
        qmp_nbd_server_add(info->value->device, true, writable, &local_err);
1444

    
1445
        if (local_err != NULL) {
1446
            qmp_nbd_server_stop(NULL);
1447
            break;
1448
        }
1449
    }
1450

    
1451
    qapi_free_BlockInfoList(block_list);
1452

    
1453
exit:
1454
    hmp_handle_error(mon, &local_err);
1455
}
1456

    
1457
void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
1458
{
1459
    const char *device = qdict_get_str(qdict, "device");
1460
    int writable = qdict_get_try_bool(qdict, "writable", 0);
1461
    Error *local_err = NULL;
1462

    
1463
    qmp_nbd_server_add(device, true, writable, &local_err);
1464

    
1465
    if (local_err != NULL) {
1466
        hmp_handle_error(mon, &local_err);
1467
    }
1468
}
1469

    
1470
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
1471
{
1472
    Error *errp = NULL;
1473

    
1474
    qmp_nbd_server_stop(&errp);
1475
    hmp_handle_error(mon, &errp);
1476
}
1477

    
1478
void hmp_chardev_add(Monitor *mon, const QDict *qdict)
1479
{
1480
    const char *args = qdict_get_str(qdict, "args");
1481
    Error *err = NULL;
1482
    QemuOpts *opts;
1483

    
1484
    opts = qemu_opts_parse(qemu_find_opts("chardev"), args, 1);
1485
    if (opts == NULL) {
1486
        error_setg(&err, "Parsing chardev args failed");
1487
    } else {
1488
        qemu_chr_new_from_opts(opts, NULL, &err);
1489
    }
1490
    hmp_handle_error(mon, &err);
1491
}
1492

    
1493
void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
1494
{
1495
    Error *local_err = NULL;
1496

    
1497
    qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
1498
    hmp_handle_error(mon, &local_err);
1499
}
1500

    
1501
void hmp_qemu_io(Monitor *mon, const QDict *qdict)
1502
{
1503
    BlockDriverState *bs;
1504
    const char* device = qdict_get_str(qdict, "device");
1505
    const char* command = qdict_get_str(qdict, "command");
1506
    Error *err = NULL;
1507

    
1508
    bs = bdrv_find(device);
1509
    if (bs) {
1510
        qemuio_command(bs, command);
1511
    } else {
1512
        error_set(&err, QERR_DEVICE_NOT_FOUND, device);
1513
    }
1514

    
1515
    hmp_handle_error(mon, &err);
1516
}