qemu_monitor.c 106.6 KB
Newer Older
1 2 3
/*
 * qemu_monitor.c: interaction with QEMU monitor console
 *
4
 * Copyright (C) 2006-2015 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17
 * Copyright (C) 2006 Daniel P. Berrange
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library.  If not, see
O
Osier Yang 已提交
19
 * <http://www.gnu.org/licenses/>.
20 21 22 23 24 25 26
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

#include <config.h>

#include <poll.h>
27
#include <sys/socket.h>
28 29 30 31 32
#include <sys/un.h>
#include <unistd.h>
#include <fcntl.h>

#include "qemu_monitor.h"
33
#include "qemu_monitor_text.h"
D
Daniel P. Berrange 已提交
34
#include "qemu_monitor_json.h"
35 36
#include "qemu_domain.h"
#include "qemu_process.h"
37
#include "virerror.h"
38
#include "viralloc.h"
39
#include "virlog.h"
E
Eric Blake 已提交
40
#include "virfile.h"
41
#include "virprocess.h"
42
#include "virobject.h"
43
#include "virprobe.h"
44
#include "virstring.h"
45
#include "virtime.h"
46

47 48 49 50
#ifdef WITH_DTRACE_PROBES
# include "libvirt_qemu_probes.h"
#endif

51 52
#define VIR_FROM_THIS VIR_FROM_QEMU

53 54
VIR_LOG_INIT("qemu.qemu_monitor");

55 56
#define DEBUG_IO 0
#define DEBUG_RAW_IO 0
57

58
struct _qemuMonitor {
59
    virObjectLockable parent;
60

61 62
    virCond notify;

63 64 65 66 67 68
    int fd;
    int watch;
    int hasSendFD;

    virDomainObjPtr vm;

69
    qemuMonitorCallbacksPtr cb;
70
    void *callbackOpaque;
71 72 73 74 75 76 77 78 79 80 81 82 83

    /* If there's a command being processed this will be
     * non-NULL */
    qemuMonitorMessagePtr msg;

    /* Buffer incoming data ready for Text/QMP monitor
     * code to process & find message boundaries */
    size_t bufferOffset;
    size_t bufferLength;
    char *buffer;

    /* If anything went wrong, this will be fed back
     * the next monitor msg */
84 85 86
    virError lastError;

    int nextSerial;
87

E
Eric Blake 已提交
88 89
    bool json;
    bool waitGreeting;
90 91 92

    /* cache of query-command-line-options results */
    virJSONValuePtr options;
93 94 95 96

    /* If found, path to the virtio memballoon driver */
    char *balloonpath;
    bool ballooninit;
97

98 99 100 101
    /* Log file context of the qemu process to dig for usable info */
    qemuMonitorReportDomainLogError logFunc;
    void *logOpaque;
    virFreeCallback logDestroy;
102 103
};

104 105 106 107 108 109 110 111 112 113 114
/**
 * QEMU_CHECK_MONITOR_FULL:
 * @mon: monitor pointer variable to check, evaluated multiple times, no parentheses
 * @force_json: force JSON monitor, true or false
 * @exit: statement that is used to exit the function
 *
 * This macro checks that the monitor is valid for given operation and exits
 * the function if not. The macro also adds a debug statement regarding the
 * monitor.
 */
#define QEMU_CHECK_MONITOR_FULL(mon, force_json, exit)                         \
115 116 117 118 119 120 121 122 123 124 125 126 127 128
    do {                                                                       \
        if (!mon) {                                                            \
            virReportError(VIR_ERR_INVALID_ARG, "%s",                          \
                           _("monitor must not be NULL"));                     \
            exit;                                                              \
        }                                                                      \
        VIR_DEBUG("mon:%p vm:%p json:%d fd:%d",                                \
                  mon, mon->vm, mon->json, mon->fd);                           \
        if (force_json && !mon->json) {                                        \
            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",                \
                           _("JSON monitor is required"));                     \
            exit;                                                              \
        }                                                                      \
    } while (0)
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147

/* Check monitor and return NULL on error */
#define QEMU_CHECK_MONITOR_NULL(mon) \
    QEMU_CHECK_MONITOR_FULL(mon, false, return NULL)
#define QEMU_CHECK_MONITOR_JSON_NULL(mon) \
    QEMU_CHECK_MONITOR_FULL(mon, true, return NULL)

/* Check monitor and return -1 on error */
#define QEMU_CHECK_MONITOR(mon) \
    QEMU_CHECK_MONITOR_FULL(mon, false, return -1)
#define QEMU_CHECK_MONITOR_JSON(mon) \
    QEMU_CHECK_MONITOR_FULL(mon, true, return -1)

/* Check monitor and jump to the provided label */
#define QEMU_CHECK_MONITOR_GOTO(mon, label) \
    QEMU_CHECK_MONITOR_FULL(mon, false, goto label)
#define QEMU_CHECK_MONITOR_JSON_GOTO(mon, label) \
    QEMU_CHECK_MONITOR_FULL(mon, true, goto label)

148 149 150 151 152
static virClassPtr qemuMonitorClass;
static void qemuMonitorDispose(void *obj);

static int qemuMonitorOnceInit(void)
{
153
    if (!(qemuMonitorClass = virClassNew(virClassForObjectLockable(),
154 155 156
                                         "qemuMonitor",
                                         sizeof(qemuMonitor),
                                         qemuMonitorDispose)))
157 158 159 160 161 162 163
        return -1;

    return 0;
}

VIR_ONCE_GLOBAL_INIT(qemuMonitor)

164

165 166
VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
              QEMU_MONITOR_MIGRATION_STATUS_LAST,
167
              "inactive", "setup",
168
              "active", "postcopy-active",
169 170
              "completed", "failed",
              "cancelling", "cancelled")
171

172 173
VIR_ENUM_IMPL(qemuMonitorMigrationCaps,
              QEMU_MONITOR_MIGRATION_CAPS_LAST,
174
              "xbzrle", "auto-converge", "rdma-pin-all", "events",
175
              "postcopy-ram", "compress")
176

177 178 179 180
VIR_ENUM_IMPL(qemuMonitorVMStatus,
              QEMU_MONITOR_VM_STATUS_LAST,
              "debug", "inmigrate", "internal-error", "io-error", "paused",
              "postmigrate", "prelaunch", "finish-migrate", "restore-vm",
181
              "running", "save-vm", "shutdown", "watchdog", "guest-panicked")
182

183 184 185 186 187 188 189 190 191 192 193 194 195 196
typedef enum {
    QEMU_MONITOR_BLOCK_IO_STATUS_OK,
    QEMU_MONITOR_BLOCK_IO_STATUS_FAILED,
    QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE,

    QEMU_MONITOR_BLOCK_IO_STATUS_LAST
} qemuMonitorBlockIOStatus;

VIR_ENUM_DECL(qemuMonitorBlockIOStatus)

VIR_ENUM_IMPL(qemuMonitorBlockIOStatus,
              QEMU_MONITOR_BLOCK_IO_STATUS_LAST,
              "ok", "failed", "nospace")

197 198
char *
qemuMonitorEscapeArg(const char *in)
199 200
{
    int len = 0;
201
    size_t i, j;
202 203 204 205 206 207 208
    char *out;

    /* To pass through the QEMU monitor, we need to use escape
       sequences: \r, \n, \", \\
    */

    for (i = 0; in[i] != '\0'; i++) {
209
        switch (in[i]) {
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
        case '\r':
        case '\n':
        case '"':
        case '\\':
            len += 2;
            break;
        default:
            len += 1;
            break;
        }
    }

    if (VIR_ALLOC_N(out, len + 1) < 0)
        return NULL;

    for (i = j = 0; in[i] != '\0'; i++) {
226
        switch (in[i]) {
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
        case '\r':
            out[j++] = '\\';
            out[j++] = 'r';
            break;
        case '\n':
            out[j++] = '\\';
            out[j++] = 'n';
            break;
        case '"':
        case '\\':
            out[j++] = '\\';
            out[j++] = in[i];
            break;
        default:
            out[j++] = in[i];
            break;
        }
    }
    out[j] = '\0';

    return out;
}

250 251 252

char *
qemuMonitorUnescapeArg(const char *in)
253
{
254
    size_t i, j;
255
    char *out;
256
    int len = strlen(in);
257 258
    char next;

259
    if (VIR_ALLOC_N(out, len + 1) < 0)
260 261 262 263 264 265
        return NULL;

    for (i = j = 0; i < len; ++i) {
        next = in[i];
        if (in[i] == '\\') {
            ++i;
266
            switch (in[i]) {
267 268 269 270 271 272 273 274 275 276 277
            case 'r':
                next = '\r';
                break;
            case 'n':
                next = '\n';
                break;
            case '"':
            case '\\':
                next = in[i];
                break;
            default:
278
                /* invalid input (including trailing '\' at end of in) */
279 280 281 282 283 284 285 286 287 288 289
                VIR_FREE(out);
                return NULL;
            }
        }
        out[j++] = next;
    }
    out[j] = '\0';

    return out;
}

290

J
Jiri Denemark 已提交
291
#if DEBUG_RAW_IO
292
# include <c-ctype.h>
293 294
static char *
qemuMonitorEscapeNonPrintable(const char *text)
295
{
296
    size_t i;
297
    virBuffer buf = VIR_BUFFER_INITIALIZER;
298
    for (i = 0; text[i] != '\0'; i++) {
299 300
        if (c_isprint(text[i]) ||
            text[i] == '\n' ||
E
Eric Blake 已提交
301 302
            (text[i] == '\r' && text[i + 1] == '\n'))
            virBufferAddChar(&buf, text[i]);
303
        else
304
            virBufferAsprintf(&buf, "0x%02x", text[i]);
305 306 307 308 309
    }
    return virBufferContentAndReset(&buf);
}
#endif

310 311 312

static void
qemuMonitorDispose(void *obj)
313
{
314 315
    qemuMonitorPtr mon = obj;

316
    VIR_DEBUG("mon=%p", mon);
317
    if (mon->cb && mon->cb->destroy)
318
        (mon->cb->destroy)(mon, mon->vm, mon->callbackOpaque);
319 320
    virObjectUnref(mon->vm);

321
    virResetError(&mon->lastError);
322
    virCondDestroy(&mon->notify);
E
Eric Blake 已提交
323
    VIR_FREE(mon->buffer);
324
    virJSONValueFree(mon->options);
325
    VIR_FREE(mon->balloonpath);
326 327 328 329
}


static int
330 331 332
qemuMonitorOpenUnix(const char *monitor,
                    pid_t cpid,
                    unsigned long long timeout)
333 334 335
{
    struct sockaddr_un addr;
    int monfd;
336
    virTimeBackOffVar timebackoff;
337
    int ret = -1;
338 339

    if ((monfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
340
        virReportSystemError(errno,
341 342 343 344 345 346 347
                             "%s", _("failed to create socket"));
        return -1;
    }

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    if (virStrcpyStatic(addr.sun_path, monitor) == NULL) {
348 349
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Monitor path %s too big for destination"), monitor);
350 351 352
        goto error;
    }

353
    if (virTimeBackOffStart(&timebackoff, 1, timeout * 1000) < 0)
354
        goto error;
355
    while (virTimeBackOffWait(&timebackoff)) {
356 357 358 359 360
        ret = connect(monfd, (struct sockaddr *) &addr, sizeof(addr));

        if (ret == 0)
            break;

361
        if ((errno == ENOENT || errno == ECONNREFUSED) &&
362
            (!cpid || virProcessKill(cpid, 0) == 0)) {
363 364 365 366 367
            /* ENOENT       : Socket may not have shown up yet
             * ECONNREFUSED : Leftover socket hasn't been removed yet */
            continue;
        }

368
        virReportSystemError(errno, "%s",
369 370 371
                             _("failed to connect to monitor socket"));
        goto error;

372
    }
373 374

    if (ret != 0) {
375
        virReportSystemError(errno, "%s",
376
                             _("monitor socket did not show up"));
377 378 379
        goto error;
    }

380
    return monfd;
381

382
 error:
383
    VIR_FORCE_CLOSE(monfd);
384 385 386
    return -1;
}

387

388
static int
389
qemuMonitorOpenPty(const char *monitor)
390 391 392 393
{
    int monfd;

    if ((monfd = open(monitor, O_RDWR)) < 0) {
394 395
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Unable to open monitor path %s"), monitor);
396 397 398
        return -1;
    }

399
    return monfd;
400
}
401

402

403 404 405 406
/* This method processes data that has been received
 * from the monitor. Looking for async events and
 * replies/errors.
 */
407 408 409 410 411 412 413 414 415 416 417
static int
qemuMonitorIOProcess(qemuMonitorPtr mon)
{
    int len;
    qemuMonitorMessagePtr msg = NULL;

    /* See if there's a message & whether its ready for its reply
     * ie whether its completed writing all its data */
    if (mon->msg && mon->msg->txOffset == mon->msg->txLength)
        msg = mon->msg;

418
#if DEBUG_IO
419
# if DEBUG_RAW_IO
420 421
    char *str1 = qemuMonitorEscapeNonPrintable(msg ? msg->txBuffer : "");
    char *str2 = qemuMonitorEscapeNonPrintable(mon->buffer);
422
    VIR_ERROR(_("Process %d %p %p [[[[%s]]][[[%s]]]"), (int)mon->bufferOffset, mon->msg, msg, str1, str2);
423 424
    VIR_FREE(str1);
    VIR_FREE(str2);
425
# else
426
    VIR_DEBUG("Process %d", (int)mon->bufferOffset);
427
# endif
428 429
#endif

430 431 432
    PROBE(QEMU_MONITOR_IO_PROCESS,
          "mon=%p buf=%s len=%zu", mon, mon->buffer, mon->bufferOffset);

D
Daniel P. Berrange 已提交
433 434 435 436 437 438 439 440
    if (mon->json)
        len = qemuMonitorJSONIOProcess(mon,
                                       mon->buffer, mon->bufferOffset,
                                       msg);
    else
        len = qemuMonitorTextIOProcess(mon,
                                       mon->buffer, mon->bufferOffset,
                                       msg);
441

442
    if (len < 0)
443 444
        return -1;

E
Eric Blake 已提交
445 446
    if (len && mon->waitGreeting)
        mon->waitGreeting = false;
447

448 449 450 451 452 453 454
    if (len < mon->bufferOffset) {
        memmove(mon->buffer, mon->buffer + len, mon->bufferOffset - len);
        mon->bufferOffset -= len;
    } else {
        VIR_FREE(mon->buffer);
        mon->bufferOffset = mon->bufferLength = 0;
    }
455
#if DEBUG_IO
456
    VIR_DEBUG("Process done %d used %d", (int)mon->bufferOffset, len);
457
#endif
458 459 460 461 462 463
    if (msg && msg->finished)
        virCondBroadcast(&mon->notify);
    return len;
}


S
Stefan Berger 已提交
464
/* Call this function while holding the monitor lock. */
465 466 467 468 469 470 471 472 473 474 475 476 477
static int
qemuMonitorIOWriteWithFD(qemuMonitorPtr mon,
                         const char *data,
                         size_t len,
                         int fd)
{
    struct msghdr msg;
    struct iovec iov[1];
    int ret;
    char control[CMSG_SPACE(sizeof(int))];
    struct cmsghdr *cmsg;

    memset(&msg, 0, sizeof(msg));
478
    memset(control, 0, sizeof(control));
479 480 481 482 483 484 485 486 487 488 489

    iov[0].iov_base = (void *)data;
    iov[0].iov_len = len;

    msg.msg_iov = iov;
    msg.msg_iovlen = 1;

    msg.msg_control = control;
    msg.msg_controllen = sizeof(control);

    cmsg = CMSG_FIRSTHDR(&msg);
490 491 492
    /* Some static analyzers, like clang 2.6-0.6.pre2, fail to see
       that our use of CMSG_FIRSTHDR will not return NULL.  */
    sa_assert(cmsg);
493 494 495 496 497 498 499 500 501 502 503 504
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));

    do {
        ret = sendmsg(mon->fd, &msg, 0);
    } while (ret < 0 && errno == EINTR);

    return ret;
}

505

S
Stefan Berger 已提交
506 507 508 509
/*
 * Called when the monitor is able to write data
 * Call this function while holding the monitor lock.
 */
510 511 512 513
static int
qemuMonitorIOWrite(qemuMonitorPtr mon)
{
    int done;
J
John Ferlan 已提交
514 515
    char *buf;
    size_t len;
516 517 518 519 520

    /* If no active message, or fully transmitted, the no-op */
    if (!mon->msg || mon->msg->txOffset == mon->msg->txLength)
        return 0;

521
    if (mon->msg->txFD != -1 && !mon->hasSendFD) {
522 523
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Monitor does not support sending of file descriptors"));
524 525 526
        return -1;
    }

J
John Ferlan 已提交
527 528
    buf = mon->msg->txBuffer + mon->msg->txOffset;
    len = mon->msg->txLength - mon->msg->txOffset;
529
    if (mon->msg->txFD == -1)
J
John Ferlan 已提交
530
        done = write(mon->fd, buf, len);
531
    else
J
John Ferlan 已提交
532
        done = qemuMonitorIOWriteWithFD(mon, buf, len, mon->msg->txFD);
533

534
    PROBE(QEMU_MONITOR_IO_WRITE,
535
          "mon=%p buf=%s len=%zu ret=%d errno=%d",
536
          mon, buf, len, done, done < 0 ? errno : 0);
537

538
    if (mon->msg->txFD != -1) {
539 540
        PROBE(QEMU_MONITOR_IO_SEND_FD,
              "mon=%p fd=%d ret=%d errno=%d",
541
              mon, mon->msg->txFD, done, done < 0 ? errno : 0);
542
    }
543

544 545 546 547
    if (done < 0) {
        if (errno == EAGAIN)
            return 0;

548 549
        virReportSystemError(errno, "%s",
                             _("Unable to write to monitor"));
550 551 552 553 554 555
        return -1;
    }
    mon->msg->txOffset += done;
    return done;
}

556

557 558
/*
 * Called when the monitor has incoming data to read
S
Stefan Berger 已提交
559
 * Call this function while holding the monitor lock.
560 561 562 563 564 565 566 567 568 569 570
 *
 * Returns -1 on error, or number of bytes read
 */
static int
qemuMonitorIORead(qemuMonitorPtr mon)
{
    size_t avail = mon->bufferLength - mon->bufferOffset;
    int ret = 0;

    if (avail < 1024) {
        if (VIR_REALLOC_N(mon->buffer,
571
                          mon->bufferLength + 1024) < 0)
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
            return -1;
        mon->bufferLength += 1024;
        avail += 1024;
    }

    /* Read as much as we can get into our buffer,
       until we block on EAGAIN, or hit EOF */
    while (avail > 1) {
        int got;
        got = read(mon->fd,
                   mon->buffer + mon->bufferOffset,
                   avail - 1);
        if (got < 0) {
            if (errno == EAGAIN)
                break;
587 588
            virReportSystemError(errno, "%s",
                                 _("Unable to read from monitor"));
589 590 591 592 593 594 595 596 597 598 599 600
            ret = -1;
            break;
        }
        if (got == 0)
            break;

        ret += got;
        avail -= got;
        mon->bufferOffset += got;
        mon->buffer[mon->bufferOffset] = '\0';
    }

601
#if DEBUG_IO
602
    VIR_DEBUG("Now read %d bytes of data", (int)mon->bufferOffset);
603
#endif
604 605 606 607 608

    return ret;
}


609 610
static void
qemuMonitorUpdateWatch(qemuMonitorPtr mon)
611 612 613 614 615
{
    int events =
        VIR_EVENT_HANDLE_HANGUP |
        VIR_EVENT_HANDLE_ERROR;

616 617 618
    if (!mon->watch)
        return;

619
    if (mon->lastError.code == VIR_ERR_OK) {
620 621
        events |= VIR_EVENT_HANDLE_READABLE;

622
        if ((mon->msg && mon->msg->txOffset < mon->msg->txLength) &&
E
Eric Blake 已提交
623
            !mon->waitGreeting)
624 625 626 627
            events |= VIR_EVENT_HANDLE_WRITABLE;
    }

    virEventUpdateHandle(mon->watch, events);
628 629
}

630 631

static void
632 633
qemuMonitorIO(int watch, int fd, int events, void *opaque)
{
634
    qemuMonitorPtr mon = opaque;
635 636
    bool error = false;
    bool eof = false;
637
    bool hangup = false;
638

639 640
    virObjectRef(mon);

S
Stefan Berger 已提交
641
    /* lock access to the monitor and protect fd */
642
    virObjectLock(mon);
643
#if DEBUG_IO
644
    VIR_DEBUG("Monitor %p I/O on watch %d fd %d events %d", mon, watch, fd, events);
645
#endif
646
    if (mon->fd == -1 || mon->watch == 0) {
647
        virObjectUnlock(mon);
648 649 650
        virObjectUnref(mon);
        return;
    }
651

652
    if (mon->fd != fd || mon->watch != watch) {
653
        if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
654
            eof = true;
655 656 657
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("event from unexpected fd %d!=%d / watch %d!=%d"),
                       mon->fd, fd, mon->watch, watch);
658 659
        error = true;
    } else if (mon->lastError.code != VIR_ERR_OK) {
660
        if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
661
            eof = true;
662
        error = true;
663
    } else {
664
        if (events & VIR_EVENT_HANDLE_WRITABLE) {
665
            if (qemuMonitorIOWrite(mon) < 0) {
666
                error = true;
667 668 669
                if (errno == ECONNRESET)
                    hangup = true;
            }
670 671
            events &= ~VIR_EVENT_HANDLE_WRITABLE;
        }
672 673

        if (!error &&
674 675
            events & VIR_EVENT_HANDLE_READABLE) {
            int got = qemuMonitorIORead(mon);
676 677
            events &= ~VIR_EVENT_HANDLE_READABLE;
            if (got < 0) {
678
                error = true;
679 680
                if (errno == ECONNRESET)
                    hangup = true;
681 682 683 684 685
            } else if (got == 0) {
                eof = true;
            } else {
                /* Ignore hangup/error events if we read some data, to
                 * give time for that data to be consumed */
686 687 688
                events = 0;

                if (qemuMonitorIOProcess(mon) < 0)
689
                    error = true;
690
            }
691 692
        }

693 694 695 696
        if (events & VIR_EVENT_HANDLE_HANGUP) {
            hangup = true;
            if (!error) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
697
                               _("End of file from qemu monitor"));
698 699 700
                eof = true;
                events &= ~VIR_EVENT_HANDLE_HANGUP;
            }
701 702
        }

703 704
        if (!error && !eof &&
            events & VIR_EVENT_HANDLE_ERROR) {
705 706
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Invalid file descriptor while waiting for monitor"));
707
            eof = true;
708
            events &= ~VIR_EVENT_HANDLE_ERROR;
709 710
        }
        if (!error && events) {
711 712 713
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Unhandled event %d for monitor fd %d"),
                           events, mon->fd);
714
            error = true;
715 716 717
        }
    }

718
    if (error || eof) {
719
        if (hangup && mon->logFunc != NULL) {
720 721
            /* Check if an error message from qemu is available and if so, use
             * it to overwrite the actual message. It's done only in early
722 723 724
             * startup phases or during incoming migration when the message
             * from qemu is certainly more interesting than a
             * "connection reset by peer" message.
725
             */
726
            mon->logFunc(mon,
727
                         _("qemu unexpectedly closed the monitor"),
728
                         mon->logOpaque);
729 730
            virCopyLastError(&mon->lastError);
            virResetLastError();
731 732
        }

733 734 735 736 737 738
        if (mon->lastError.code != VIR_ERR_OK) {
            /* Already have an error, so clear any new error */
            virResetLastError();
        } else {
            virErrorPtr err = virGetLastError();
            if (!err)
739 740
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Error while processing monitor IO"));
741 742 743 744 745 746 747 748 749 750 751 752
            virCopyLastError(&mon->lastError);
            virResetLastError();
        }

        VIR_DEBUG("Error on monitor %s", NULLSTR(mon->lastError.message));
        /* If IO process resulted in an error & we have a message,
         * then wakeup that waiter */
        if (mon->msg && !mon->msg->finished) {
            mon->msg->finished = 1;
            virCondSignal(&mon->notify);
        }
    }
753 754 755

    qemuMonitorUpdateWatch(mon);

756 757 758
    /* We have to unlock to avoid deadlock against command thread,
     * but is this safe ?  I think it is, because the callback
     * will try to acquire the virDomainObjPtr mutex next */
759
    if (eof) {
J
Jiri Denemark 已提交
760
        qemuMonitorEofNotifyCallback eofNotify = mon->cb->eofNotify;
761
        virDomainObjPtr vm = mon->vm;
762

763 764
        /* Make sure anyone waiting wakes up now */
        virCondSignal(&mon->notify);
765
        virObjectUnlock(mon);
766
        VIR_DEBUG("Triggering EOF callback");
767
        (eofNotify)(mon, vm, mon->callbackOpaque);
768
        virObjectUnref(mon);
769
    } else if (error) {
J
Jiri Denemark 已提交
770
        qemuMonitorErrorNotifyCallback errorNotify = mon->cb->errorNotify;
771
        virDomainObjPtr vm = mon->vm;
772

773 774
        /* Make sure anyone waiting wakes up now */
        virCondSignal(&mon->notify);
775
        virObjectUnlock(mon);
776
        VIR_DEBUG("Triggering error callback");
777
        (errorNotify)(mon, vm, mon->callbackOpaque);
778
        virObjectUnref(mon);
779
    } else {
780
        virObjectUnlock(mon);
781
        virObjectUnref(mon);
782
    }
783 784 785
}


786 787 788 789
static qemuMonitorPtr
qemuMonitorOpenInternal(virDomainObjPtr vm,
                        int fd,
                        bool hasSendFD,
E
Eric Blake 已提交
790
                        bool json,
791 792
                        qemuMonitorCallbacksPtr cb,
                        void *opaque)
793
{
794 795
    qemuMonitorPtr mon;

796
    if (!cb->eofNotify) {
797 798
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("EOF notify callback must be supplied"));
799 800
        return NULL;
    }
801 802 803 804 805
    if (!cb->errorNotify) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Error notify callback must be supplied"));
        return NULL;
    }
806

807 808 809
    if (qemuMonitorInitialize() < 0)
        return NULL;

810
    if (!(mon = virObjectLockableNew(qemuMonitorClass)))
811 812
        return NULL;

813
    if (virCondInit(&mon->notify) < 0) {
814 815
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("cannot initialize monitor condition"));
816
        goto cleanup;
817
    }
818 819
    mon->fd = fd;
    mon->hasSendFD = hasSendFD;
820
    mon->vm = virObjectRef(vm);
D
Daniel P. Berrange 已提交
821
    mon->json = json;
822
    if (json)
E
Eric Blake 已提交
823
        mon->waitGreeting = true;
824
    mon->cb = cb;
825
    mon->callbackOpaque = opaque;
826

827
    if (virSetCloseExec(mon->fd) < 0) {
828 829
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("Unable to set monitor close-on-exec flag"));
830 831 832
        goto cleanup;
    }
    if (virSetNonBlock(mon->fd) < 0) {
833 834
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("Unable to put monitor into non-blocking mode"));
835 836 837 838
        goto cleanup;
    }


E
Eric Blake 已提交
839
    virObjectLock(mon);
840
    virObjectRef(mon);
841
    if ((mon->watch = virEventAddHandle(mon->fd,
842 843 844
                                        VIR_EVENT_HANDLE_HANGUP |
                                        VIR_EVENT_HANDLE_ERROR |
                                        VIR_EVENT_HANDLE_READABLE,
845
                                        qemuMonitorIO,
846 847
                                        mon,
                                        virObjectFreeCallback)) < 0) {
848
        virObjectUnref(mon);
E
Eric Blake 已提交
849
        virObjectUnlock(mon);
850 851
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("unable to register monitor events"));
852 853 854
        goto cleanup;
    }

855 856
    PROBE(QEMU_MONITOR_NEW,
          "mon=%p refs=%d fd=%d",
857
          mon, mon->parent.parent.u.s.refs, mon->fd);
858
    virObjectUnlock(mon);
859

860 861
    return mon;

862
 cleanup:
863 864 865 866 867 868
    /* We don't want the 'destroy' callback invoked during
     * cleanup from construction failure, because that can
     * give a double-unref on virDomainObjPtr in the caller,
     * so kill the callbacks now.
     */
    mon->cb = NULL;
869 870
    /* The caller owns 'fd' on failure */
    mon->fd = -1;
871 872 873 874
    qemuMonitorClose(mon);
    return NULL;
}

875

876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894
#define QEMU_DEFAULT_MONITOR_WAIT 30

/**
 * qemuMonitorOpen:
 * @vm: domain object
 * @config: monitor configuration
 * @json: enable JSON on the monitor
 * @timeout: number of seconds to add to default timeout
 * @cb: monitor event handles
 * @opaque: opaque data for @cb
 *
 * Opens the monitor for running qemu. It may happen that it
 * takes some time for qemu to create the monitor socket (e.g.
 * because kernel is zeroing configured hugepages), therefore we
 * wait up to default + timeout seconds for the monitor to show
 * up after which a failure is claimed.
 *
 * Returns monitor object, NULL on error.
 */
895 896 897
qemuMonitorPtr
qemuMonitorOpen(virDomainObjPtr vm,
                virDomainChrSourceDefPtr config,
E
Eric Blake 已提交
898
                bool json,
899
                unsigned long long timeout,
900 901
                qemuMonitorCallbacksPtr cb,
                void *opaque)
902 903 904 905 906
{
    int fd;
    bool hasSendFD = false;
    qemuMonitorPtr ret;

907 908
    timeout += QEMU_DEFAULT_MONITOR_WAIT;

909 910 911
    switch (config->type) {
    case VIR_DOMAIN_CHR_TYPE_UNIX:
        hasSendFD = true;
912 913 914
        if ((fd = qemuMonitorOpenUnix(config->data.nix.path,
                                      vm ? vm->pid : 0,
                                      timeout)) < 0)
915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
            return NULL;
        break;

    case VIR_DOMAIN_CHR_TYPE_PTY:
        if ((fd = qemuMonitorOpenPty(config->data.file.path)) < 0)
            return NULL;
        break;

    default:
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unable to handle monitor type: %s"),
                       virDomainChrTypeToString(config->type));
        return NULL;
    }

930
    ret = qemuMonitorOpenInternal(vm, fd, hasSendFD, json, cb, opaque);
931 932 933 934 935 936
    if (!ret)
        VIR_FORCE_CLOSE(fd);
    return ret;
}


937 938 939 940 941 942
qemuMonitorPtr
qemuMonitorOpenFD(virDomainObjPtr vm,
                  int sockfd,
                  bool json,
                  qemuMonitorCallbacksPtr cb,
                  void *opaque)
943
{
944
    return qemuMonitorOpenInternal(vm, sockfd, true, json, cb, opaque);
945 946
}

947

948 949 950 951 952 953 954 955 956
void
qemuMonitorUnregister(qemuMonitorPtr mon)
{
    if (mon->watch) {
        virEventRemoveHandle(mon->watch);
        mon->watch = 0;
    }
}

957 958
void
qemuMonitorClose(qemuMonitorPtr mon)
959 960
{
    if (!mon)
961
        return;
962

963
    virObjectLock(mon);
964
    PROBE(QEMU_MONITOR_CLOSE,
965
          "mon=%p refs=%d", mon, mon->parent.parent.u.s.refs);
S
Stefan Berger 已提交
966

967
    qemuMonitorSetDomainLog(mon, NULL, NULL, NULL);
968

S
Stefan Berger 已提交
969
    if (mon->fd >= 0) {
970
        qemuMonitorUnregister(mon);
S
Stefan Berger 已提交
971
        VIR_FORCE_CLOSE(mon->fd);
972
    }
973

974 975 976 977 978 979 980
    /* In case another thread is waiting for its monitor command to be
     * processed, we need to wake it up with appropriate error set.
     */
    if (mon->msg) {
        if (mon->lastError.code == VIR_ERR_OK) {
            virErrorPtr err = virSaveLastError();

981
            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
P
Philipp Hahn 已提交
982
                           _("QEMU monitor was closed"));
983 984 985 986 987 988 989 990 991 992 993 994
            virCopyLastError(&mon->lastError);
            if (err) {
                virSetError(err);
                virFreeError(err);
            } else {
                virResetLastError();
            }
        }
        mon->msg->finished = 1;
        virCondSignal(&mon->notify);
    }

995 996 997 998 999 1000
    /* Propagate existing monitor error in case the current thread has no
     * error set.
     */
    if (mon->lastError.code != VIR_ERR_OK && !virGetLastError())
        virSetError(&mon->lastError);

1001
    virObjectUnlock(mon);
1002
    virObjectUnref(mon);
1003 1004 1005
}


1006 1007
char *
qemuMonitorNextCommandID(qemuMonitorPtr mon)
1008 1009 1010
{
    char *id;

1011
    ignore_value(virAsprintf(&id, "libvirt-%d", ++mon->nextSerial));
1012 1013 1014 1015
    return id;
}


1016 1017 1018
int
qemuMonitorSend(qemuMonitorPtr mon,
                qemuMonitorMessagePtr msg)
1019
{
1020
    int ret = -1;
1021

E
Eric Blake 已提交
1022
    /* Check whether qemu quit unexpectedly */
1023 1024 1025 1026
    if (mon->lastError.code != VIR_ERR_OK) {
        VIR_DEBUG("Attempt to send command while error is set %s",
                  NULLSTR(mon->lastError.message));
        virSetError(&mon->lastError);
1027 1028 1029
        return -1;
    }

1030 1031
    mon->msg = msg;
    qemuMonitorUpdateWatch(mon);
1032

1033 1034 1035 1036
    PROBE(QEMU_MONITOR_SEND_MSG,
          "mon=%p msg=%s fd=%d",
          mon, mon->msg->txBuffer, mon->msg->txFD);

1037
    while (!mon->msg->finished) {
1038
        if (virCondWait(&mon->notify, &mon->parent.lock) < 0) {
1039 1040
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Unable to wait on monitor condition"));
1041
            goto cleanup;
1042 1043 1044 1045 1046 1047 1048 1049
        }
    }

    if (mon->lastError.code != VIR_ERR_OK) {
        VIR_DEBUG("Send command resulted in error %s",
                  NULLSTR(mon->lastError.message));
        virSetError(&mon->lastError);
        goto cleanup;
1050
    }
1051

1052
    ret = 0;
1053

1054
 cleanup:
1055 1056
    mon->msg = NULL;
    qemuMonitorUpdateWatch(mon);
1057

1058
    return ret;
1059
}
1060 1061


1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
/**
 * This function returns a new virError object; the caller is responsible
 * for freeing it.
 */
virErrorPtr
qemuMonitorLastError(qemuMonitorPtr mon)
{
    if (mon->lastError.code == VIR_ERR_OK)
        return NULL;

    return virErrorCopyNew(&mon->lastError);
}


1076 1077 1078 1079 1080 1081
virJSONValuePtr
qemuMonitorGetOptions(qemuMonitorPtr mon)
{
    return mon->options;
}

1082

1083 1084 1085 1086 1087 1088
void
qemuMonitorSetOptions(qemuMonitorPtr mon, virJSONValuePtr options)
{
    mon->options = options;
}

1089 1090

/**
1091 1092 1093
 * Search the qom objects for the balloon driver object by its known names
 * of "virtio-balloon-pci" or "virtio-balloon-ccw". The entry for the driver
 * will be found by using function "qemuMonitorJSONFindLinkPath".
1094 1095 1096 1097 1098
 *
 * Once found, check the entry to ensure it has the correct property listed.
 * If it does not, then obtaining statistics from QEMU will not be possible.
 * This feature was added to QEMU 1.5.
 */
1099
static void
1100 1101
qemuMonitorInitBalloonObjectPath(qemuMonitorPtr mon,
                                 virDomainMemballoonDefPtr balloon)
1102 1103 1104
{
    ssize_t i, nprops = 0;
    char *path = NULL;
1105
    const char *name;
1106 1107 1108
    qemuMonitorJSONListPathPtr *bprops = NULL;

    if (mon->balloonpath) {
1109
        return;
1110 1111 1112
    } else if (mon->ballooninit) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Cannot determine balloon device path"));
1113
        return;
1114
    }
1115
    mon->ballooninit = true;
1116

1117 1118 1119 1120 1121 1122 1123 1124
    switch (balloon->info.type) {
    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
        name = "virtio-balloon-pci";
        break;
    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
        name = "virtio-balloon-ccw";
        break;
    default:
1125
        return;
1126
    }
1127

1128 1129 1130
    if (qemuMonitorJSONFindLinkPath(mon, name, balloon->info.alias, &path) < 0)
        return;

1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
    nprops = qemuMonitorJSONGetObjectListPaths(mon, path, &bprops);
    if (nprops < 0)
        goto cleanup;

    for (i = 0; i < nprops; i++) {
        if (STREQ(bprops[i]->name, "guest-stats-polling-interval")) {
            VIR_DEBUG("Found Balloon Object Path %s", path);
            mon->balloonpath = path;
            path = NULL;
            goto cleanup;
        }
    }


    /* If we get here, we found the path, but not the property */
    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                   _("Property 'guest-stats-polling-interval' "
                     "not found on memory balloon driver."));

 cleanup:
    for (i = 0; i < nprops; i++)
        qemuMonitorJSONListPathFree(bprops[i]);
    VIR_FREE(bprops);
    VIR_FREE(path);
1155
    return;
1156 1157
}

1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172

/**
 * To update video memory size in status XML we need to load correct values from
 * QEMU.  This is supported only with JSON monitor.
 *
 * Returns 0 on success, -1 on failure and sets proper error message.
 */
int
qemuMonitorUpdateVideoMemorySize(qemuMonitorPtr mon,
                                 virDomainVideoDefPtr video,
                                 const char *videoName)
{
    int ret = -1;
    char *path = NULL;

1173 1174
    QEMU_CHECK_MONITOR(mon);

1175
    if (mon->json) {
1176 1177
        ret = qemuMonitorJSONFindLinkPath(mon, videoName,
                                          video->info.alias, &path);
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194
        if (ret < 0) {
            if (ret == -2)
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Failed to find QOM Object path for "
                                 "device '%s'"), videoName);
            return -1;
        }

        ret = qemuMonitorJSONUpdateVideoMemorySize(mon, video, path);
        VIR_FREE(path);
        return ret;
    }

    return 0;
}


1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211
/**
 * To update video vram64 size in status XML we need to load correct value from
 * QEMU.  This is supported only with JSON monitor.
 *
 * Returns 0 on success, -1 on failure and sets proper error message.
 */
int
qemuMonitorUpdateVideoVram64Size(qemuMonitorPtr mon,
                                 virDomainVideoDefPtr video,
                                 const char *videoName)
{
    int ret = -1;
    char *path = NULL;

    QEMU_CHECK_MONITOR(mon);

    if (mon->json) {
1212 1213
        ret = qemuMonitorJSONFindLinkPath(mon, videoName,
                                          video->info.alias, &path);
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
        if (ret < 0) {
            if (ret == -2)
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Failed to find QOM Object path for "
                                 "device '%s'"), videoName);
            return -1;
        }

        ret = qemuMonitorJSONUpdateVideoVram64Size(mon, video, path);
        VIR_FREE(path);
        return ret;
    }

    return 0;
}


1231 1232 1233 1234 1235
int
qemuMonitorHMPCommandWithFd(qemuMonitorPtr mon,
                            const char *cmd,
                            int scm_fd,
                            char **reply)
1236
{
1237 1238 1239
    char *json_cmd = NULL;
    int ret = -1;

1240 1241
    QEMU_CHECK_MONITOR(mon);

1242 1243 1244 1245 1246
    if (mon->json) {
        /* hack to avoid complicating each call to text monitor functions */
        json_cmd = qemuMonitorUnescapeArg(cmd);
        if (!json_cmd) {
            VIR_DEBUG("Could not unescape command: %s", cmd);
1247 1248
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Unable to unescape command"));
1249 1250 1251 1252 1253 1254 1255
            goto cleanup;
        }
        ret = qemuMonitorJSONHumanCommandWithFd(mon, json_cmd, scm_fd, reply);
    } else {
        ret = qemuMonitorTextCommandWithFd(mon, cmd, scm_fd, reply);
    }

1256
 cleanup:
1257 1258
    VIR_FREE(json_cmd);
    return ret;
1259 1260
}

1261

E
Eric Blake 已提交
1262 1263 1264
/* Ensure proper locking around callbacks.  */
#define QEMU_MONITOR_CALLBACK(mon, ret, callback, ...)          \
    do {                                                        \
1265
        virObjectRef(mon);                                      \
1266
        virObjectUnlock(mon);                                   \
E
Eric Blake 已提交
1267
        if ((mon)->cb && (mon)->cb->callback)                   \
1268 1269
            (ret) = (mon)->cb->callback(mon, __VA_ARGS__,       \
                                        (mon)->callbackOpaque); \
1270
        virObjectLock(mon);                                     \
1271
        virObjectUnref(mon);                                    \
E
Eric Blake 已提交
1272
    } while (0)
1273

1274 1275 1276 1277 1278 1279 1280

int
qemuMonitorGetDiskSecret(qemuMonitorPtr mon,
                         virConnectPtr conn,
                         const char *path,
                         char **secret,
                         size_t *secretLen)
1281
{
1282
    int ret = -1;
1283 1284 1285
    *secret = NULL;
    *secretLen = 0;

E
Eric Blake 已提交
1286 1287
    QEMU_MONITOR_CALLBACK(mon, ret, diskSecretLookup, conn, mon->vm,
                          path, secret, secretLen);
1288
    return ret;
1289
}
1290 1291


1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
int
qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event,
                     long long seconds, unsigned int micros,
                     const char *details)
{
    int ret = -1;
    VIR_DEBUG("mon=%p event=%s", mon, event);

    QEMU_MONITOR_CALLBACK(mon, ret, domainEvent, mon->vm, event, seconds,
                          micros, details);
    return ret;
}


1306 1307
int
qemuMonitorEmitShutdown(qemuMonitorPtr mon)
1308 1309 1310 1311
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1312
    QEMU_MONITOR_CALLBACK(mon, ret, domainShutdown, mon->vm);
1313 1314 1315 1316
    return ret;
}


1317 1318
int
qemuMonitorEmitReset(qemuMonitorPtr mon)
1319 1320 1321 1322
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1323
    QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm);
1324 1325 1326 1327
    return ret;
}


1328 1329
int
qemuMonitorEmitPowerdown(qemuMonitorPtr mon)
1330 1331 1332 1333
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1334
    QEMU_MONITOR_CALLBACK(mon, ret, domainPowerdown, mon->vm);
1335 1336 1337 1338
    return ret;
}


1339 1340
int
qemuMonitorEmitStop(qemuMonitorPtr mon)
1341 1342 1343 1344
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1345
    QEMU_MONITOR_CALLBACK(mon, ret, domainStop, mon->vm);
1346 1347 1348 1349
    return ret;
}


1350 1351
int
qemuMonitorEmitResume(qemuMonitorPtr mon)
1352 1353 1354 1355 1356 1357 1358 1359 1360
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainResume, mon->vm);
    return ret;
}


1361 1362
int
qemuMonitorEmitGuestPanic(qemuMonitorPtr mon)
1363 1364 1365 1366 1367 1368 1369 1370
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);
    QEMU_MONITOR_CALLBACK(mon, ret, domainGuestPanic, mon->vm);
    return ret;
}


1371 1372
int
qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset)
1373 1374 1375 1376
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1377
    QEMU_MONITOR_CALLBACK(mon, ret, domainRTCChange, mon->vm, offset);
1378 1379 1380 1381
    return ret;
}


1382 1383
int
qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action)
1384 1385 1386 1387
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1388
    QEMU_MONITOR_CALLBACK(mon, ret, domainWatchdog, mon->vm, action);
1389 1390 1391 1392
    return ret;
}


1393 1394 1395 1396 1397
int
qemuMonitorEmitIOError(qemuMonitorPtr mon,
                       const char *diskAlias,
                       int action,
                       const char *reason)
1398 1399 1400 1401
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1402 1403
    QEMU_MONITOR_CALLBACK(mon, ret, domainIOError, mon->vm,
                          diskAlias, action, reason);
1404 1405 1406 1407
    return ret;
}


1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419
int
qemuMonitorEmitGraphics(qemuMonitorPtr mon,
                        int phase,
                        int localFamily,
                        const char *localNode,
                        const char *localService,
                        int remoteFamily,
                        const char *remoteNode,
                        const char *remoteService,
                        const char *authScheme,
                        const char *x509dname,
                        const char *saslUsername)
1420 1421 1422 1423
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1424 1425 1426 1427
    QEMU_MONITOR_CALLBACK(mon, ret, domainGraphics, mon->vm, phase,
                          localFamily, localNode, localService,
                          remoteFamily, remoteNode, remoteService,
                          authScheme, x509dname, saslUsername);
1428 1429 1430
    return ret;
}

1431 1432 1433 1434 1435

int
qemuMonitorEmitTrayChange(qemuMonitorPtr mon,
                          const char *devAlias,
                          int reason)
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainTrayChange, mon->vm,
                          devAlias, reason);

    return ret;
}

1446 1447 1448

int
qemuMonitorEmitPMWakeup(qemuMonitorPtr mon)
O
Osier Yang 已提交
1449 1450 1451 1452 1453 1454 1455 1456 1457
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainPMWakeup, mon->vm);

    return ret;
}

1458 1459 1460

int
qemuMonitorEmitPMSuspend(qemuMonitorPtr mon)
O
Osier Yang 已提交
1461 1462 1463 1464 1465 1466 1467 1468 1469
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainPMSuspend, mon->vm);

    return ret;
}

1470 1471 1472

int
qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon)
1473 1474 1475 1476 1477 1478 1479 1480 1481
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainPMSuspendDisk, mon->vm);

    return ret;
}

1482 1483 1484 1485 1486 1487

int
qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
                        const char *diskAlias,
                        int type,
                        int status)
1488 1489 1490 1491 1492 1493 1494 1495 1496
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainBlockJob, mon->vm,
                          diskAlias, type, status);
    return ret;
}

1497

1498 1499 1500
int
qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
                             unsigned long long actual)
1501 1502 1503 1504 1505 1506 1507 1508
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainBalloonChange, mon->vm, actual);
    return ret;
}

1509

1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522
int
qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon,
                             const char *devAlias)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainDeviceDeleted, mon->vm, devAlias);

    return ret;
}


1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535
int
qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
                                  const char *devAlias)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainNicRxFilterChanged, mon->vm, devAlias);

    return ret;
}


1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
int
qemuMonitorEmitSerialChange(qemuMonitorPtr mon,
                            const char *devAlias,
                            bool connected)
{
    int ret = -1;
    VIR_DEBUG("mon=%p, devAlias='%s', connected=%d", mon, devAlias, connected);

    QEMU_MONITOR_CALLBACK(mon, ret, domainSerialChange, mon->vm, devAlias, connected);

    return ret;
}


1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561
int
qemuMonitorEmitSpiceMigrated(qemuMonitorPtr mon)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

    QEMU_MONITOR_CALLBACK(mon, ret, domainSpiceMigrated, mon->vm);

    return ret;
}


1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575
int
qemuMonitorEmitMigrationStatus(qemuMonitorPtr mon,
                               int status)
{
    int ret = -1;
    VIR_DEBUG("mon=%p, status=%s",
              mon, NULLSTR(qemuMonitorMigrationStatusTypeToString(status)));

    QEMU_MONITOR_CALLBACK(mon, ret, domainMigrationStatus, mon->vm, status);

    return ret;
}


1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588
int
qemuMonitorEmitMigrationPass(qemuMonitorPtr mon,
                             int pass)
{
    int ret = -1;
    VIR_DEBUG("mon=%p, pass=%d", mon, pass);

    QEMU_MONITOR_CALLBACK(mon, ret, domainMigrationPass, mon->vm, pass);

    return ret;
}


1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607
int
qemuMonitorEmitAcpiOstInfo(qemuMonitorPtr mon,
                           const char *alias,
                           const char *slotType,
                           const char *slot,
                           unsigned int source,
                           unsigned int status)
{
    int ret = -1;
    VIR_DEBUG("mon=%p, alias='%s', slotType='%s', slot='%s', source='%u' status=%u",
              mon, NULLSTR(alias), slotType, slot, source, status);

    QEMU_MONITOR_CALLBACK(mon, ret, domainAcpiOstInfo, mon->vm,
                          alias, slotType, slot, source, status);

    return ret;
}


1608 1609
int
qemuMonitorSetCapabilities(qemuMonitorPtr mon)
1610
{
1611
    QEMU_CHECK_MONITOR(mon);
1612

1613 1614
    if (!mon->json)
        return 0;
1615

1616
    return qemuMonitorJSONSetCapabilities(mon);
1617 1618 1619
}


1620 1621 1622 1623
int
qemuMonitorStartCPUs(qemuMonitorPtr mon,
                     virConnectPtr conn)
{
1624
    QEMU_CHECK_MONITOR(mon);
1625

D
Daniel P. Berrange 已提交
1626
    if (mon->json)
1627
        return qemuMonitorJSONStartCPUs(mon, conn);
D
Daniel P. Berrange 已提交
1628
    else
1629
        return qemuMonitorTextStartCPUs(mon, conn);
1630 1631 1632 1633 1634 1635
}


int
qemuMonitorStopCPUs(qemuMonitorPtr mon)
{
1636
    QEMU_CHECK_MONITOR(mon);
1637

D
Daniel P. Berrange 已提交
1638
    if (mon->json)
1639
        return qemuMonitorJSONStopCPUs(mon);
D
Daniel P. Berrange 已提交
1640
    else
1641
        return qemuMonitorTextStopCPUs(mon);
1642 1643 1644
}


1645 1646 1647 1648 1649 1650 1651 1652
int
qemuMonitorCheck(qemuMonitorPtr mon)
{
    bool running;
    return qemuMonitorGetStatus(mon, &running, NULL);
}


1653
int
1654 1655 1656
qemuMonitorGetStatus(qemuMonitorPtr mon,
                     bool *running,
                     virDomainPausedReason *reason)
1657
{
1658
    VIR_DEBUG("running=%p, reason=%p", running, reason);
1659

1660
    QEMU_CHECK_MONITOR(mon);
1661 1662

    if (mon->json)
1663
        return qemuMonitorJSONGetStatus(mon, running, reason);
1664
    else
1665
        return qemuMonitorTextGetStatus(mon, running, reason);
1666 1667 1668
}


1669 1670
int
qemuMonitorSystemPowerdown(qemuMonitorPtr mon)
1671
{
1672
    QEMU_CHECK_MONITOR(mon);
1673

D
Daniel P. Berrange 已提交
1674
    if (mon->json)
1675
        return qemuMonitorJSONSystemPowerdown(mon);
D
Daniel P. Berrange 已提交
1676
    else
1677
        return qemuMonitorTextSystemPowerdown(mon);
1678 1679 1680
}


1681 1682
int
qemuMonitorSystemReset(qemuMonitorPtr mon)
1683
{
1684
    QEMU_CHECK_MONITOR(mon);
1685 1686

    if (mon->json)
1687
        return qemuMonitorJSONSystemReset(mon);
1688
    else
1689
        return qemuMonitorTextSystemReset(mon);
1690 1691 1692
}


1693 1694 1695 1696 1697 1698 1699 1700
static void
qemuMonitorCPUInfoClear(qemuMonitorCPUInfoPtr cpus,
                        size_t ncpus)
{
    size_t i;

    for (i = 0; i < ncpus; i++) {
        cpus[i].id = 0;
1701
        cpus[i].qemu_id = -1;
1702 1703 1704 1705 1706
        cpus[i].socket_id = -1;
        cpus[i].core_id = -1;
        cpus[i].thread_id = -1;
        cpus[i].vcpus = 0;
        cpus[i].tid = 0;
1707
        cpus[i].halted = false;
1708 1709 1710 1711 1712 1713 1714 1715

        VIR_FREE(cpus[i].qom_path);
        VIR_FREE(cpus[i].alias);
        VIR_FREE(cpus[i].type);
    }
}


1716 1717
void
qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr cpus,
1718
                       size_t ncpus)
1719 1720 1721 1722
{
    if (!cpus)
        return;

1723 1724
    qemuMonitorCPUInfoClear(cpus, ncpus);

1725 1726 1727
    VIR_FREE(cpus);
}

1728 1729
void
qemuMonitorQueryCpusFree(struct qemuMonitorQueryCpusEntry *entries,
1730
                         size_t nentries)
1731
{
1732 1733
    size_t i;

1734 1735 1736
    if (!entries)
        return;

1737 1738 1739
    for (i = 0; i < nentries; i++)
        VIR_FREE(entries[i].qom_path);

1740 1741 1742
    VIR_FREE(entries);
}

1743

1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
/**
 * Legacy approach doesn't allow out of order cpus, thus no complex matching
 * algorithm is necessary */
static void
qemuMonitorGetCPUInfoLegacy(struct qemuMonitorQueryCpusEntry *cpuentries,
                            size_t ncpuentries,
                            qemuMonitorCPUInfoPtr vcpus,
                            size_t maxvcpus)
{
    size_t i;

    for (i = 0; i < maxvcpus; i++) {
1756
        if (i < ncpuentries) {
1757
            vcpus[i].tid = cpuentries[i].tid;
1758
            vcpus[i].halted = cpuentries[i].halted;
1759
            vcpus[i].qemu_id = cpuentries[i].qemu_id;
1760
        }
1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805

        /* for legacy hotplug to work we need to fake the vcpu count added by
         * enabling a given vcpu */
        vcpus[i].vcpus = 1;
    }
}


/**
 * qemuMonitorGetCPUInfoHotplug:
 *
 * This function stitches together data retrieved via query-hotpluggable-cpus
 * which returns entities on the hotpluggable level (which may describe more
 * than one guest logical vcpu) with the output of query-cpus, having an entry
 * per enabled guest logical vcpu.
 *
 * query-hotpluggable-cpus conveys following information:
 * - topology information and number of logical vcpus this entry creates
 * - device type name of the entry that needs to be used when hotplugging
 * - qom path in qemu which can be used to map the entry against query-cpus
 *
 * query-cpus conveys following information:
 * - thread id of a given guest logical vcpu
 * - order in which the vcpus were inserted
 * - qom path to allow mapping the two together
 *
 * The libvirt's internal structure has an entry for each possible (even
 * disabled) guest vcpu. The purpose is to map the data together so that we are
 * certain of the thread id mapping and the information required for vcpu
 * hotplug.
 *
 * This function returns 0 on success and -1 on error, but does not report
 * libvirt errors so that fallback approach can be used.
 */
static int
qemuMonitorGetCPUInfoHotplug(struct qemuMonitorQueryHotpluggableCpusEntry *hotplugvcpus,
                             size_t nhotplugvcpus,
                             struct qemuMonitorQueryCpusEntry *cpuentries,
                             size_t ncpuentries,
                             qemuMonitorCPUInfoPtr vcpus,
                             size_t maxvcpus)
{
    char *tmp;
    int order = 1;
    size_t totalvcpus = 0;
1806
    size_t mastervcpu; /* this iterator is used for iterating hotpluggable entities */
1807
    size_t slavevcpu; /* this corresponds to subentries of a hotpluggable entry */
1808
    size_t anyvcpu; /* this iterator is used for any vcpu entry in the result */
1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848
    size_t i;
    size_t j;

    /* ensure that the total vcpu count reported by query-hotpluggable-cpus equals
     * to the libvirt maximum cpu count */
    for (i = 0; i < nhotplugvcpus; i++)
        totalvcpus += hotplugvcpus[i].vcpus;

    /* trim '/thread...' suffix from the data returned by query-cpus */
    for (i = 0; i < ncpuentries; i++) {
        if (cpuentries[i].qom_path &&
            (tmp = strstr(cpuentries[i].qom_path, "/thread")))
            *tmp = '\0';
    }

    if (totalvcpus != maxvcpus) {
        VIR_DEBUG("expected '%zu' total vcpus got '%zu'", maxvcpus, totalvcpus);
        return -1;
    }

    /* Note the order in which the hotpluggable entities are inserted by
     * matching them to the query-cpus entries */
    for (i = 0; i < ncpuentries; i++) {
        for (j = 0; j < nhotplugvcpus; j++) {
            if (!cpuentries[i].qom_path ||
                !hotplugvcpus[j].qom_path ||
                STRNEQ(cpuentries[i].qom_path, hotplugvcpus[j].qom_path))
                continue;

            /* add ordering info for hotpluggable entries */
            if (hotplugvcpus[j].enable_id == 0)
                hotplugvcpus[j].enable_id = order++;

            break;
        }
    }

    /* transfer appropriate data from the hotpluggable list to corresponding
     * entries. the entries returned by qemu may in fact describe multiple
     * logical vcpus in the guest */
1849
    mastervcpu = 0;
1850
    for (i = 0; i < nhotplugvcpus; i++) {
1851 1852 1853
        vcpus[mastervcpu].online = !!hotplugvcpus[i].qom_path;
        vcpus[mastervcpu].hotpluggable = !!hotplugvcpus[i].alias ||
                                         !vcpus[mastervcpu].online;
1854 1855 1856 1857 1858 1859 1860 1861 1862
        vcpus[mastervcpu].socket_id = hotplugvcpus[i].socket_id;
        vcpus[mastervcpu].core_id = hotplugvcpus[i].core_id;
        vcpus[mastervcpu].thread_id = hotplugvcpus[i].thread_id;
        vcpus[mastervcpu].vcpus = hotplugvcpus[i].vcpus;
        VIR_STEAL_PTR(vcpus[mastervcpu].qom_path, hotplugvcpus[i].qom_path);
        VIR_STEAL_PTR(vcpus[mastervcpu].alias, hotplugvcpus[i].alias);
        VIR_STEAL_PTR(vcpus[mastervcpu].type, hotplugvcpus[i].type);
        vcpus[mastervcpu].id = hotplugvcpus[i].enable_id;

1863 1864 1865 1866 1867 1868
        /* copy state information to slave vcpus */
        for (slavevcpu = mastervcpu + 1; slavevcpu < mastervcpu + hotplugvcpus[i].vcpus; slavevcpu++) {
            vcpus[slavevcpu].online = vcpus[mastervcpu].online;
            vcpus[slavevcpu].hotpluggable = vcpus[mastervcpu].hotpluggable;
        }

1869 1870
        /* calculate next master vcpu (hotpluggable unit) entry */
        mastervcpu += hotplugvcpus[i].vcpus;
1871 1872 1873 1874 1875 1876
    }

    /* match entries from query cpus to the output array taking into account
     * multi-vcpu objects */
    for (j = 0; j < ncpuentries; j++) {
        /* find the correct entry or beginning of group of entries */
1877 1878 1879
        for (anyvcpu = 0; anyvcpu < maxvcpus; anyvcpu++) {
            if (cpuentries[j].qom_path && vcpus[anyvcpu].qom_path &&
                STREQ(cpuentries[j].qom_path, vcpus[anyvcpu].qom_path))
1880 1881 1882
                break;
        }

1883
        if (anyvcpu == maxvcpus) {
1884 1885 1886 1887 1888
            VIR_DEBUG("too many query-cpus entries for a given "
                      "query-hotpluggable-cpus entry");
            return -1;
        }

1889
        if (vcpus[anyvcpu].vcpus != 1) {
1890
            /* find a possibly empty vcpu thread for core granularity systems */
1891 1892
            for (; anyvcpu < maxvcpus; anyvcpu++) {
                if (vcpus[anyvcpu].tid == 0)
1893 1894 1895 1896
                    break;
            }
        }

1897
        vcpus[anyvcpu].qemu_id = cpuentries[j].qemu_id;
1898
        vcpus[anyvcpu].tid = cpuentries[j].tid;
1899
        vcpus[anyvcpu].halted = cpuentries[j].halted;
1900 1901 1902 1903 1904 1905
    }

    return 0;
}


1906 1907 1908
/**
 * qemuMonitorGetCPUInfo:
 * @mon: monitor
1909 1910
 * @vcpus: pointer filled by array of qemuMonitorCPUInfo structures
 * @maxvcpus: total possible number of vcpus
1911
 * @hotplug: query data relevant for hotplug support
1912 1913 1914 1915
 *
 * Detects VCPU information. If qemu doesn't support or fails reporting
 * information this function will return success as other parts of libvirt
 * are able to cope with that.
1916
 *
1917 1918
 * Returns 0 on success (including if qemu didn't report any data) and
 *  -1 on error (reports libvirt error).
1919
 */
1920 1921
int
qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
1922
                      qemuMonitorCPUInfoPtr *vcpus,
1923 1924
                      size_t maxvcpus,
                      bool hotplug)
1925
{
1926 1927
    struct qemuMonitorQueryHotpluggableCpusEntry *hotplugcpus = NULL;
    size_t nhotplugcpus = 0;
1928 1929
    struct qemuMonitorQueryCpusEntry *cpuentries = NULL;
    size_t ncpuentries = 0;
1930 1931
    int ret = -1;
    int rc;
1932
    qemuMonitorCPUInfoPtr info = NULL;
1933

1934
    QEMU_CHECK_MONITOR(mon);
1935

1936 1937 1938
    if (VIR_ALLOC_N(info, maxvcpus) < 0)
        return -1;

1939 1940 1941
    if (!mon->json)
        hotplug = false;

1942 1943 1944 1945 1946 1947 1948
    /* initialize a few non-zero defaults */
    qemuMonitorCPUInfoClear(info, maxvcpus);

    if (hotplug &&
        (qemuMonitorJSONGetHotpluggableCPUs(mon, &hotplugcpus, &nhotplugcpus)) < 0)
        goto cleanup;

D
Daniel P. Berrange 已提交
1949
    if (mon->json)
1950
        rc = qemuMonitorJSONQueryCPUs(mon, &cpuentries, &ncpuentries, hotplug);
D
Daniel P. Berrange 已提交
1951
    else
1952
        rc = qemuMonitorTextQueryCPUs(mon, &cpuentries, &ncpuentries);
1953 1954

    if (rc < 0) {
1955
        if (!hotplug && rc == -2) {
1956 1957 1958 1959
            VIR_STEAL_PTR(*vcpus, info);
            ret = 0;
        }

1960 1961 1962
        goto cleanup;
    }

1963 1964 1965 1966 1967 1968 1969 1970 1971
    if (!hotplugcpus ||
        qemuMonitorGetCPUInfoHotplug(hotplugcpus, nhotplugcpus,
                                     cpuentries, ncpuentries,
                                     info, maxvcpus) < 0) {
        /* Fallback to the legacy algorithm. Hotplug paths will make sure that
         * the apropriate data is present */
        qemuMonitorCPUInfoClear(info, maxvcpus);
        qemuMonitorGetCPUInfoLegacy(cpuentries, ncpuentries, info, maxvcpus);
    }
1972 1973 1974 1975 1976

    VIR_STEAL_PTR(*vcpus, info);
    ret = 0;

 cleanup:
1977
    qemuMonitorQueryHotpluggableCpusFree(hotplugcpus, nhotplugcpus);
1978
    qemuMonitorQueryCpusFree(cpuentries, ncpuentries);
1979
    qemuMonitorCPUInfoFree(info, maxvcpus);
1980
    return ret;
1981 1982
}

1983

1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002
/**
 * qemuMonitorGetCpuHalted:
 *
 * Returns a bitmap of vcpu id's that are halted. The id's correspond to the
 * 'CPU' field as reported by query-cpus'.
 */
virBitmapPtr
qemuMonitorGetCpuHalted(qemuMonitorPtr mon,
                        size_t maxvcpus)
{
    struct qemuMonitorQueryCpusEntry *cpuentries = NULL;
    size_t ncpuentries = 0;
    size_t i;
    int rc;
    virBitmapPtr ret = NULL;

    QEMU_CHECK_MONITOR_NULL(mon);

    if (mon->json)
2003
        rc = qemuMonitorJSONQueryCPUs(mon, &cpuentries, &ncpuentries, false);
2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023
    else
        rc = qemuMonitorTextQueryCPUs(mon, &cpuentries, &ncpuentries);

    if (rc < 0)
        goto cleanup;

    if (!(ret = virBitmapNew(maxvcpus)))
        goto cleanup;

    for (i = 0; i < ncpuentries; i++) {
        if (cpuentries[i].halted)
            ignore_value(virBitmapSetBit(ret, cpuentries[i].qemu_id));
    }

 cleanup:
    qemuMonitorQueryCpusFree(cpuentries, ncpuentries);
    return ret;
}


2024 2025 2026 2027
int
qemuMonitorSetLink(qemuMonitorPtr mon,
                   const char *name,
                   virDomainNetInterfaceLinkState state)
2028
{
2029
    VIR_DEBUG("name=%s, state=%u", name, state);
2030

2031
    QEMU_CHECK_MONITOR(mon);
2032 2033

    if (mon->json)
2034
        return qemuMonitorJSONSetLink(mon, name, state);
2035
    else
2036
        return qemuMonitorTextSetLink(mon, name, state);
2037
}
2038

2039 2040 2041

int
qemuMonitorGetVirtType(qemuMonitorPtr mon,
2042
                       virDomainVirtType *virtType)
2043
{
2044
    QEMU_CHECK_MONITOR(mon);
2045 2046

    if (mon->json)
2047
        return qemuMonitorJSONGetVirtType(mon, virtType);
2048
    else
2049
        return qemuMonitorTextGetVirtType(mon, virtType);
2050 2051 2052
}


2053 2054 2055 2056
/**
 * Returns: 0 if balloon not supported, +1 if balloon query worked
 * or -1 on failure
 */
2057 2058 2059
int
qemuMonitorGetBalloonInfo(qemuMonitorPtr mon,
                          unsigned long long *currmem)
2060
{
2061
    QEMU_CHECK_MONITOR(mon);
2062

D
Daniel P. Berrange 已提交
2063
    if (mon->json)
2064
        return qemuMonitorJSONGetBalloonInfo(mon, currmem);
D
Daniel P. Berrange 已提交
2065
    else
2066
        return qemuMonitorTextGetBalloonInfo(mon, currmem);
2067 2068 2069
}


2070 2071
int
qemuMonitorGetMemoryStats(qemuMonitorPtr mon,
2072
                          virDomainMemballoonDefPtr balloon,
2073 2074
                          virDomainMemoryStatPtr stats,
                          unsigned int nr_stats)
2075
{
2076
    VIR_DEBUG("stats=%p nstats=%u", stats, nr_stats);
2077

2078
    QEMU_CHECK_MONITOR(mon);
2079

2080
    if (mon->json) {
2081
        qemuMonitorInitBalloonObjectPath(mon, balloon);
2082 2083
        return qemuMonitorJSONGetMemoryStats(mon, mon->balloonpath,
                                             stats, nr_stats);
2084
    } else {
2085
        return qemuMonitorTextGetMemoryStats(mon, stats, nr_stats);
2086
    }
2087 2088
}

2089

2090 2091 2092 2093 2094 2095 2096
/**
 * qemuMonitorSetMemoryStatsPeriod:
 *
 * This function sets balloon stats update period.
 *
 * Returns 0 on success and -1 on error, but does *not* set an error.
 */
2097 2098
int
qemuMonitorSetMemoryStatsPeriod(qemuMonitorPtr mon,
2099
                                virDomainMemballoonDefPtr balloon,
2100
                                int period)
2101 2102 2103 2104
{
    int ret = -1;
    VIR_DEBUG("mon=%p period=%d", mon, period);

2105
    if (!mon)
2106 2107
        return -1;

2108 2109 2110 2111
    if (!mon->json)
        return -1;

    if (period < 0)
2112 2113
        return -1;

2114
    qemuMonitorInitBalloonObjectPath(mon, balloon);
2115
    if (mon->balloonpath) {
2116 2117
        ret = qemuMonitorJSONSetMemoryStatsPeriod(mon, mon->balloonpath,
                                                  period);
2118 2119 2120 2121 2122 2123 2124 2125 2126

        /*
         * Most of the calls to this function are supposed to be
         * non-fatal and the only one that should be fatal wants its
         * own error message.  More details for debugging will be in
         * the log file.
         */
        if (ret < 0)
            virResetLastError();
2127 2128 2129 2130
    }
    return ret;
}

2131

2132 2133 2134 2135 2136 2137
int
qemuMonitorBlockIOStatusToError(const char *status)
{
    int st = qemuMonitorBlockIOStatusTypeFromString(status);

    if (st < 0) {
2138 2139
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown block IO status: %s"), status);
2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157
        return -1;
    }

    switch ((qemuMonitorBlockIOStatus) st) {
    case QEMU_MONITOR_BLOCK_IO_STATUS_OK:
        return VIR_DOMAIN_DISK_ERROR_NONE;
    case QEMU_MONITOR_BLOCK_IO_STATUS_FAILED:
        return VIR_DOMAIN_DISK_ERROR_UNSPEC;
    case QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE:
        return VIR_DOMAIN_DISK_ERROR_NO_SPACE;

    /* unreachable */
    case QEMU_MONITOR_BLOCK_IO_STATUS_LAST:
        break;
    }
    return -1;
}

2158

2159 2160
virHashTablePtr
qemuMonitorGetBlockInfo(qemuMonitorPtr mon)
2161 2162
{
    int ret;
2163 2164
    virHashTablePtr table;

2165
    QEMU_CHECK_MONITOR_NULL(mon);
2166

E
Eric Blake 已提交
2167
    if (!(table = virHashCreate(32, virHashValueFree)))
2168 2169
        return NULL;

2170
    if (mon->json)
2171
        ret = qemuMonitorJSONGetBlockInfo(mon, table);
2172
    else
2173 2174 2175 2176 2177 2178 2179 2180 2181 2182
        ret = qemuMonitorTextGetBlockInfo(mon, table);

    if (ret < 0) {
        virHashFree(table);
        return NULL;
    }

    return table;
}

2183

2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194
/**
 * qemuMonitorGetAllBlockStatsInfo:
 * @mon: monitor object
 * @ret_stats: pointer that is filled with a hash table containing the stats
 * @backingChain: recurse into the backing chain of devices
 *
 * Creates a hash table in @ret_stats with block stats of all devices. In case
 * @backingChain is true @ret_stats will additionally contain stats for
 * backing chain members of block devices.
 *
 * Returns < 0 on error, count of supported block stats fields on success.
2195 2196 2197
 */
int
qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
2198 2199
                                virHashTablePtr *ret_stats,
                                bool backingChain)
2200
{
2201
    int ret = -1;
2202 2203 2204
    VIR_DEBUG("ret_stats=%p, backing=%d", ret_stats, backingChain);

    QEMU_CHECK_MONITOR(mon);
2205

2206 2207 2208
    if (!(*ret_stats = virHashCreate(10, virHashValueFree)))
        goto error;

2209
    if (mon->json) {
2210 2211
        ret = qemuMonitorJSONGetAllBlockStatsInfo(mon, *ret_stats,
                                                  backingChain);
2212 2213 2214 2215 2216 2217 2218 2219
    } else {
         if (backingChain) {
             virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                            _("text monitor doesn't support block stats for "
                              "backing chain members"));
             goto error;
         }

2220
         ret = qemuMonitorTextGetAllBlockStatsInfo(mon, *ret_stats);
2221
    }
2222

2223 2224 2225 2226
    if (ret < 0)
        goto error;

    return ret;
2227 2228 2229 2230 2231

 error:
    virHashFree(*ret_stats);
    *ret_stats = NULL;
    return -1;
2232 2233
}

2234 2235

/* Updates "stats" to fill virtual and physical size of the image */
2236 2237 2238 2239
int
qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
                                    virHashTablePtr stats,
                                    bool backingChain)
2240
{
2241
    VIR_DEBUG("stats=%p, backing=%d", stats, backingChain);
2242

2243
    QEMU_CHECK_MONITOR_JSON(mon);
2244

2245
    return qemuMonitorJSONBlockStatsUpdateCapacity(mon, stats, backingChain);
2246 2247 2248
}


2249 2250 2251 2252
int
qemuMonitorBlockResize(qemuMonitorPtr mon,
                       const char *device,
                       unsigned long long size)
2253
{
2254 2255 2256
    VIR_DEBUG("device=%s size=%llu", device, size);

    QEMU_CHECK_MONITOR(mon);
2257 2258

    if (mon->json)
2259
        return qemuMonitorJSONBlockResize(mon, device, size);
2260
    else
2261
        return qemuMonitorTextBlockResize(mon, device, size);
2262
}
2263

2264 2265 2266 2267

int
qemuMonitorSetVNCPassword(qemuMonitorPtr mon,
                          const char *password)
2268
{
2269
    VIR_DEBUG("password=%p", password);
2270

2271
    QEMU_CHECK_MONITOR(mon);
2272

2273 2274 2275
    if (!password)
        password = "";

D
Daniel P. Berrange 已提交
2276
    if (mon->json)
2277
        return qemuMonitorJSONSetVNCPassword(mon, password);
D
Daniel P. Berrange 已提交
2278
    else
2279
        return qemuMonitorTextSetVNCPassword(mon, password);
2280 2281
}

2282 2283 2284

static const char *
qemuMonitorTypeToProtocol(int type)
2285 2286 2287 2288 2289 2290 2291
{
    switch (type) {
    case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
        return "vnc";
    case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
        return "spice";
    default:
2292 2293 2294
        virReportError(VIR_ERR_INVALID_ARG,
                       _("unsupported protocol type %s"),
                       virDomainGraphicsTypeToString(type));
2295 2296 2297 2298
        return NULL;
    }
}

2299

2300
/* Returns -2 if not supported with this monitor connection */
2301 2302 2303 2304 2305
int
qemuMonitorSetPassword(qemuMonitorPtr mon,
                       int type,
                       const char *password,
                       const char *action_if_connected)
2306 2307 2308 2309 2310 2311
{
    const char *protocol = qemuMonitorTypeToProtocol(type);

    if (!protocol)
        return -1;

2312 2313
    VIR_DEBUG("protocol=%s, password=%p, action_if_connected=%s",
              protocol, password, action_if_connected);
2314

2315
    QEMU_CHECK_MONITOR(mon);
2316 2317 2318 2319 2320 2321 2322 2323

    if (!password)
        password = "";

    if (!action_if_connected)
        action_if_connected = "keep";

    if (mon->json)
2324
        return qemuMonitorJSONSetPassword(mon, protocol, password, action_if_connected);
2325
    else
2326
        return qemuMonitorTextSetPassword(mon, protocol, password, action_if_connected);
2327 2328
}

2329 2330 2331 2332 2333

int
qemuMonitorExpirePassword(qemuMonitorPtr mon,
                          int type,
                          const char *expire_time)
2334 2335 2336 2337 2338 2339
{
    const char *protocol = qemuMonitorTypeToProtocol(type);

    if (!protocol)
        return -1;

2340
    VIR_DEBUG("protocol=%s, expire_time=%s", protocol, expire_time);
2341

2342
    QEMU_CHECK_MONITOR(mon);
2343 2344 2345 2346 2347

    if (!expire_time)
        expire_time = "now";

    if (mon->json)
2348
        return qemuMonitorJSONExpirePassword(mon, protocol, expire_time);
2349
    else
2350
        return qemuMonitorTextExpirePassword(mon, protocol, expire_time);
2351
}
2352

2353

2354 2355 2356 2357
/*
 * Returns: 0 if balloon not supported, +1 if balloon adjust worked
 * or -1 on failure
 */
2358 2359
int
qemuMonitorSetBalloon(qemuMonitorPtr mon,
2360
                      unsigned long long newmem)
2361
{
2362
    VIR_DEBUG("newmem=%llu", newmem);
2363

2364
    QEMU_CHECK_MONITOR(mon);
2365

D
Daniel P. Berrange 已提交
2366
    if (mon->json)
2367
        return qemuMonitorJSONSetBalloon(mon, newmem);
D
Daniel P. Berrange 已提交
2368
    else
2369
        return qemuMonitorTextSetBalloon(mon, newmem);
2370 2371
}

2372

2373 2374 2375
/*
 * Returns: 0 if CPU modification was successful or -1 on failure
 */
2376 2377
int
qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, bool online)
2378
{
2379
    VIR_DEBUG("cpu=%d online=%d", cpu, online);
2380

2381
    QEMU_CHECK_MONITOR(mon);
2382 2383

    if (mon->json)
2384
        return qemuMonitorJSONSetCPU(mon, cpu, online);
2385
    else
2386
        return qemuMonitorTextSetCPU(mon, cpu, online);
2387 2388 2389
}


2390 2391 2392 2393
int
qemuMonitorEjectMedia(qemuMonitorPtr mon,
                      const char *dev_name,
                      bool force)
2394
{
2395
    VIR_DEBUG("dev_name=%s force=%d", dev_name, force);
2396

2397
    QEMU_CHECK_MONITOR(mon);
2398

D
Daniel P. Berrange 已提交
2399
    if (mon->json)
2400
        return qemuMonitorJSONEjectMedia(mon, dev_name, force);
D
Daniel P. Berrange 已提交
2401
    else
2402
        return qemuMonitorTextEjectMedia(mon, dev_name, force);
2403 2404 2405
}


2406 2407 2408 2409 2410
int
qemuMonitorChangeMedia(qemuMonitorPtr mon,
                       const char *dev_name,
                       const char *newmedia,
                       const char *format)
2411
{
2412
    VIR_DEBUG("dev_name=%s newmedia=%s format=%s", dev_name, newmedia, format);
2413

2414
    QEMU_CHECK_MONITOR(mon);
2415

D
Daniel P. Berrange 已提交
2416
    if (mon->json)
2417
        return qemuMonitorJSONChangeMedia(mon, dev_name, newmedia, format);
D
Daniel P. Berrange 已提交
2418
    else
2419
        return qemuMonitorTextChangeMedia(mon, dev_name, newmedia, format);
2420 2421 2422
}


2423 2424 2425 2426 2427
int
qemuMonitorSaveVirtualMemory(qemuMonitorPtr mon,
                             unsigned long long offset,
                             size_t length,
                             const char *path)
2428
{
2429
    VIR_DEBUG("offset=%llu length=%zu path=%s", offset, length, path);
2430

2431
    QEMU_CHECK_MONITOR(mon);
2432

D
Daniel P. Berrange 已提交
2433
    if (mon->json)
2434
        return qemuMonitorJSONSaveVirtualMemory(mon, offset, length, path);
D
Daniel P. Berrange 已提交
2435
    else
2436
        return qemuMonitorTextSaveVirtualMemory(mon, offset, length, path);
2437 2438
}

2439 2440 2441 2442 2443 2444

int
qemuMonitorSavePhysicalMemory(qemuMonitorPtr mon,
                              unsigned long long offset,
                              size_t length,
                              const char *path)
2445
{
2446
    VIR_DEBUG("offset=%llu length=%zu path=%s", offset, length, path);
2447

2448
    QEMU_CHECK_MONITOR(mon);
2449

D
Daniel P. Berrange 已提交
2450
    if (mon->json)
2451
        return qemuMonitorJSONSavePhysicalMemory(mon, offset, length, path);
D
Daniel P. Berrange 已提交
2452
    else
2453
        return qemuMonitorTextSavePhysicalMemory(mon, offset, length, path);
2454 2455 2456
}


2457 2458 2459
int
qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon,
                             unsigned long bandwidth)
2460
{
2461
    VIR_DEBUG("bandwidth=%lu", bandwidth);
2462

2463
    QEMU_CHECK_MONITOR(mon);
2464

2465 2466 2467 2468 2469 2470 2471
    if (bandwidth > QEMU_DOMAIN_MIG_BANDWIDTH_MAX) {
        virReportError(VIR_ERR_OVERFLOW,
                       _("bandwidth must be less than %llu"),
                       QEMU_DOMAIN_MIG_BANDWIDTH_MAX + 1ULL);
        return -1;
    }

D
Daniel P. Berrange 已提交
2472
    if (mon->json)
2473
        return qemuMonitorJSONSetMigrationSpeed(mon, bandwidth);
D
Daniel P. Berrange 已提交
2474
    else
2475
        return qemuMonitorTextSetMigrationSpeed(mon, bandwidth);
2476 2477
}

2478

2479 2480 2481
int
qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon,
                                unsigned long long downtime)
2482
{
2483
    VIR_DEBUG("downtime=%llu", downtime);
2484

2485
    QEMU_CHECK_MONITOR(mon);
2486 2487

    if (mon->json)
2488
        return qemuMonitorJSONSetMigrationDowntime(mon, downtime);
2489
    else
2490
        return qemuMonitorTextSetMigrationDowntime(mon, downtime);
2491 2492 2493
}


2494 2495 2496 2497
int
qemuMonitorGetMigrationCacheSize(qemuMonitorPtr mon,
                                 unsigned long long *cacheSize)
{
2498
    VIR_DEBUG("cacheSize=%p", cacheSize);
2499

2500
    QEMU_CHECK_MONITOR_JSON(mon);
2501 2502 2503 2504

    return qemuMonitorJSONGetMigrationCacheSize(mon, cacheSize);
}

2505

2506 2507 2508 2509
int
qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon,
                                 unsigned long long cacheSize)
{
2510
    VIR_DEBUG("cacheSize=%llu", cacheSize);
2511

2512
    QEMU_CHECK_MONITOR_JSON(mon);
2513 2514 2515 2516 2517

    return qemuMonitorJSONSetMigrationCacheSize(mon, cacheSize);
}


2518
int
2519 2520
qemuMonitorGetMigrationParams(qemuMonitorPtr mon,
                              qemuMonitorMigrationParamsPtr params)
2521 2522 2523
{
    QEMU_CHECK_MONITOR_JSON(mon);

2524
    return qemuMonitorJSONGetMigrationParams(mon, params);
2525 2526 2527
}

int
2528 2529
qemuMonitorSetMigrationParams(qemuMonitorPtr mon,
                              qemuMonitorMigrationParamsPtr params)
2530
{
2531
    VIR_DEBUG("compressLevel=%d:%d compressThreads=%d:%d "
2532 2533
              "decompressThreads=%d:%d cpuThrottleInitial=%d:%d "
              "cpuThrottleIncrement=%d:%d",
2534 2535
              params->compressLevel_set, params->compressLevel,
              params->compressThreads_set, params->compressThreads,
2536 2537 2538
              params->decompressThreads_set, params->decompressThreads,
              params->cpuThrottleInitial_set, params->cpuThrottleInitial,
              params->cpuThrottleIncrement_set, params->cpuThrottleIncrement);
2539 2540 2541

    QEMU_CHECK_MONITOR_JSON(mon);

2542 2543
    if (!params->compressLevel_set &&
        !params->compressThreads_set &&
2544 2545 2546
        !params->decompressThreads_set &&
        !params->cpuThrottleInitial_set &&
        !params->cpuThrottleIncrement_set)
2547 2548
        return 0;

2549
    return qemuMonitorJSONSetMigrationParams(mon, params);
2550 2551 2552
}


2553
int
2554 2555
qemuMonitorGetMigrationStats(qemuMonitorPtr mon,
                             qemuMonitorMigrationStatsPtr stats)
2556
{
2557
    QEMU_CHECK_MONITOR(mon);
2558

D
Daniel P. Berrange 已提交
2559
    if (mon->json)
2560
        return qemuMonitorJSONGetMigrationStats(mon, stats);
D
Daniel P. Berrange 已提交
2561
    else
2562
        return qemuMonitorTextGetMigrationStats(mon, stats);
2563 2564 2565
}


2566 2567 2568 2569
int
qemuMonitorMigrateToFd(qemuMonitorPtr mon,
                       unsigned int flags,
                       int fd)
E
Eric Blake 已提交
2570 2571
{
    int ret;
2572
    VIR_DEBUG("fd=%d flags=%x", fd, flags);
E
Eric Blake 已提交
2573

2574
    QEMU_CHECK_MONITOR(mon);
E
Eric Blake 已提交
2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585

    if (qemuMonitorSendFileHandle(mon, "migrate", fd) < 0)
        return -1;

    if (mon->json)
        ret = qemuMonitorJSONMigrate(mon, flags, "fd:migrate");
    else
        ret = qemuMonitorTextMigrate(mon, flags, "fd:migrate");

    if (ret < 0) {
        if (qemuMonitorCloseFileHandle(mon, "migrate") < 0)
2586
            VIR_WARN("failed to close migration handle");
E
Eric Blake 已提交
2587 2588 2589 2590 2591 2592
    }

    return ret;
}


2593 2594 2595 2596 2597 2598
int
qemuMonitorMigrateToHost(qemuMonitorPtr mon,
                         unsigned int flags,
                         const char *protocol,
                         const char *hostname,
                         int port)
2599
{
D
Daniel P. Berrange 已提交
2600
    int ret;
2601
    char *uri = NULL;
2602
    VIR_DEBUG("hostname=%s port=%d flags=%x", hostname, port, flags);
2603

2604
    QEMU_CHECK_MONITOR(mon);
2605

2606 2607 2608 2609
    if (strchr(hostname, ':')) {
        if (virAsprintf(&uri, "%s:[%s]:%d", protocol, hostname, port) < 0)
            return -1;
    } else if (virAsprintf(&uri, "%s:%s:%d", protocol, hostname, port) < 0) {
2610
        return -1;
2611
    }
2612

D
Daniel P. Berrange 已提交
2613
    if (mon->json)
2614
        ret = qemuMonitorJSONMigrate(mon, flags, uri);
D
Daniel P. Berrange 已提交
2615
    else
2616 2617 2618
        ret = qemuMonitorTextMigrate(mon, flags, uri);

    VIR_FREE(uri);
D
Daniel P. Berrange 已提交
2619
    return ret;
2620 2621 2622
}


2623 2624 2625 2626
int
qemuMonitorMigrateToCommand(qemuMonitorPtr mon,
                            unsigned int flags,
                            const char * const *argv)
2627
{
2628 2629 2630
    char *argstr;
    char *dest = NULL;
    int ret = -1;
2631
    VIR_DEBUG("argv=%p flags=%x", argv, flags);
2632

2633
    QEMU_CHECK_MONITOR(mon);
2634

2635
    argstr = virArgvToString(argv);
2636
    if (!argstr)
2637 2638
        goto cleanup;

2639
    if (virAsprintf(&dest, "exec:%s", argstr) < 0)
2640 2641
        goto cleanup;

D
Daniel P. Berrange 已提交
2642
    if (mon->json)
2643
        ret = qemuMonitorJSONMigrate(mon, flags, dest);
D
Daniel P. Berrange 已提交
2644
    else
2645 2646
        ret = qemuMonitorTextMigrate(mon, flags, dest);

2647
 cleanup:
2648 2649
    VIR_FREE(argstr);
    VIR_FREE(dest);
2650 2651 2652
    return ret;
}

2653 2654 2655

int
qemuMonitorMigrateCancel(qemuMonitorPtr mon)
2656
{
2657
    QEMU_CHECK_MONITOR(mon);
2658

D
Daniel P. Berrange 已提交
2659
    if (mon->json)
2660
        return qemuMonitorJSONMigrateCancel(mon);
D
Daniel P. Berrange 已提交
2661
    else
2662
        return qemuMonitorTextMigrateCancel(mon);
2663 2664
}

2665

2666 2667 2668
/**
 * Returns 1 if @capability is supported, 0 if it's not, or -1 on error.
 */
2669 2670 2671
int
qemuMonitorGetDumpGuestMemoryCapability(qemuMonitorPtr mon,
                                        const char *capability)
2672
{
2673
    VIR_DEBUG("capability=%s", capability);
2674

2675
    QEMU_CHECK_MONITOR(mon);
2676 2677 2678 2679 2680 2681 2682 2683

    /* No capability is supported without JSON monitor */
    if (!mon->json)
        return 0;

    return qemuMonitorJSONGetDumpGuestMemoryCapability(mon, capability);
}

2684

2685
int
2686
qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd, const char *dumpformat)
2687 2688
{
    int ret;
2689
    VIR_DEBUG("fd=%d dumpformat=%s", fd, dumpformat);
2690

2691
    QEMU_CHECK_MONITOR_JSON(mon);
2692 2693 2694 2695

    if (qemuMonitorSendFileHandle(mon, "dump", fd) < 0)
        return -1;

2696
    ret = qemuMonitorJSONDump(mon, "fd:dump", dumpformat);
2697 2698 2699 2700 2701 2702 2703 2704

    if (ret < 0) {
        if (qemuMonitorCloseFileHandle(mon, "dump") < 0)
            VIR_WARN("failed to close dumping handle");
    }

    return ret;
}
2705

2706 2707 2708 2709 2710 2711 2712 2713

int
qemuMonitorGraphicsRelocate(qemuMonitorPtr mon,
                            int type,
                            const char *hostname,
                            int port,
                            int tlsPort,
                            const char *tlsSubject)
2714
{
2715 2716 2717 2718
    VIR_DEBUG("type=%d hostname=%s port=%d tlsPort=%d tlsSubject=%s",
              type, hostname, port, tlsPort, NULLSTR(tlsSubject));

    QEMU_CHECK_MONITOR(mon);
2719 2720

    if (mon->json)
2721 2722 2723 2724 2725 2726
        return qemuMonitorJSONGraphicsRelocate(mon,
                                               type,
                                               hostname,
                                               port,
                                               tlsPort,
                                               tlsSubject);
2727
    else
2728 2729 2730 2731 2732 2733
        return qemuMonitorTextGraphicsRelocate(mon,
                                               type,
                                               hostname,
                                               port,
                                               tlsPort,
                                               tlsSubject);
2734 2735 2736
}


2737 2738 2739 2740
int
qemuMonitorSendFileHandle(qemuMonitorPtr mon,
                          const char *fdname,
                          int fd)
2741
{
2742
    VIR_DEBUG("fdname=%s fd=%d", fdname, fd);
2743

2744
    QEMU_CHECK_MONITOR(mon);
2745

2746
    if (fd < 0) {
2747 2748
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("fd must be valid"));
2749 2750 2751 2752
        return -1;
    }

    if (!mon->hasSendFD) {
2753
        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
2754 2755
                       _("qemu is not using a unix socket monitor, "
                         "cannot send fd %s"), fdname);
2756 2757 2758
        return -1;
    }

D
Daniel P. Berrange 已提交
2759
    if (mon->json)
2760
        return qemuMonitorJSONSendFileHandle(mon, fdname, fd);
D
Daniel P. Berrange 已提交
2761
    else
2762
        return qemuMonitorTextSendFileHandle(mon, fdname, fd);
2763 2764 2765
}


2766 2767 2768
int
qemuMonitorCloseFileHandle(qemuMonitorPtr mon,
                           const char *fdname)
2769
{
2770 2771 2772
    int ret = -1;
    virErrorPtr error;

2773
    VIR_DEBUG("fdname=%s", fdname);
2774

2775 2776
    error = virSaveLastError();

2777
    QEMU_CHECK_MONITOR_GOTO(mon, cleanup);
2778

D
Daniel P. Berrange 已提交
2779 2780 2781 2782
    if (mon->json)
        ret = qemuMonitorJSONCloseFileHandle(mon, fdname);
    else
        ret = qemuMonitorTextCloseFileHandle(mon, fdname);
2783

2784
 cleanup:
2785 2786 2787 2788
    if (error) {
        virSetError(error);
        virFreeError(error);
    }
D
Daniel P. Berrange 已提交
2789
    return ret;
2790 2791 2792
}


2793 2794 2795 2796 2797 2798
/* Add the open file descriptor FD into the non-negative set FDSET.
 * If NAME is present, it will be passed along for logging purposes.
 * Returns the counterpart fd that qemu received, or -1 on error.  */
int
qemuMonitorAddFd(qemuMonitorPtr mon, int fdset, int fd, const char *name)
{
2799
    VIR_DEBUG("fdset=%d, fd=%d, name=%s", fdset, fd, NULLSTR(name));
2800

2801
    QEMU_CHECK_MONITOR_JSON(mon);
2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815

    if (fd < 0 || fdset < 0) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("fd and fdset must be valid"));
        return -1;
    }

    if (!mon->hasSendFD) {
        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                       _("qemu is not using a unix socket monitor, "
                         "cannot send fd %s"), NULLSTR(name));
        return -1;
    }

2816
    return qemuMonitorJSONAddFd(mon, fdset, fd, name);
2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828
}


/* Remove one of qemu's fds from the given FDSET, or if FD is
 * negative, remove the entire set.  Preserve any previous error on
 * entry.  Returns 0 on success, -1 on error.  */
int
qemuMonitorRemoveFd(qemuMonitorPtr mon, int fdset, int fd)
{
    int ret = -1;
    virErrorPtr error;

2829
    VIR_DEBUG("fdset=%d, fd=%d", fdset, fd);
2830 2831 2832

    error = virSaveLastError();

2833
    QEMU_CHECK_MONITOR_JSON_GOTO(mon, cleanup);
2834

2835
    ret = qemuMonitorJSONRemoveFd(mon, fdset, fd);
2836

2837
 cleanup:
2838 2839 2840 2841 2842 2843 2844 2845
    if (error) {
        virSetError(error);
        virFreeError(error);
    }
    return ret;
}


2846 2847 2848 2849 2850
int
qemuMonitorAddHostNetwork(qemuMonitorPtr mon,
                          const char *netstr,
                          int *tapfd, char **tapfdName, int tapfdSize,
                          int *vhostfd, char **vhostfdName, int vhostfdSize)
2851
{
2852
    int ret = -1;
2853
    size_t i = 0, j = 0;
2854

2855
    VIR_DEBUG("netstr=%s tapfd=%p tapfdName=%p tapfdSize=%d "
2856
              "vhostfd=%p vhostfdName=%p vhostfdSize=%d",
2857
              netstr, tapfd, tapfdName, tapfdSize,
2858
              vhostfd, vhostfdName, vhostfdSize);
2859

2860
    QEMU_CHECK_MONITOR(mon);
2861

2862 2863 2864 2865 2866 2867 2868
    for (i = 0; i < tapfdSize; i++) {
        if (qemuMonitorSendFileHandle(mon, tapfdName[i], tapfd[i]) < 0)
            goto cleanup;
    }
    for (j = 0; j < vhostfdSize; j++) {
        if (qemuMonitorSendFileHandle(mon, vhostfdName[j], vhostfd[j]) < 0)
            goto cleanup;
2869 2870
    }

D
Daniel P. Berrange 已提交
2871
    if (mon->json)
2872
        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2873
                       _("JSON monitor should be using AddNetdev"));
D
Daniel P. Berrange 已提交
2874 2875
    else
        ret = qemuMonitorTextAddHostNetwork(mon, netstr);
2876

2877
 cleanup:
2878
    if (ret < 0) {
2879 2880 2881 2882 2883 2884 2885 2886
        while (i--) {
            if (qemuMonitorCloseFileHandle(mon, tapfdName[i]) < 0)
                VIR_WARN("failed to close device handle '%s'", tapfdName[i]);
        }
        while (j--) {
            if (qemuMonitorCloseFileHandle(mon, vhostfdName[j]) < 0)
                VIR_WARN("failed to close device handle '%s'", vhostfdName[j]);
        }
2887 2888
    }

D
Daniel P. Berrange 已提交
2889
    return ret;
2890 2891 2892
}


2893 2894 2895 2896
int
qemuMonitorRemoveHostNetwork(qemuMonitorPtr mon,
                             int vlan,
                             const char *netname)
2897
{
2898
    VIR_DEBUG("netname=%s", netname);
2899

2900
    QEMU_CHECK_MONITOR(mon);
2901

2902
    if (mon->json) {
2903
        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2904
                       _("JSON monitor should be using RemoveNetdev"));
2905 2906 2907 2908
        return -1;
    }

    return qemuMonitorTextRemoveHostNetwork(mon, vlan, netname);
2909
}
2910

2911

2912 2913 2914 2915 2916
int
qemuMonitorAddNetdev(qemuMonitorPtr mon,
                     const char *netdevstr,
                     int *tapfd, char **tapfdName, int tapfdSize,
                     int *vhostfd, char **vhostfdName, int vhostfdSize)
2917
{
2918
    int ret = -1;
2919
    size_t i = 0, j = 0;
2920

2921
    VIR_DEBUG("netdevstr=%s tapfd=%p tapfdName=%p tapfdSize=%d"
2922
              "vhostfd=%p vhostfdName=%p vhostfdSize=%d",
2923
              netdevstr, tapfd, tapfdName, tapfdSize,
2924
              vhostfd, vhostfdName, vhostfdSize);
2925

2926
    QEMU_CHECK_MONITOR(mon);
2927

2928 2929 2930 2931 2932 2933 2934
    for (i = 0; i < tapfdSize; i++) {
        if (qemuMonitorSendFileHandle(mon, tapfdName[i], tapfd[i]) < 0)
            goto cleanup;
    }
    for (j = 0; j < vhostfdSize; j++) {
        if (qemuMonitorSendFileHandle(mon, vhostfdName[j], vhostfd[j]) < 0)
            goto cleanup;
2935 2936
    }

2937 2938 2939 2940
    if (mon->json)
        ret = qemuMonitorJSONAddNetdev(mon, netdevstr);
    else
        ret = qemuMonitorTextAddNetdev(mon, netdevstr);
2941

2942
 cleanup:
2943
    if (ret < 0) {
2944 2945 2946 2947 2948 2949 2950 2951
        while (i--) {
            if (qemuMonitorCloseFileHandle(mon, tapfdName[i]) < 0)
                VIR_WARN("failed to close device handle '%s'", tapfdName[i]);
        }
        while (j--) {
            if (qemuMonitorCloseFileHandle(mon, vhostfdName[j]) < 0)
                VIR_WARN("failed to close device handle '%s'", vhostfdName[j]);
        }
2952 2953
    }

2954 2955 2956
    return ret;
}

2957 2958 2959 2960

int
qemuMonitorRemoveNetdev(qemuMonitorPtr mon,
                        const char *alias)
2961
{
2962
    VIR_DEBUG("alias=%s", alias);
2963

2964
    QEMU_CHECK_MONITOR(mon);
2965 2966

    if (mon->json)
2967
        return qemuMonitorJSONRemoveNetdev(mon, alias);
2968
    else
2969
        return qemuMonitorTextRemoveNetdev(mon, alias);
2970 2971 2972
}


2973 2974 2975 2976
int
qemuMonitorQueryRxFilter(qemuMonitorPtr mon, const char *alias,
                         virNetDevRxFilterPtr *filter)
{
2977
    VIR_DEBUG("alias=%s filter=%p", alias, filter);
2978

2979
    QEMU_CHECK_MONITOR_JSON(mon);
2980 2981

    return qemuMonitorJSONQueryRxFilter(mon, alias, filter);
2982 2983 2984
}


2985
void
2986 2987 2988 2989 2990 2991 2992 2993 2994 2995
qemuMonitorChardevInfoFree(void *data,
                           const void *name ATTRIBUTE_UNUSED)
{
    qemuMonitorChardevInfoPtr info = data;

    VIR_FREE(info->ptyPath);
    VIR_FREE(info);
}


2996 2997 2998
int
qemuMonitorGetChardevInfo(qemuMonitorPtr mon,
                          virHashTablePtr *retinfo)
2999
{
3000
    int ret;
3001 3002
    virHashTablePtr info = NULL;

3003
    VIR_DEBUG("retinfo=%p", retinfo);
3004

3005
    QEMU_CHECK_MONITOR_GOTO(mon, error);
3006

3007
    if (!(info = virHashCreate(10, qemuMonitorChardevInfoFree)))
3008 3009
        goto error;

3010
    if (mon->json)
3011
        ret = qemuMonitorJSONGetChardevInfo(mon, info);
3012
    else
3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024
        ret = qemuMonitorTextGetChardevInfo(mon, info);

    if (ret < 0)
        goto error;

    *retinfo = info;
    return 0;

 error:
    virHashFree(info);
    *retinfo = NULL;
    return -1;
3025
}
3026 3027


3028 3029 3030 3031 3032 3033 3034
/**
 * qemuMonitorDriveDel:
 * @mon: monitor object
 * @drivestr: identifier of drive to delete.
 *
 * Attempts to remove a host drive.
 * Returns 1 if unsupported, 0 if ok, and -1 on other failure */
3035 3036 3037
int
qemuMonitorDriveDel(qemuMonitorPtr mon,
                    const char *drivestr)
3038
{
3039
    VIR_DEBUG("drivestr=%s", drivestr);
3040

3041
    QEMU_CHECK_MONITOR(mon);
3042

3043 3044
    /* there won't be a direct replacement for drive_del in QMP */
    return qemuMonitorTextDriveDel(mon, drivestr);
3045 3046
}

3047 3048 3049 3050

int
qemuMonitorDelDevice(qemuMonitorPtr mon,
                     const char *devalias)
3051
{
3052
    VIR_DEBUG("devalias=%s", devalias);
3053

3054
    QEMU_CHECK_MONITOR(mon);
3055

3056
    if (mon->json)
3057
        return qemuMonitorJSONDelDevice(mon, devalias);
3058
    else
3059
        return qemuMonitorTextDelDevice(mon, devalias);
3060 3061
}

3062

3063 3064 3065 3066 3067
int
qemuMonitorAddDeviceWithFd(qemuMonitorPtr mon,
                           const char *devicestr,
                           int fd,
                           const char *fdname)
3068
{
3069
    VIR_DEBUG("device=%s fd=%d fdname=%s", devicestr, fd, NULLSTR(fdname));
3070 3071
    int ret;

3072
    QEMU_CHECK_MONITOR(mon);
3073

3074 3075 3076
    if (fd >= 0 && qemuMonitorSendFileHandle(mon, fdname, fd) < 0)
        return -1;

3077 3078 3079 3080
    if (mon->json)
        ret = qemuMonitorJSONAddDevice(mon, devicestr);
    else
        ret = qemuMonitorTextAddDevice(mon, devicestr);
3081 3082 3083 3084 3085 3086

    if (ret < 0 && fd >= 0) {
        if (qemuMonitorCloseFileHandle(mon, fdname) < 0)
            VIR_WARN("failed to close device handle '%s'", fdname);
    }

3087 3088 3089
    return ret;
}

3090 3091 3092 3093

int
qemuMonitorAddDevice(qemuMonitorPtr mon,
                     const char *devicestr)
3094 3095 3096 3097
{
    return qemuMonitorAddDeviceWithFd(mon, devicestr, -1, NULL);
}

3098

3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116
/**
 * qemuMonitorAddDeviceArgs:
 * @mon: monitor object
 * @args: arguments for device add, consumed on success or failure
 *
 * Adds a device described by @args. Requires JSON monitor.
 * Returns 0 on success -1 on error.
 */
int
qemuMonitorAddDeviceArgs(qemuMonitorPtr mon,
                         virJSONValuePtr args)
{
    QEMU_CHECK_MONITOR_JSON(mon);

    return qemuMonitorJSONAddDeviceArgs(mon, args);
}


3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132
/**
 * qemuMonitorAddObject:
 * @mon: Pointer to monitor object
 * @type: Type name of object to add
 * @objalias: Alias of the new object
 * @props: Optional arguments for the given type. The object is consumed and
 *         should not be referenced by the caller after this function returns.
 *
 * Returns 0 on success -1 on error.
 */
int
qemuMonitorAddObject(qemuMonitorPtr mon,
                     const char *type,
                     const char *objalias,
                     virJSONValuePtr props)
{
3133
    VIR_DEBUG("type=%s objalias=%s props=%p", type, objalias, props);
3134

3135
    QEMU_CHECK_MONITOR_JSON_GOTO(mon, error);
3136

3137
    return qemuMonitorJSONAddObject(mon, type, objalias, props);
3138 3139 3140 3141 3142

 error:
    virJSONValueFree(props);
    return -1;
}
3143 3144 3145 3146 3147 3148


int
qemuMonitorDelObject(qemuMonitorPtr mon,
                     const char *objalias)
{
3149
    VIR_DEBUG("objalias=%s", objalias);
3150

3151
    QEMU_CHECK_MONITOR_JSON(mon);
3152

3153
    return qemuMonitorJSONDelObject(mon, objalias);
3154 3155 3156
}


3157 3158 3159
int
qemuMonitorAddDrive(qemuMonitorPtr mon,
                    const char *drivestr)
3160
{
3161
    VIR_DEBUG("drive=%s", drivestr);
3162

3163
    QEMU_CHECK_MONITOR(mon);
3164

3165 3166
    /* there won't ever be a direct QMP replacement for this function */
    return qemuMonitorTextAddDrive(mon, drivestr);
3167
}
3168 3169


3170 3171 3172 3173
int
qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon,
                              const char *alias,
                              const char *passphrase)
3174
{
3175
    VIR_DEBUG("alias=%s passphrase=%p(value hidden)", alias, passphrase);
3176

3177
    QEMU_CHECK_MONITOR(mon);
3178

3179
    if (mon->json)
3180
        return qemuMonitorJSONSetDrivePassphrase(mon, alias, passphrase);
3181
    else
3182
        return qemuMonitorTextSetDrivePassphrase(mon, alias, passphrase);
3183
}
C
Chris Lalancette 已提交
3184

3185 3186 3187

int
qemuMonitorCreateSnapshot(qemuMonitorPtr mon, const char *name)
C
Chris Lalancette 已提交
3188
{
3189
    VIR_DEBUG("name=%s", name);
C
Chris Lalancette 已提交
3190

3191
    QEMU_CHECK_MONITOR(mon);
3192

C
Chris Lalancette 已提交
3193
    if (mon->json)
3194
        return qemuMonitorJSONCreateSnapshot(mon, name);
C
Chris Lalancette 已提交
3195
    else
3196
        return qemuMonitorTextCreateSnapshot(mon, name);
C
Chris Lalancette 已提交
3197 3198
}

3199 3200
int
qemuMonitorLoadSnapshot(qemuMonitorPtr mon, const char *name)
C
Chris Lalancette 已提交
3201
{
3202
    VIR_DEBUG("name=%s", name);
C
Chris Lalancette 已提交
3203

3204
    QEMU_CHECK_MONITOR(mon);
3205

C
Chris Lalancette 已提交
3206
    if (mon->json)
3207
        return qemuMonitorJSONLoadSnapshot(mon, name);
C
Chris Lalancette 已提交
3208
    else
3209
        return qemuMonitorTextLoadSnapshot(mon, name);
C
Chris Lalancette 已提交
3210 3211
}

3212 3213 3214

int
qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name)
C
Chris Lalancette 已提交
3215
{
3216
    VIR_DEBUG("name=%s", name);
C
Chris Lalancette 已提交
3217

3218
    QEMU_CHECK_MONITOR(mon);
3219

C
Chris Lalancette 已提交
3220
    if (mon->json)
3221
        return qemuMonitorJSONDeleteSnapshot(mon, name);
C
Chris Lalancette 已提交
3222
    else
3223
        return qemuMonitorTextDeleteSnapshot(mon, name);
C
Chris Lalancette 已提交
3224
}
3225

3226

3227 3228 3229 3230
/* Use the snapshot_blkdev command to convert the existing file for
 * device into a read-only backing file of a new qcow2 image located
 * at file.  */
int
3231
qemuMonitorDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions,
3232 3233
                        const char *device, const char *file,
                        const char *format, bool reuse)
3234
{
3235 3236
    VIR_DEBUG("actions=%p, device=%s, file=%s, format=%s, reuse=%d",
              actions, device, file, format, reuse);
3237

3238
    QEMU_CHECK_MONITOR_JSON(mon);
3239 3240

    return qemuMonitorJSONDiskSnapshot(mon, actions, device, file, format, reuse);
3241 3242
}

3243

3244
/* Start a drive-mirror block job.  bandwidth is in bytes/sec.  */
3245 3246 3247
int
qemuMonitorDriveMirror(qemuMonitorPtr mon,
                       const char *device, const char *file,
3248
                       const char *format, unsigned long long bandwidth,
3249
                       unsigned int granularity, unsigned long long buf_size,
3250 3251
                       unsigned int flags)
{
3252
    VIR_DEBUG("device=%s, file=%s, format=%s, bandwidth=%lld, "
3253
              "granularity=%#x, buf_size=%lld, flags=%x",
3254
              device, file, NULLSTR(format), bandwidth, granularity,
3255
              buf_size, flags);
3256

3257
    QEMU_CHECK_MONITOR_JSON(mon);
3258 3259 3260

    return qemuMonitorJSONDriveMirror(mon, device, file, format, bandwidth,
                                      granularity, buf_size, flags);
3261 3262
}

3263

3264 3265 3266 3267
/* Use the transaction QMP command to run atomic snapshot commands.  */
int
qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions)
{
3268
    VIR_DEBUG("actions=%p", actions);
3269

3270
    QEMU_CHECK_MONITOR_JSON(mon);
3271 3272

    return qemuMonitorJSONTransaction(mon, actions);
3273 3274
}

3275

3276
/* Start a block-commit block job.  bandwidth is in bytes/sec.  */
3277 3278 3279
int
qemuMonitorBlockCommit(qemuMonitorPtr mon, const char *device,
                       const char *top, const char *base,
3280
                       const char *backingName,
3281
                       unsigned long long bandwidth)
3282
{
3283 3284
    VIR_DEBUG("device=%s, top=%s, base=%s, backingName=%s, bandwidth=%llu",
              device, top, base, NULLSTR(backingName), bandwidth);
3285

3286
    QEMU_CHECK_MONITOR_JSON(mon);
3287 3288 3289

    return qemuMonitorJSONBlockCommit(mon, device, top, base,
                                         backingName, bandwidth);
3290 3291
}

3292 3293 3294 3295 3296

/* Probe whether active commits are supported by a given qemu binary. */
bool
qemuMonitorSupportsActiveCommit(qemuMonitorPtr mon)
{
3297
    if (!mon || !mon->json)
3298 3299
        return false;

3300
    return qemuMonitorJSONBlockCommit(mon, "bogus", NULL, NULL, NULL, 0) == -2;
3301 3302 3303
}


3304 3305 3306 3307 3308 3309 3310 3311
/* Determine the name that qemu is using for tracking the backing
 * element TARGET within the chain starting at TOP.  */
char *
qemuMonitorDiskNameLookup(qemuMonitorPtr mon,
                          const char *device,
                          virStorageSourcePtr top,
                          virStorageSourcePtr target)
{
3312
    QEMU_CHECK_MONITOR_JSON_NULL(mon);
3313 3314 3315 3316 3317

    return qemuMonitorJSONDiskNameLookup(mon, device, top, target);
}


3318
/* Use the block-job-complete monitor command to pivot a block copy job.  */
3319
int
3320 3321
qemuMonitorDrivePivot(qemuMonitorPtr mon,
                      const char *device)
3322
{
3323
    VIR_DEBUG("device=%s", device);
3324

3325
    QEMU_CHECK_MONITOR_JSON(mon);
3326 3327

    return qemuMonitorJSONDrivePivot(mon, device);
3328 3329
}

3330 3331 3332 3333 3334 3335

int
qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
                            const char *cmd,
                            char **reply,
                            bool hmp)
3336
{
3337 3338 3339
    VIR_DEBUG("cmd=%s, reply=%p, hmp=%d", cmd, reply, hmp);

    QEMU_CHECK_MONITOR(mon);
3340 3341

    if (mon->json)
3342
        return qemuMonitorJSONArbitraryCommand(mon, cmd, reply, hmp);
3343
    else
3344
        return qemuMonitorTextArbitraryCommand(mon, cmd, reply);
3345
}
3346 3347


3348 3349
int
qemuMonitorInjectNMI(qemuMonitorPtr mon)
3350
{
3351
    QEMU_CHECK_MONITOR(mon);
3352 3353

    if (mon->json)
3354
        return qemuMonitorJSONInjectNMI(mon);
3355
    else
3356
        return qemuMonitorTextInjectNMI(mon);
3357
}
3358

3359 3360 3361 3362 3363 3364

int
qemuMonitorSendKey(qemuMonitorPtr mon,
                   unsigned int holdtime,
                   unsigned int *keycodes,
                   unsigned int nkeycodes)
3365
{
3366 3367 3368
    VIR_DEBUG("holdtime=%u, nkeycodes=%u", holdtime, nkeycodes);

    QEMU_CHECK_MONITOR(mon);
3369 3370

    if (mon->json)
3371
        return qemuMonitorJSONSendKey(mon, holdtime, keycodes, nkeycodes);
3372
    else
3373
        return qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
3374 3375
}

3376 3377 3378 3379

int
qemuMonitorScreendump(qemuMonitorPtr mon,
                      const char *file)
3380
{
3381
    VIR_DEBUG("file=%s", file);
3382

3383
    QEMU_CHECK_MONITOR(mon);
3384 3385

    if (mon->json)
3386
        return qemuMonitorJSONScreendump(mon, file);
3387
    else
3388
        return qemuMonitorTextScreendump(mon, file);
3389
}
3390

3391

3392
/* bandwidth is in bytes/sec */
3393
int
3394 3395 3396 3397 3398 3399
qemuMonitorBlockStream(qemuMonitorPtr mon,
                       const char *device,
                       const char *base,
                       const char *backingName,
                       unsigned long long bandwidth,
                       bool modern)
3400
{
3401 3402
    VIR_DEBUG("device=%s, base=%s, backingName=%s, bandwidth=%lluB, modern=%d",
              device, NULLSTR(base), NULLSTR(backingName), bandwidth, modern);
3403

3404
    QEMU_CHECK_MONITOR_JSON(mon);
3405 3406 3407

    return qemuMonitorJSONBlockStream(mon, device, base, backingName,
                                      bandwidth, modern);
3408
}
3409

3410

3411 3412 3413 3414 3415
int
qemuMonitorBlockJobCancel(qemuMonitorPtr mon,
                          const char *device,
                          bool modern)
{
3416
    VIR_DEBUG("device=%s, modern=%d", device, modern);
3417

3418
    QEMU_CHECK_MONITOR_JSON(mon);
3419 3420 3421 3422 3423

    return qemuMonitorJSONBlockJobCancel(mon, device, modern);
}


3424 3425 3426 3427 3428 3429
int
qemuMonitorBlockJobSetSpeed(qemuMonitorPtr mon,
                            const char *device,
                            unsigned long long bandwidth,
                            bool modern)
{
3430
    VIR_DEBUG("device=%s, bandwidth=%lluB, modern=%d", device, bandwidth, modern);
3431

3432
    QEMU_CHECK_MONITOR_JSON(mon);
3433 3434 3435 3436 3437

    return qemuMonitorJSONBlockJobSetSpeed(mon, device, bandwidth, modern);
}


3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450
virHashTablePtr
qemuMonitorGetAllBlockJobInfo(qemuMonitorPtr mon)
{
    QEMU_CHECK_MONITOR_JSON_NULL(mon);
    return qemuMonitorJSONGetAllBlockJobInfo(mon);
}


/**
 * qemuMonitorGetBlockJobInfo:
 * Parse Block Job information, and populate info for the named device.
 * Return 1 if info available, 0 if device has no block job, and -1 on error.
 */
3451
int
3452 3453 3454
qemuMonitorGetBlockJobInfo(qemuMonitorPtr mon,
                           const char *alias,
                           qemuMonitorBlockJobInfoPtr info)
3455
{
3456 3457 3458
    virHashTablePtr all;
    qemuMonitorBlockJobInfoPtr data;
    int ret = 0;
3459

3460 3461 3462 3463
    VIR_DEBUG("alias=%s, info=%p", alias, info);

    if (!(all = qemuMonitorGetAllBlockJobInfo(mon)))
        return -1;
3464

3465 3466 3467 3468 3469 3470 3471
    if ((data = virHashLookup(all, alias))) {
        *info = *data;
        ret = 1;
    }

    virHashFree(all);
    return ret;
3472 3473 3474
}


3475 3476 3477 3478
int
qemuMonitorSetBlockIoThrottle(qemuMonitorPtr mon,
                              const char *device,
                              virDomainBlockIoTuneInfoPtr info,
3479
                              bool supportMaxOptions,
3480
                              bool supportGroupNameOption,
3481
                              bool supportMaxLengthOptions)
3482
{
3483 3484 3485
    VIR_DEBUG("device=%p, info=%p", device, info);

    QEMU_CHECK_MONITOR(mon);
3486

3487
    if (mon->json)
3488 3489
        return qemuMonitorJSONSetBlockIoThrottle(mon, device, info,
                                                 supportMaxOptions,
3490
                                                 supportGroupNameOption,
3491
                                                 supportMaxLengthOptions);
3492 3493
    else
        return qemuMonitorTextSetBlockIoThrottle(mon, device, info);
3494 3495
}

3496 3497 3498 3499

int
qemuMonitorGetBlockIoThrottle(qemuMonitorPtr mon,
                              const char *device,
3500
                              virDomainBlockIoTuneInfoPtr reply)
3501
{
3502 3503 3504
    VIR_DEBUG("device=%p, reply=%p", device, reply);

    QEMU_CHECK_MONITOR(mon);
3505

3506
    if (mon->json)
3507
        return qemuMonitorJSONGetBlockIoThrottle(mon, device, reply);
3508 3509
    else
        return qemuMonitorTextGetBlockIoThrottle(mon, device, reply);
3510 3511 3512
}


3513 3514
int
qemuMonitorVMStatusToPausedReason(const char *status)
3515 3516 3517 3518 3519 3520 3521
{
    int st;

    if (!status)
        return VIR_DOMAIN_PAUSED_UNKNOWN;

    if ((st = qemuMonitorVMStatusTypeFromString(status)) < 0) {
P
Philipp Hahn 已提交
3522
        VIR_WARN("QEMU reported unknown VM status: '%s'", status);
3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544
        return VIR_DOMAIN_PAUSED_UNKNOWN;
    }

    switch ((qemuMonitorVMStatus) st) {
    case QEMU_MONITOR_VM_STATUS_DEBUG:
    case QEMU_MONITOR_VM_STATUS_INTERNAL_ERROR:
    case QEMU_MONITOR_VM_STATUS_RESTORE_VM:
        return VIR_DOMAIN_PAUSED_UNKNOWN;

    case QEMU_MONITOR_VM_STATUS_INMIGRATE:
    case QEMU_MONITOR_VM_STATUS_POSTMIGRATE:
    case QEMU_MONITOR_VM_STATUS_FINISH_MIGRATE:
        return VIR_DOMAIN_PAUSED_MIGRATION;

    case QEMU_MONITOR_VM_STATUS_IO_ERROR:
        return VIR_DOMAIN_PAUSED_IOERROR;

    case QEMU_MONITOR_VM_STATUS_PAUSED:
    case QEMU_MONITOR_VM_STATUS_PRELAUNCH:
        return VIR_DOMAIN_PAUSED_USER;

    case QEMU_MONITOR_VM_STATUS_RUNNING:
P
Philipp Hahn 已提交
3545
        VIR_WARN("QEMU reports the guest is paused but status is 'running'");
3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556
        return VIR_DOMAIN_PAUSED_UNKNOWN;

    case QEMU_MONITOR_VM_STATUS_SAVE_VM:
        return VIR_DOMAIN_PAUSED_SAVE;

    case QEMU_MONITOR_VM_STATUS_SHUTDOWN:
        return VIR_DOMAIN_PAUSED_SHUTTING_DOWN;

    case QEMU_MONITOR_VM_STATUS_WATCHDOG:
        return VIR_DOMAIN_PAUSED_WATCHDOG;

3557
    case QEMU_MONITOR_VM_STATUS_GUEST_PANICKED:
3558
        return VIR_DOMAIN_PAUSED_CRASHED;
3559

3560 3561 3562 3563 3564 3565
    /* unreachable from this point on */
    case QEMU_MONITOR_VM_STATUS_LAST:
        ;
    }
    return VIR_DOMAIN_PAUSED_UNKNOWN;
}
3566 3567


3568 3569 3570 3571 3572 3573
int
qemuMonitorOpenGraphics(qemuMonitorPtr mon,
                        const char *protocol,
                        int fd,
                        const char *fdname,
                        bool skipauth)
3574
{
3575 3576
    VIR_DEBUG("protocol=%s fd=%d fdname=%s skipauth=%d",
              protocol, fd, NULLSTR(fdname), skipauth);
3577 3578
    int ret;

3579
    QEMU_CHECK_MONITOR(mon);
3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595

    if (qemuMonitorSendFileHandle(mon, fdname, fd) < 0)
        return -1;

    if (mon->json)
        ret = qemuMonitorJSONOpenGraphics(mon, protocol, fdname, skipauth);
    else
        ret = qemuMonitorTextOpenGraphics(mon, protocol, fdname, skipauth);

    if (ret < 0) {
        if (qemuMonitorCloseFileHandle(mon, fdname) < 0)
            VIR_WARN("failed to close device handle '%s'", fdname);
    }

    return ret;
}
3596

3597 3598 3599

int
qemuMonitorSystemWakeup(qemuMonitorPtr mon)
3600
{
3601
    QEMU_CHECK_MONITOR_JSON(mon);
3602 3603 3604

    return qemuMonitorJSONSystemWakeup(mon);
}
3605

3606 3607 3608 3609 3610 3611 3612

int
qemuMonitorGetVersion(qemuMonitorPtr mon,
                      int *major,
                      int *minor,
                      int *micro,
                      char **package)
3613
{
3614 3615
    VIR_DEBUG("major=%p minor=%p micro=%p package=%p",
              major, minor, micro, package);
3616

3617
    QEMU_CHECK_MONITOR_JSON(mon);
3618 3619 3620

    return qemuMonitorJSONGetVersion(mon, major, minor, micro, package);
}
3621

3622 3623 3624 3625

int
qemuMonitorGetMachines(qemuMonitorPtr mon,
                       qemuMonitorMachineInfoPtr **machines)
3626
{
3627
    VIR_DEBUG("machines=%p", machines);
3628

3629
    QEMU_CHECK_MONITOR_JSON(mon);
3630 3631 3632 3633

    return qemuMonitorJSONGetMachines(mon, machines);
}

3634 3635 3636

void
qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine)
3637 3638 3639 3640 3641 3642 3643
{
    if (!machine)
        return;
    VIR_FREE(machine->name);
    VIR_FREE(machine->alias);
    VIR_FREE(machine);
}
3644

3645 3646 3647

int
qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
3648
                             qemuMonitorCPUDefInfoPtr **cpus)
3649
{
3650
    VIR_DEBUG("cpus=%p", cpus);
3651

3652
    QEMU_CHECK_MONITOR_JSON(mon);
3653 3654 3655

    return qemuMonitorJSONGetCPUDefinitions(mon, cpus);
}
3656 3657


3658 3659 3660 3661 3662 3663 3664 3665 3666 3667
void
qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu)
{
    if (!cpu)
        return;
    VIR_FREE(cpu->name);
    VIR_FREE(cpu);
}


3668 3669
int
qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
3670
                                qemuMonitorCPUModelExpansionType type,
3671 3672 3673
                                const char *model_name,
                                qemuMonitorCPUModelInfoPtr *model_info)
{
3674
    VIR_DEBUG("type=%d model_name=%s", type, model_name);
3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689

    QEMU_CHECK_MONITOR_JSON(mon);

    return qemuMonitorJSONGetCPUModelExpansion(mon, type, model_name, model_info);
}


void
qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info)
{
    size_t i;

    if (!model_info)
        return;

3690
    for (i = 0; i < model_info->nprops; i++) {
3691
        VIR_FREE(model_info->props[i].name);
3692 3693 3694
        if (model_info->props[i].type == QEMU_MONITOR_CPU_PROPERTY_STRING)
            VIR_FREE(model_info->props[i].value.string);
    }
3695

3696
    VIR_FREE(model_info->props);
3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722
    VIR_FREE(model_info->name);
    VIR_FREE(model_info);
}


qemuMonitorCPUModelInfoPtr
qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig)
{
    qemuMonitorCPUModelInfoPtr copy;
    size_t i;

    if (VIR_ALLOC(copy) < 0)
        goto error;

    if (VIR_ALLOC_N(copy->props, orig->nprops) < 0)
        goto error;

    if (VIR_STRDUP(copy->name, orig->name) < 0)
        goto error;

    copy->nprops = orig->nprops;

    for (i = 0; i < orig->nprops; i++) {
        if (VIR_STRDUP(copy->props[i].name, orig->props[i].name) < 0)
            goto error;

3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741
        copy->props[i].type = orig->props[i].type;
        switch (orig->props[i].type) {
        case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
            copy->props[i].value.boolean = orig->props[i].value.boolean;
            break;

        case QEMU_MONITOR_CPU_PROPERTY_STRING:
            if (VIR_STRDUP(copy->props[i].value.string,
                           orig->props[i].value.string) < 0)
                goto error;
            break;

        case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
            copy->props[i].value.number = orig->props[i].value.number;
            break;

        case QEMU_MONITOR_CPU_PROPERTY_LAST:
            break;
        }
3742 3743 3744 3745 3746 3747 3748 3749 3750 3751
    }

    return copy;

 error:
    qemuMonitorCPUModelInfoFree(copy);
    return NULL;
}


3752 3753 3754
int
qemuMonitorGetCommands(qemuMonitorPtr mon,
                       char ***commands)
3755
{
3756
    VIR_DEBUG("commands=%p", commands);
3757

3758
    QEMU_CHECK_MONITOR_JSON(mon);
3759 3760 3761

    return qemuMonitorJSONGetCommands(mon, commands);
}
3762 3763


3764 3765 3766
int
qemuMonitorGetEvents(qemuMonitorPtr mon,
                     char ***events)
3767
{
3768
    VIR_DEBUG("events=%p", events);
3769

3770
    QEMU_CHECK_MONITOR_JSON(mon);
3771 3772 3773

    return qemuMonitorJSONGetEvents(mon, events);
}
3774 3775


3776 3777 3778 3779 3780
/* Collect the parameters associated with a given command line option.
 * Return count of known parameters or -1 on error.  */
int
qemuMonitorGetCommandLineOptionParameters(qemuMonitorPtr mon,
                                          const char *option,
3781 3782
                                          char ***params,
                                          bool *found)
3783
{
3784
    VIR_DEBUG("option=%s params=%p", option, params);
3785

3786
    QEMU_CHECK_MONITOR_JSON(mon);
3787

3788 3789
    return qemuMonitorJSONGetCommandLineOptionParameters(mon, option,
                                                         params, found);
3790 3791 3792
}


3793 3794 3795 3796
int
qemuMonitorGetKVMState(qemuMonitorPtr mon,
                       bool *enabled,
                       bool *present)
3797
{
3798
    VIR_DEBUG("enabled=%p present=%p", enabled, present);
3799

3800
    QEMU_CHECK_MONITOR_JSON(mon);
3801 3802 3803 3804 3805

    return qemuMonitorJSONGetKVMState(mon, enabled, present);
}


3806 3807 3808
int
qemuMonitorGetObjectTypes(qemuMonitorPtr mon,
                          char ***types)
3809
{
3810
    VIR_DEBUG("types=%p", types);
3811

3812
    QEMU_CHECK_MONITOR_JSON(mon);
3813 3814 3815

    return qemuMonitorJSONGetObjectTypes(mon, types);
}
3816 3817


3818 3819 3820 3821
int
qemuMonitorGetObjectProps(qemuMonitorPtr mon,
                          const char *type,
                          char ***props)
3822
{
3823
    VIR_DEBUG("type=%s props=%p", type, props);
3824

3825
    QEMU_CHECK_MONITOR_JSON(mon);
3826 3827 3828

    return qemuMonitorJSONGetObjectProps(mon, type, props);
}
3829 3830


3831 3832
char *
qemuMonitorGetTargetArch(qemuMonitorPtr mon)
3833
{
3834
    QEMU_CHECK_MONITOR_JSON_NULL(mon);
3835 3836 3837

    return qemuMonitorJSONGetTargetArch(mon);
}
3838 3839


3840 3841 3842 3843
int
qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon,
                                    char ***capabilities)
{
3844
    QEMU_CHECK_MONITOR(mon);
3845 3846 3847 3848 3849 3850 3851 3852 3853

    /* No capability is supported without JSON monitor */
    if (!mon->json)
        return 0;

    return qemuMonitorJSONGetMigrationCapabilities(mon, capabilities);
}


3854 3855 3856
/**
 * Returns 1 if @capability is supported, 0 if it's not, or -1 on error.
 */
3857 3858 3859
int
qemuMonitorGetMigrationCapability(qemuMonitorPtr mon,
                                  qemuMonitorMigrationCaps capability)
3860
{
3861
    VIR_DEBUG("capability=%d", capability);
3862

3863
    QEMU_CHECK_MONITOR(mon);
3864 3865 3866 3867 3868 3869 3870 3871

    /* No capability is supported without JSON monitor */
    if (!mon->json)
        return 0;

    return qemuMonitorJSONGetMigrationCapability(mon, capability);
}

3872 3873 3874 3875 3876

int
qemuMonitorSetMigrationCapability(qemuMonitorPtr mon,
                                  qemuMonitorMigrationCaps capability,
                                  bool state)
3877
{
3878
    VIR_DEBUG("capability=%d", capability);
3879

3880
    QEMU_CHECK_MONITOR_JSON(mon);
3881

3882
    return qemuMonitorJSONSetMigrationCapability(mon, capability, state);
3883
}
3884

3885

A
Andrea Bolognani 已提交
3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902
/**
 * qemuMonitorGetGICCapabilities:
 * @mon: QEMU monitor
 * @capabilities: where to store the GIC capabilities
 *
 * See qemuMonitorJSONGetGICCapabilities().
 */
int
qemuMonitorGetGICCapabilities(qemuMonitorPtr mon,
                              virGICCapability **capabilities)
{
    QEMU_CHECK_MONITOR_JSON(mon);

    return qemuMonitorJSONGetGICCapabilities(mon, capabilities);
}


3903 3904 3905 3906
int
qemuMonitorNBDServerStart(qemuMonitorPtr mon,
                          const char *host,
                          unsigned int port)
3907
{
3908
    VIR_DEBUG("host=%s port=%u", host, port);
3909

3910
    QEMU_CHECK_MONITOR_JSON(mon);
3911 3912 3913

    return qemuMonitorJSONNBDServerStart(mon, host, port);
}
3914

3915 3916 3917 3918 3919

int
qemuMonitorNBDServerAdd(qemuMonitorPtr mon,
                        const char *deviceID,
                        bool writable)
3920
{
3921
    VIR_DEBUG("deviceID=%s", deviceID);
3922

3923
    QEMU_CHECK_MONITOR_JSON(mon);
3924 3925 3926

    return qemuMonitorJSONNBDServerAdd(mon, deviceID, writable);
}
3927

3928 3929 3930

int
qemuMonitorNBDServerStop(qemuMonitorPtr mon)
3931
{
3932
    QEMU_CHECK_MONITOR_JSON(mon);
3933 3934 3935

    return qemuMonitorJSONNBDServerStop(mon);
}
S
Stefan Berger 已提交
3936 3937


3938 3939
int
qemuMonitorGetTPMModels(qemuMonitorPtr mon,
S
Stefan Berger 已提交
3940 3941
                            char ***tpmmodels)
{
3942
    VIR_DEBUG("tpmmodels=%p", tpmmodels);
S
Stefan Berger 已提交
3943

3944
    QEMU_CHECK_MONITOR_JSON(mon);
S
Stefan Berger 已提交
3945 3946 3947 3948 3949

    return qemuMonitorJSONGetTPMModels(mon, tpmmodels);
}


3950 3951 3952
int
qemuMonitorGetTPMTypes(qemuMonitorPtr mon,
                       char ***tpmtypes)
S
Stefan Berger 已提交
3953
{
3954
    VIR_DEBUG("tpmtypes=%p", tpmtypes);
S
Stefan Berger 已提交
3955

3956
    QEMU_CHECK_MONITOR_JSON(mon);
S
Stefan Berger 已提交
3957 3958 3959

    return qemuMonitorJSONGetTPMTypes(mon, tpmtypes);
}
3960

3961 3962 3963 3964 3965

int
qemuMonitorAttachCharDev(qemuMonitorPtr mon,
                         const char *chrID,
                         virDomainChrSourceDefPtr chr)
3966
{
3967
    VIR_DEBUG("chrID=%s chr=%p", chrID, chr);
3968

3969
    QEMU_CHECK_MONITOR_JSON(mon);
3970 3971 3972

    return qemuMonitorJSONAttachCharDev(mon, chrID, chr);
}
3973

3974 3975 3976 3977

int
qemuMonitorDetachCharDev(qemuMonitorPtr mon,
                         const char *chrID)
3978
{
3979
    VIR_DEBUG("chrID=%s", chrID);
3980

3981
    QEMU_CHECK_MONITOR_JSON(mon);
3982 3983 3984

    return qemuMonitorJSONDetachCharDev(mon, chrID);
}
3985

3986

3987 3988 3989 3990
int
qemuMonitorGetDeviceAliases(qemuMonitorPtr mon,
                            char ***aliases)
{
3991
    VIR_DEBUG("aliases=%p", aliases);
3992

3993
    QEMU_CHECK_MONITOR_JSON(mon);
3994 3995 3996

    return qemuMonitorJSONGetDeviceAliases(mon, aliases);
}
3997 3998 3999 4000 4001 4002 4003 4004


/**
 * qemuMonitorSetDomainLog:
 * Set the file descriptor of the open VM log file to report potential
 * early startup errors of qemu.
 *
 * @mon: Monitor object to set the log file reading on
4005 4006 4007
 * @func: the callback to report errors
 * @opaque: data to pass to @func
 * @destroy: optional callback to free @opaque
4008
 */
4009 4010 4011 4012 4013
void
qemuMonitorSetDomainLog(qemuMonitorPtr mon,
                        qemuMonitorReportDomainLogError func,
                        void *opaque,
                        virFreeCallback destroy)
4014
{
4015 4016
    if (mon->logDestroy && mon->logOpaque)
        mon->logDestroy(mon->logOpaque);
4017

4018 4019 4020
    mon->logFunc = func;
    mon->logOpaque = opaque;
    mon->logDestroy = destroy;
4021
}
4022 4023 4024 4025 4026 4027


/**
 * qemuMonitorJSONGetGuestCPU:
 * @mon: Pointer to the monitor
 * @arch: arch of the guest
4028
 * @data: returns the cpu data
4029
 * @disabled: returns the CPU data for features which were disabled by QEMU
4030 4031 4032
 *
 * Retrieve the definition of the guest CPU from a running qemu instance.
 *
4033 4034
 * Returns 0 on success, -2 if the operation is not supported by the guest,
 * -1 on other errors.
4035
 */
4036
int
4037
qemuMonitorGetGuestCPU(qemuMonitorPtr mon,
4038
                       virArch arch,
4039 4040
                       virCPUDataPtr *data,
                       virCPUDataPtr *disabled)
4041
{
4042 4043
    VIR_DEBUG("arch=%s data=%p disabled=%p",
              virArchToString(arch), data, disabled);
4044

4045
    QEMU_CHECK_MONITOR_JSON(mon);
4046

4047
    *data = NULL;
4048 4049
    if (disabled)
        *disabled = NULL;
4050

4051
    return qemuMonitorJSONGetGuestCPU(mon, arch, data, disabled);
4052
}
4053

4054

4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069
/**
 * qemuMonitorRTCResetReinjection:
 * @mon: Pointer to the monitor
 *
 * Issue rtc-reset-reinjection command.
 * This should be used in cases where guest time is restored via
 * guest agent, so RTC injection is not needed (in fact it would
 * confuse guest's RTC).
 *
 * Returns 0 on success
 *        -1 on error.
 */
int
qemuMonitorRTCResetReinjection(qemuMonitorPtr mon)
{
4070
    QEMU_CHECK_MONITOR_JSON(mon);
4071 4072 4073

    return qemuMonitorJSONRTCResetReinjection(mon);
}
4074

4075

4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088
/**
 * qemuMonitorGetIOThreads:
 * @mon: Pointer to the monitor
 * @iothreads: Location to return array of IOThreadInfo data
 *
 * Issue query-iothreads command.
 * Retrieve the list of iothreads defined/running for the machine
 *
 * Returns count of IOThreadInfo structures on success
 *        -1 on error.
 */
int
qemuMonitorGetIOThreads(qemuMonitorPtr mon,
4089
                        qemuMonitorIOThreadInfoPtr **iothreads)
4090 4091
{

4092
    VIR_DEBUG("iothreads=%p", iothreads);
4093

4094
    QEMU_CHECK_MONITOR(mon);
4095

4096
    /* Requires JSON to make the query */
4097
    if (!mon->json) {
4098 4099
        *iothreads = NULL;
        return 0;
4100 4101 4102 4103 4104
    }

    return qemuMonitorJSONGetIOThreads(mon, iothreads);
}

4105

4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121
/**
 * qemuMonitorGetMemoryDeviceInfo:
 * @mon: pointer to the monitor
 * @info: Location to return the hash of qemuMonitorMemoryDeviceInfo
 *
 * Retrieve state and addresses of frontend memory devices present in
 * the guest.
 *
 * Returns 0 on success and fills @info with a newly allocated struct; if the
 * data can't be retrieved due to lack of support in qemu, returns -2. On
 * other errors returns -1.
 */
int
qemuMonitorGetMemoryDeviceInfo(qemuMonitorPtr mon,
                               virHashTablePtr *info)
{
4122
    VIR_DEBUG("info=%p", info);
4123 4124 4125 4126
    int ret;

    *info = NULL;

4127
    QEMU_CHECK_MONITOR(mon);
4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141

    if (!mon->json)
        return -2;

    if (!(*info = virHashCreate(10, virHashValueFree)))
        return -1;

    if ((ret = qemuMonitorJSONGetMemoryDeviceInfo(mon, *info)) < 0) {
        virHashFree(*info);
        *info = NULL;
    }

    return ret;
}
4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153


int
qemuMonitorMigrateIncoming(qemuMonitorPtr mon,
                           const char *uri)
{
    VIR_DEBUG("uri=%s", uri);

    QEMU_CHECK_MONITOR_JSON(mon);

    return qemuMonitorJSONMigrateIncoming(mon, uri);
}
4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164


int
qemuMonitorMigrateStartPostCopy(qemuMonitorPtr mon)
{
    VIR_DEBUG("mon=%p", mon);

    QEMU_CHECK_MONITOR_JSON(mon);

    return qemuMonitorJSONMigrateStartPostCopy(mon);
}
4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175

int
qemuMonitorGetRTCTime(qemuMonitorPtr mon,
                      struct tm *tm)
{
    VIR_DEBUG("mon=%p", mon);

    QEMU_CHECK_MONITOR_JSON(mon);

    return qemuMonitorJSONGetRTCTime(mon, tm);
}
4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186


virHashTablePtr
qemuMonitorQueryQMPSchema(qemuMonitorPtr mon)
{
    VIR_DEBUG("mon=%p", mon);

    QEMU_CHECK_MONITOR_JSON_NULL(mon);

    return qemuMonitorJSONQueryQMPSchema(mon);
}