You need to sign in or sign up before continuing.
qemu_monitor.c 101.4 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
qemuMonitorOpenUnix(const char *monitor, pid_t cpid)
331 332 333
{
    struct sockaddr_un addr;
    int monfd;
334 335
    virTimeBackOffVar timeout;
    int ret = -1;
336 337

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

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

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

        if (ret == 0)
            break;

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

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

370
    }
371 372

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

378
    return monfd;
379

380
 error:
381
    VIR_FORCE_CLOSE(monfd);
382 383 384
    return -1;
}

385

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

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

397
    return monfd;
398
}
399

400

401 402 403 404
/* This method processes data that has been received
 * from the monitor. Looking for async events and
 * replies/errors.
 */
405 406 407 408 409 410 411 412 413 414 415
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;

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

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

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

440
    if (len < 0)
441 442
        return -1;

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

446 447 448 449 450 451 452
    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;
    }
453
#if DEBUG_IO
454
    VIR_DEBUG("Process done %d used %d", (int)mon->bufferOffset, len);
455
#endif
456 457 458 459 460 461
    if (msg && msg->finished)
        virCondBroadcast(&mon->notify);
    return len;
}


S
Stefan Berger 已提交
462
/* Call this function while holding the monitor lock. */
463 464 465 466 467 468 469 470 471 472 473 474 475
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));
476
    memset(control, 0, sizeof(control));
477 478 479 480 481 482 483 484 485 486 487

    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);
488 489 490
    /* 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);
491 492 493 494 495 496 497 498 499 500 501 502
    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;
}

503

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

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

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

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

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

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

542 543 544 545
    if (done < 0) {
        if (errno == EAGAIN)
            return 0;

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

554

555 556
/*
 * Called when the monitor has incoming data to read
S
Stefan Berger 已提交
557
 * Call this function while holding the monitor lock.
558 559 560 561 562 563 564 565 566 567 568
 *
 * 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,
569
                          mon->bufferLength + 1024) < 0)
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
            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;
585 586
            virReportSystemError(errno, "%s",
                                 _("Unable to read from monitor"));
587 588 589 590 591 592 593 594 595 596 597 598
            ret = -1;
            break;
        }
        if (got == 0)
            break;

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

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

    return ret;
}


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

614 615 616
    if (!mon->watch)
        return;

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

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

    virEventUpdateHandle(mon->watch, events);
626 627
}

628 629

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

637 638
    virObjectRef(mon);

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

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

        if (!error &&
672 673
            events & VIR_EVENT_HANDLE_READABLE) {
            int got = qemuMonitorIORead(mon);
674 675
            events &= ~VIR_EVENT_HANDLE_READABLE;
            if (got < 0) {
676
                error = true;
677 678
                if (errno == ECONNRESET)
                    hangup = true;
679 680 681 682 683
            } 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 */
684 685 686
                events = 0;

                if (qemuMonitorIOProcess(mon) < 0)
687
                    error = true;
688
            }
689 690
        }

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

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

716
    if (error || eof) {
717
        if (hangup && mon->logFunc != NULL) {
718 719
            /* 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
720 721 722
             * startup phases or during incoming migration when the message
             * from qemu is certainly more interesting than a
             * "connection reset by peer" message.
723
             */
724
            mon->logFunc(mon,
725
                         _("qemu unexpectedly closed the monitor"),
726
                         mon->logOpaque);
727 728
            virCopyLastError(&mon->lastError);
            virResetLastError();
729 730
        }

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

    qemuMonitorUpdateWatch(mon);

754 755 756
    /* 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 */
757
    if (eof) {
J
Jiri Denemark 已提交
758
        qemuMonitorEofNotifyCallback eofNotify = mon->cb->eofNotify;
759
        virDomainObjPtr vm = mon->vm;
760

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

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


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

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

805 806 807
    if (qemuMonitorInitialize() < 0)
        return NULL;

808
    if (!(mon = virObjectLockableNew(qemuMonitorClass)))
809 810
        return NULL;

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

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


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

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

858 859
    return mon;

860
 cleanup:
861 862 863 864 865 866
    /* 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;
867 868
    /* The caller owns 'fd' on failure */
    mon->fd = -1;
869 870 871 872
    qemuMonitorClose(mon);
    return NULL;
}

873

874 875 876
qemuMonitorPtr
qemuMonitorOpen(virDomainObjPtr vm,
                virDomainChrSourceDefPtr config,
E
Eric Blake 已提交
877
                bool json,
878 879
                qemuMonitorCallbacksPtr cb,
                void *opaque)
880 881 882 883 884 885 886 887
{
    int fd;
    bool hasSendFD = false;
    qemuMonitorPtr ret;

    switch (config->type) {
    case VIR_DOMAIN_CHR_TYPE_UNIX:
        hasSendFD = true;
888
        if ((fd = qemuMonitorOpenUnix(config->data.nix.path, vm ? vm->pid : 0)) < 0)
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
            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;
    }

904
    ret = qemuMonitorOpenInternal(vm, fd, hasSendFD, json, cb, opaque);
905 906 907 908 909 910
    if (!ret)
        VIR_FORCE_CLOSE(fd);
    return ret;
}


911 912 913 914 915 916
qemuMonitorPtr
qemuMonitorOpenFD(virDomainObjPtr vm,
                  int sockfd,
                  bool json,
                  qemuMonitorCallbacksPtr cb,
                  void *opaque)
917
{
918
    return qemuMonitorOpenInternal(vm, sockfd, true, json, cb, opaque);
919 920
}

921

922 923 924 925 926 927 928 929 930
void
qemuMonitorUnregister(qemuMonitorPtr mon)
{
    if (mon->watch) {
        virEventRemoveHandle(mon->watch);
        mon->watch = 0;
    }
}

931 932
void
qemuMonitorClose(qemuMonitorPtr mon)
933 934
{
    if (!mon)
935
        return;
936

937
    virObjectLock(mon);
938
    PROBE(QEMU_MONITOR_CLOSE,
939
          "mon=%p refs=%d", mon, mon->parent.parent.u.s.refs);
S
Stefan Berger 已提交
940

941
    qemuMonitorSetDomainLog(mon, NULL, NULL, NULL);
942

S
Stefan Berger 已提交
943
    if (mon->fd >= 0) {
944
        qemuMonitorUnregister(mon);
S
Stefan Berger 已提交
945
        VIR_FORCE_CLOSE(mon->fd);
946
    }
947

948 949 950 951 952 953 954
    /* 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();

955 956
            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                           _("Qemu monitor was closed"));
957 958 959 960 961 962 963 964 965 966 967 968
            virCopyLastError(&mon->lastError);
            if (err) {
                virSetError(err);
                virFreeError(err);
            } else {
                virResetLastError();
            }
        }
        mon->msg->finished = 1;
        virCondSignal(&mon->notify);
    }

969 970 971 972 973 974
    /* Propagate existing monitor error in case the current thread has no
     * error set.
     */
    if (mon->lastError.code != VIR_ERR_OK && !virGetLastError())
        virSetError(&mon->lastError);

975
    virObjectUnlock(mon);
976
    virObjectUnref(mon);
977 978 979
}


980 981
char *
qemuMonitorNextCommandID(qemuMonitorPtr mon)
982 983 984
{
    char *id;

985
    ignore_value(virAsprintf(&id, "libvirt-%d", ++mon->nextSerial));
986 987 988 989
    return id;
}


990 991 992
int
qemuMonitorSend(qemuMonitorPtr mon,
                qemuMonitorMessagePtr msg)
993
{
994
    int ret = -1;
995

E
Eric Blake 已提交
996
    /* Check whether qemu quit unexpectedly */
997 998 999 1000
    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);
1001 1002 1003
        return -1;
    }

1004 1005
    mon->msg = msg;
    qemuMonitorUpdateWatch(mon);
1006

1007 1008 1009 1010
    PROBE(QEMU_MONITOR_SEND_MSG,
          "mon=%p msg=%s fd=%d",
          mon, mon->msg->txBuffer, mon->msg->txFD);

1011
    while (!mon->msg->finished) {
1012
        if (virCondWait(&mon->notify, &mon->parent.lock) < 0) {
1013 1014
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Unable to wait on monitor condition"));
1015
            goto cleanup;
1016 1017 1018 1019 1020 1021 1022 1023
        }
    }

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

1026
    ret = 0;
1027

1028
 cleanup:
1029 1030
    mon->msg = NULL;
    qemuMonitorUpdateWatch(mon);
1031

1032
    return ret;
1033
}
1034 1035


1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
/**
 * 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);
}


1050 1051 1052 1053 1054 1055
virJSONValuePtr
qemuMonitorGetOptions(qemuMonitorPtr mon)
{
    return mon->options;
}

1056

1057 1058 1059 1060 1061 1062
void
qemuMonitorSetOptions(qemuMonitorPtr mon, virJSONValuePtr options)
{
    mon->options = options;
}

1063 1064

/**
1065 1066 1067
 * 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".
1068 1069 1070 1071 1072
 *
 * 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.
 */
1073
static void
1074 1075
qemuMonitorInitBalloonObjectPath(qemuMonitorPtr mon,
                                 virDomainMemballoonDefPtr balloon)
1076 1077 1078
{
    ssize_t i, nprops = 0;
    char *path = NULL;
1079
    const char *name;
1080 1081 1082
    qemuMonitorJSONListPathPtr *bprops = NULL;

    if (mon->balloonpath) {
1083
        return;
1084 1085 1086
    } else if (mon->ballooninit) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Cannot determine balloon device path"));
1087
        return;
1088
    }
1089
    mon->ballooninit = true;
1090

1091 1092 1093 1094 1095 1096 1097 1098
    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:
1099
        return;
1100
    }
1101

1102 1103 1104
    if (qemuMonitorJSONFindLinkPath(mon, name, balloon->info.alias, &path) < 0)
        return;

1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128
    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);
1129
    return;
1130 1131
}

1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146

/**
 * 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;

1147 1148
    QEMU_CHECK_MONITOR(mon);

1149
    if (mon->json) {
1150 1151
        ret = qemuMonitorJSONFindLinkPath(mon, videoName,
                                          video->info.alias, &path);
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
        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;
}


1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185
/**
 * 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) {
1186 1187
        ret = qemuMonitorJSONFindLinkPath(mon, videoName,
                                          video->info.alias, &path);
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204
        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;
}


1205 1206 1207 1208 1209
int
qemuMonitorHMPCommandWithFd(qemuMonitorPtr mon,
                            const char *cmd,
                            int scm_fd,
                            char **reply)
1210
{
1211 1212 1213
    char *json_cmd = NULL;
    int ret = -1;

1214 1215
    QEMU_CHECK_MONITOR(mon);

1216 1217 1218 1219 1220
    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);
1221 1222
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Unable to unescape command"));
1223 1224 1225 1226 1227 1228 1229
            goto cleanup;
        }
        ret = qemuMonitorJSONHumanCommandWithFd(mon, json_cmd, scm_fd, reply);
    } else {
        ret = qemuMonitorTextCommandWithFd(mon, cmd, scm_fd, reply);
    }

1230
 cleanup:
1231 1232
    VIR_FREE(json_cmd);
    return ret;
1233 1234
}

1235

E
Eric Blake 已提交
1236 1237 1238
/* Ensure proper locking around callbacks.  */
#define QEMU_MONITOR_CALLBACK(mon, ret, callback, ...)          \
    do {                                                        \
1239
        virObjectRef(mon);                                      \
1240
        virObjectUnlock(mon);                                   \
E
Eric Blake 已提交
1241
        if ((mon)->cb && (mon)->cb->callback)                   \
1242 1243
            (ret) = (mon)->cb->callback(mon, __VA_ARGS__,       \
                                        (mon)->callbackOpaque); \
1244
        virObjectLock(mon);                                     \
1245
        virObjectUnref(mon);                                    \
E
Eric Blake 已提交
1246
    } while (0)
1247

1248 1249 1250 1251 1252 1253 1254

int
qemuMonitorGetDiskSecret(qemuMonitorPtr mon,
                         virConnectPtr conn,
                         const char *path,
                         char **secret,
                         size_t *secretLen)
1255
{
1256
    int ret = -1;
1257 1258 1259
    *secret = NULL;
    *secretLen = 0;

E
Eric Blake 已提交
1260 1261
    QEMU_MONITOR_CALLBACK(mon, ret, diskSecretLookup, conn, mon->vm,
                          path, secret, secretLen);
1262
    return ret;
1263
}
1264 1265


1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279
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;
}


1280 1281
int
qemuMonitorEmitShutdown(qemuMonitorPtr mon)
1282 1283 1284 1285
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1286
    QEMU_MONITOR_CALLBACK(mon, ret, domainShutdown, mon->vm);
1287 1288 1289 1290
    return ret;
}


1291 1292
int
qemuMonitorEmitReset(qemuMonitorPtr mon)
1293 1294 1295 1296
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1297
    QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm);
1298 1299 1300 1301
    return ret;
}


1302 1303
int
qemuMonitorEmitPowerdown(qemuMonitorPtr mon)
1304 1305 1306 1307
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1308
    QEMU_MONITOR_CALLBACK(mon, ret, domainPowerdown, mon->vm);
1309 1310 1311 1312
    return ret;
}


1313 1314
int
qemuMonitorEmitStop(qemuMonitorPtr mon)
1315 1316 1317 1318
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1319
    QEMU_MONITOR_CALLBACK(mon, ret, domainStop, mon->vm);
1320 1321 1322 1323
    return ret;
}


1324 1325
int
qemuMonitorEmitResume(qemuMonitorPtr mon)
1326 1327 1328 1329 1330 1331 1332 1333 1334
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

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


1335 1336
int
qemuMonitorEmitGuestPanic(qemuMonitorPtr mon)
1337 1338 1339 1340 1341 1342 1343 1344
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);
    QEMU_MONITOR_CALLBACK(mon, ret, domainGuestPanic, mon->vm);
    return ret;
}


1345 1346
int
qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset)
1347 1348 1349 1350
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1351
    QEMU_MONITOR_CALLBACK(mon, ret, domainRTCChange, mon->vm, offset);
1352 1353 1354 1355
    return ret;
}


1356 1357
int
qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action)
1358 1359 1360 1361
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1362
    QEMU_MONITOR_CALLBACK(mon, ret, domainWatchdog, mon->vm, action);
1363 1364 1365 1366
    return ret;
}


1367 1368 1369 1370 1371
int
qemuMonitorEmitIOError(qemuMonitorPtr mon,
                       const char *diskAlias,
                       int action,
                       const char *reason)
1372 1373 1374 1375
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1376 1377
    QEMU_MONITOR_CALLBACK(mon, ret, domainIOError, mon->vm,
                          diskAlias, action, reason);
1378 1379 1380 1381
    return ret;
}


1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393
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)
1394 1395 1396 1397
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
1398 1399 1400 1401
    QEMU_MONITOR_CALLBACK(mon, ret, domainGraphics, mon->vm, phase,
                          localFamily, localNode, localService,
                          remoteFamily, remoteNode, remoteService,
                          authScheme, x509dname, saslUsername);
1402 1403 1404
    return ret;
}

1405 1406 1407 1408 1409

int
qemuMonitorEmitTrayChange(qemuMonitorPtr mon,
                          const char *devAlias,
                          int reason)
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

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

    return ret;
}

1420 1421 1422

int
qemuMonitorEmitPMWakeup(qemuMonitorPtr mon)
O
Osier Yang 已提交
1423 1424 1425 1426 1427 1428 1429 1430 1431
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

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

    return ret;
}

1432 1433 1434

int
qemuMonitorEmitPMSuspend(qemuMonitorPtr mon)
O
Osier Yang 已提交
1435 1436 1437 1438 1439 1440 1441 1442 1443
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

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

    return ret;
}

1444 1445 1446

int
qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon)
1447 1448 1449 1450 1451 1452 1453 1454 1455
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

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

    return ret;
}

1456 1457 1458 1459 1460 1461

int
qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
                        const char *diskAlias,
                        int type,
                        int status)
1462 1463 1464 1465 1466 1467 1468 1469 1470
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

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

1471

1472 1473 1474
int
qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
                             unsigned long long actual)
1475 1476 1477 1478 1479 1480 1481 1482
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

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

1483

1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496
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;
}


1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509
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;
}


1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523
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;
}


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

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

    return ret;
}


1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
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;
}


1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562
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;
}


1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581
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;
}


1582 1583
int
qemuMonitorSetCapabilities(qemuMonitorPtr mon)
1584
{
1585
    QEMU_CHECK_MONITOR(mon);
1586

1587 1588
    if (!mon->json)
        return 0;
1589

1590
    return qemuMonitorJSONSetCapabilities(mon);
1591 1592 1593
}


1594 1595 1596 1597
int
qemuMonitorStartCPUs(qemuMonitorPtr mon,
                     virConnectPtr conn)
{
1598
    QEMU_CHECK_MONITOR(mon);
1599

D
Daniel P. Berrange 已提交
1600
    if (mon->json)
1601
        return qemuMonitorJSONStartCPUs(mon, conn);
D
Daniel P. Berrange 已提交
1602
    else
1603
        return qemuMonitorTextStartCPUs(mon, conn);
1604 1605 1606 1607 1608 1609
}


int
qemuMonitorStopCPUs(qemuMonitorPtr mon)
{
1610
    QEMU_CHECK_MONITOR(mon);
1611

D
Daniel P. Berrange 已提交
1612
    if (mon->json)
1613
        return qemuMonitorJSONStopCPUs(mon);
D
Daniel P. Berrange 已提交
1614
    else
1615
        return qemuMonitorTextStopCPUs(mon);
1616 1617 1618
}


1619 1620 1621 1622 1623 1624 1625 1626
int
qemuMonitorCheck(qemuMonitorPtr mon)
{
    bool running;
    return qemuMonitorGetStatus(mon, &running, NULL);
}


1627
int
1628 1629 1630
qemuMonitorGetStatus(qemuMonitorPtr mon,
                     bool *running,
                     virDomainPausedReason *reason)
1631
{
1632
    VIR_DEBUG("running=%p, reason=%p", running, reason);
1633

1634
    QEMU_CHECK_MONITOR(mon);
1635 1636

    if (mon->json)
1637
        return qemuMonitorJSONGetStatus(mon, running, reason);
1638
    else
1639
        return qemuMonitorTextGetStatus(mon, running, reason);
1640 1641 1642
}


1643 1644
int
qemuMonitorSystemPowerdown(qemuMonitorPtr mon)
1645
{
1646
    QEMU_CHECK_MONITOR(mon);
1647

D
Daniel P. Berrange 已提交
1648
    if (mon->json)
1649
        return qemuMonitorJSONSystemPowerdown(mon);
D
Daniel P. Berrange 已提交
1650
    else
1651
        return qemuMonitorTextSystemPowerdown(mon);
1652 1653 1654
}


1655 1656
int
qemuMonitorSystemReset(qemuMonitorPtr mon)
1657
{
1658
    QEMU_CHECK_MONITOR(mon);
1659 1660

    if (mon->json)
1661
        return qemuMonitorJSONSystemReset(mon);
1662
    else
1663
        return qemuMonitorTextSystemReset(mon);
1664 1665 1666
}


1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687
static void
qemuMonitorCPUInfoClear(qemuMonitorCPUInfoPtr cpus,
                        size_t ncpus)
{
    size_t i;

    for (i = 0; i < ncpus; i++) {
        cpus[i].id = 0;
        cpus[i].socket_id = -1;
        cpus[i].core_id = -1;
        cpus[i].thread_id = -1;
        cpus[i].vcpus = 0;
        cpus[i].tid = 0;

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


1688 1689
void
qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr cpus,
1690
                       size_t ncpus)
1691 1692 1693 1694
{
    if (!cpus)
        return;

1695 1696
    qemuMonitorCPUInfoClear(cpus, ncpus);

1697 1698 1699
    VIR_FREE(cpus);
}

1700 1701
void
qemuMonitorQueryCpusFree(struct qemuMonitorQueryCpusEntry *entries,
1702
                         size_t nentries)
1703
{
1704 1705
    size_t i;

1706 1707 1708
    if (!entries)
        return;

1709 1710 1711
    for (i = 0; i < nentries; i++)
        VIR_FREE(entries[i].qom_path);

1712 1713 1714
    VIR_FREE(entries);
}

1715

1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774
/**
 * 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++) {
        if (i < ncpuentries)
            vcpus[i].tid = cpuentries[i].tid;

        /* 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;
1775
    size_t mastervcpu; /* this iterator is used for iterating hotpluggable entities */
1776
    size_t anyvcpu; /* this iterator is used for any vcpu entry in the result */
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 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816
    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 */
1817
    mastervcpu = 0;
1818
    for (i = 0; i < nhotplugvcpus; i++) {
1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829
        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;

        /* calculate next master vcpu (hotpluggable unit) entry */
        mastervcpu += hotplugvcpus[i].vcpus;
1830 1831 1832 1833 1834 1835
    }

    /* 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 */
1836 1837 1838
        for (anyvcpu = 0; anyvcpu < maxvcpus; anyvcpu++) {
            if (cpuentries[j].qom_path && vcpus[anyvcpu].qom_path &&
                STREQ(cpuentries[j].qom_path, vcpus[anyvcpu].qom_path))
1839 1840 1841
                break;
        }

1842
        if (anyvcpu == maxvcpus) {
1843 1844 1845 1846 1847
            VIR_DEBUG("too many query-cpus entries for a given "
                      "query-hotpluggable-cpus entry");
            return -1;
        }

1848
        if (vcpus[anyvcpu].vcpus != 1) {
1849
            /* find a possibly empty vcpu thread for core granularity systems */
1850 1851
            for (; anyvcpu < maxvcpus; anyvcpu++) {
                if (vcpus[anyvcpu].tid == 0)
1852 1853 1854 1855
                    break;
            }
        }

1856
        vcpus[anyvcpu].tid = cpuentries[j].tid;
1857 1858 1859 1860 1861 1862
    }

    return 0;
}


1863 1864 1865
/**
 * qemuMonitorGetCPUInfo:
 * @mon: monitor
1866 1867
 * @vcpus: pointer filled by array of qemuMonitorCPUInfo structures
 * @maxvcpus: total possible number of vcpus
1868
 * @hotplug: query data relevant for hotplug support
1869 1870 1871 1872
 *
 * 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.
1873
 *
1874 1875
 * Returns 0 on success (including if qemu didn't report any data) and
 *  -1 on error (reports libvirt error).
1876
 */
1877 1878
int
qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
1879
                      qemuMonitorCPUInfoPtr *vcpus,
1880 1881
                      size_t maxvcpus,
                      bool hotplug)
1882
{
1883 1884
    struct qemuMonitorQueryHotpluggableCpusEntry *hotplugcpus = NULL;
    size_t nhotplugcpus = 0;
1885 1886
    struct qemuMonitorQueryCpusEntry *cpuentries = NULL;
    size_t ncpuentries = 0;
1887 1888
    int ret = -1;
    int rc;
1889
    qemuMonitorCPUInfoPtr info = NULL;
1890

1891 1892 1893 1894
    if (hotplug)
        QEMU_CHECK_MONITOR_JSON(mon);
    else
        QEMU_CHECK_MONITOR(mon);
1895

1896 1897 1898
    if (VIR_ALLOC_N(info, maxvcpus) < 0)
        return -1;

1899 1900 1901 1902 1903 1904 1905
    /* initialize a few non-zero defaults */
    qemuMonitorCPUInfoClear(info, maxvcpus);

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

D
Daniel P. Berrange 已提交
1906
    if (mon->json)
1907
        rc = qemuMonitorJSONQueryCPUs(mon, &cpuentries, &ncpuentries);
D
Daniel P. Berrange 已提交
1908
    else
1909
        rc = qemuMonitorTextQueryCPUs(mon, &cpuentries, &ncpuentries);
1910 1911

    if (rc < 0) {
1912 1913 1914 1915 1916
        if (rc == -2) {
            VIR_STEAL_PTR(*vcpus, info);
            ret = 0;
        }

1917 1918 1919
        goto cleanup;
    }

1920 1921 1922 1923 1924 1925 1926 1927 1928
    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);
    }
1929 1930 1931 1932 1933

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

 cleanup:
1934
    qemuMonitorQueryHotpluggableCpusFree(hotplugcpus, nhotplugcpus);
1935
    qemuMonitorQueryCpusFree(cpuentries, ncpuentries);
1936
    qemuMonitorCPUInfoFree(info, maxvcpus);
1937
    return ret;
1938 1939
}

1940 1941 1942 1943 1944

int
qemuMonitorSetLink(qemuMonitorPtr mon,
                   const char *name,
                   virDomainNetInterfaceLinkState state)
1945
{
1946
    VIR_DEBUG("name=%s, state=%u", name, state);
1947

1948
    QEMU_CHECK_MONITOR(mon);
1949 1950

    if (mon->json)
1951
        return qemuMonitorJSONSetLink(mon, name, state);
1952
    else
1953
        return qemuMonitorTextSetLink(mon, name, state);
1954
}
1955

1956 1957 1958

int
qemuMonitorGetVirtType(qemuMonitorPtr mon,
1959
                       virDomainVirtType *virtType)
1960
{
1961
    QEMU_CHECK_MONITOR(mon);
1962 1963

    if (mon->json)
1964
        return qemuMonitorJSONGetVirtType(mon, virtType);
1965
    else
1966
        return qemuMonitorTextGetVirtType(mon, virtType);
1967 1968 1969
}


1970 1971 1972 1973
/**
 * Returns: 0 if balloon not supported, +1 if balloon query worked
 * or -1 on failure
 */
1974 1975 1976
int
qemuMonitorGetBalloonInfo(qemuMonitorPtr mon,
                          unsigned long long *currmem)
1977
{
1978
    QEMU_CHECK_MONITOR(mon);
1979

D
Daniel P. Berrange 已提交
1980
    if (mon->json)
1981
        return qemuMonitorJSONGetBalloonInfo(mon, currmem);
D
Daniel P. Berrange 已提交
1982
    else
1983
        return qemuMonitorTextGetBalloonInfo(mon, currmem);
1984 1985 1986
}


1987 1988
int
qemuMonitorGetMemoryStats(qemuMonitorPtr mon,
1989
                          virDomainMemballoonDefPtr balloon,
1990 1991
                          virDomainMemoryStatPtr stats,
                          unsigned int nr_stats)
1992
{
1993
    VIR_DEBUG("stats=%p nstats=%u", stats, nr_stats);
1994

1995
    QEMU_CHECK_MONITOR(mon);
1996

1997
    if (mon->json) {
1998
        qemuMonitorInitBalloonObjectPath(mon, balloon);
1999 2000
        return qemuMonitorJSONGetMemoryStats(mon, mon->balloonpath,
                                             stats, nr_stats);
2001
    } else {
2002
        return qemuMonitorTextGetMemoryStats(mon, stats, nr_stats);
2003
    }
2004 2005
}

2006

2007 2008 2009 2010 2011 2012 2013
/**
 * qemuMonitorSetMemoryStatsPeriod:
 *
 * This function sets balloon stats update period.
 *
 * Returns 0 on success and -1 on error, but does *not* set an error.
 */
2014 2015
int
qemuMonitorSetMemoryStatsPeriod(qemuMonitorPtr mon,
2016
                                virDomainMemballoonDefPtr balloon,
2017
                                int period)
2018 2019 2020 2021
{
    int ret = -1;
    VIR_DEBUG("mon=%p period=%d", mon, period);

2022
    if (!mon)
2023 2024
        return -1;

2025 2026 2027 2028
    if (!mon->json)
        return -1;

    if (period < 0)
2029 2030
        return -1;

2031
    qemuMonitorInitBalloonObjectPath(mon, balloon);
2032
    if (mon->balloonpath) {
2033 2034
        ret = qemuMonitorJSONSetMemoryStatsPeriod(mon, mon->balloonpath,
                                                  period);
2035 2036 2037 2038 2039 2040 2041 2042 2043

        /*
         * 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();
2044 2045 2046 2047
    }
    return ret;
}

2048

2049 2050 2051 2052 2053 2054
int
qemuMonitorBlockIOStatusToError(const char *status)
{
    int st = qemuMonitorBlockIOStatusTypeFromString(status);

    if (st < 0) {
2055 2056
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown block IO status: %s"), status);
2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074
        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;
}

2075

2076 2077
virHashTablePtr
qemuMonitorGetBlockInfo(qemuMonitorPtr mon)
2078 2079
{
    int ret;
2080 2081
    virHashTablePtr table;

2082
    QEMU_CHECK_MONITOR_NULL(mon);
2083

E
Eric Blake 已提交
2084
    if (!(table = virHashCreate(32, virHashValueFree)))
2085 2086
        return NULL;

2087
    if (mon->json)
2088
        ret = qemuMonitorJSONGetBlockInfo(mon, table);
2089
    else
2090 2091 2092 2093 2094 2095 2096 2097 2098 2099
        ret = qemuMonitorTextGetBlockInfo(mon, table);

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

    return table;
}

2100

2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111
/**
 * 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.
2112 2113 2114
 */
int
qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon,
2115 2116
                                virHashTablePtr *ret_stats,
                                bool backingChain)
2117
{
2118
    int ret = -1;
2119 2120 2121
    VIR_DEBUG("ret_stats=%p, backing=%d", ret_stats, backingChain);

    QEMU_CHECK_MONITOR(mon);
2122

2123 2124 2125
    if (!(*ret_stats = virHashCreate(10, virHashValueFree)))
        goto error;

2126
    if (mon->json) {
2127 2128
        ret = qemuMonitorJSONGetAllBlockStatsInfo(mon, *ret_stats,
                                                  backingChain);
2129 2130 2131 2132 2133 2134 2135 2136
    } else {
         if (backingChain) {
             virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                            _("text monitor doesn't support block stats for "
                              "backing chain members"));
             goto error;
         }

2137
         ret = qemuMonitorTextGetAllBlockStatsInfo(mon, *ret_stats);
2138
    }
2139

2140 2141 2142 2143
    if (ret < 0)
        goto error;

    return ret;
2144 2145 2146 2147 2148

 error:
    virHashFree(*ret_stats);
    *ret_stats = NULL;
    return -1;
2149 2150
}

2151 2152

/* Updates "stats" to fill virtual and physical size of the image */
2153 2154 2155 2156
int
qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr mon,
                                    virHashTablePtr stats,
                                    bool backingChain)
2157
{
2158
    VIR_DEBUG("stats=%p, backing=%d", stats, backingChain);
2159

2160
    QEMU_CHECK_MONITOR_JSON(mon);
2161

2162
    return qemuMonitorJSONBlockStatsUpdateCapacity(mon, stats, backingChain);
2163 2164 2165
}


2166 2167 2168 2169
int
qemuMonitorBlockResize(qemuMonitorPtr mon,
                       const char *device,
                       unsigned long long size)
2170
{
2171 2172 2173
    VIR_DEBUG("device=%s size=%llu", device, size);

    QEMU_CHECK_MONITOR(mon);
2174 2175

    if (mon->json)
2176
        return qemuMonitorJSONBlockResize(mon, device, size);
2177
    else
2178
        return qemuMonitorTextBlockResize(mon, device, size);
2179
}
2180

2181 2182 2183 2184

int
qemuMonitorSetVNCPassword(qemuMonitorPtr mon,
                          const char *password)
2185
{
2186
    VIR_DEBUG("password=%p", password);
2187

2188
    QEMU_CHECK_MONITOR(mon);
2189

2190 2191 2192
    if (!password)
        password = "";

D
Daniel P. Berrange 已提交
2193
    if (mon->json)
2194
        return qemuMonitorJSONSetVNCPassword(mon, password);
D
Daniel P. Berrange 已提交
2195
    else
2196
        return qemuMonitorTextSetVNCPassword(mon, password);
2197 2198
}

2199 2200 2201

static const char *
qemuMonitorTypeToProtocol(int type)
2202 2203 2204 2205 2206 2207 2208
{
    switch (type) {
    case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
        return "vnc";
    case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
        return "spice";
    default:
2209 2210 2211
        virReportError(VIR_ERR_INVALID_ARG,
                       _("unsupported protocol type %s"),
                       virDomainGraphicsTypeToString(type));
2212 2213 2214 2215
        return NULL;
    }
}

2216

2217
/* Returns -2 if not supported with this monitor connection */
2218 2219 2220 2221 2222
int
qemuMonitorSetPassword(qemuMonitorPtr mon,
                       int type,
                       const char *password,
                       const char *action_if_connected)
2223 2224 2225 2226 2227 2228
{
    const char *protocol = qemuMonitorTypeToProtocol(type);

    if (!protocol)
        return -1;

2229 2230
    VIR_DEBUG("protocol=%s, password=%p, action_if_connected=%s",
              protocol, password, action_if_connected);
2231

2232
    QEMU_CHECK_MONITOR(mon);
2233 2234 2235 2236 2237 2238 2239 2240

    if (!password)
        password = "";

    if (!action_if_connected)
        action_if_connected = "keep";

    if (mon->json)
2241
        return qemuMonitorJSONSetPassword(mon, protocol, password, action_if_connected);
2242
    else
2243
        return qemuMonitorTextSetPassword(mon, protocol, password, action_if_connected);
2244 2245
}

2246 2247 2248 2249 2250

int
qemuMonitorExpirePassword(qemuMonitorPtr mon,
                          int type,
                          const char *expire_time)
2251 2252 2253 2254 2255 2256
{
    const char *protocol = qemuMonitorTypeToProtocol(type);

    if (!protocol)
        return -1;

2257
    VIR_DEBUG("protocol=%s, expire_time=%s", protocol, expire_time);
2258

2259
    QEMU_CHECK_MONITOR(mon);
2260 2261 2262 2263 2264

    if (!expire_time)
        expire_time = "now";

    if (mon->json)
2265
        return qemuMonitorJSONExpirePassword(mon, protocol, expire_time);
2266
    else
2267
        return qemuMonitorTextExpirePassword(mon, protocol, expire_time);
2268
}
2269

2270

2271 2272 2273 2274
/*
 * Returns: 0 if balloon not supported, +1 if balloon adjust worked
 * or -1 on failure
 */
2275 2276
int
qemuMonitorSetBalloon(qemuMonitorPtr mon,
2277
                      unsigned long long newmem)
2278
{
2279
    VIR_DEBUG("newmem=%llu", newmem);
2280

2281
    QEMU_CHECK_MONITOR(mon);
2282

D
Daniel P. Berrange 已提交
2283
    if (mon->json)
2284
        return qemuMonitorJSONSetBalloon(mon, newmem);
D
Daniel P. Berrange 已提交
2285
    else
2286
        return qemuMonitorTextSetBalloon(mon, newmem);
2287 2288
}

2289

2290 2291 2292
/*
 * Returns: 0 if CPU modification was successful or -1 on failure
 */
2293 2294
int
qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, bool online)
2295
{
2296
    VIR_DEBUG("cpu=%d online=%d", cpu, online);
2297

2298
    QEMU_CHECK_MONITOR(mon);
2299 2300

    if (mon->json)
2301
        return qemuMonitorJSONSetCPU(mon, cpu, online);
2302
    else
2303
        return qemuMonitorTextSetCPU(mon, cpu, online);
2304 2305 2306
}


2307 2308 2309 2310
int
qemuMonitorEjectMedia(qemuMonitorPtr mon,
                      const char *dev_name,
                      bool force)
2311
{
2312
    VIR_DEBUG("dev_name=%s force=%d", dev_name, force);
2313

2314
    QEMU_CHECK_MONITOR(mon);
2315

D
Daniel P. Berrange 已提交
2316
    if (mon->json)
2317
        return qemuMonitorJSONEjectMedia(mon, dev_name, force);
D
Daniel P. Berrange 已提交
2318
    else
2319
        return qemuMonitorTextEjectMedia(mon, dev_name, force);
2320 2321 2322
}


2323 2324 2325 2326 2327
int
qemuMonitorChangeMedia(qemuMonitorPtr mon,
                       const char *dev_name,
                       const char *newmedia,
                       const char *format)
2328
{
2329
    VIR_DEBUG("dev_name=%s newmedia=%s format=%s", dev_name, newmedia, format);
2330

2331
    QEMU_CHECK_MONITOR(mon);
2332

D
Daniel P. Berrange 已提交
2333
    if (mon->json)
2334
        return qemuMonitorJSONChangeMedia(mon, dev_name, newmedia, format);
D
Daniel P. Berrange 已提交
2335
    else
2336
        return qemuMonitorTextChangeMedia(mon, dev_name, newmedia, format);
2337 2338 2339
}


2340 2341 2342 2343 2344
int
qemuMonitorSaveVirtualMemory(qemuMonitorPtr mon,
                             unsigned long long offset,
                             size_t length,
                             const char *path)
2345
{
2346
    VIR_DEBUG("offset=%llu length=%zu path=%s", offset, length, path);
2347

2348
    QEMU_CHECK_MONITOR(mon);
2349

D
Daniel P. Berrange 已提交
2350
    if (mon->json)
2351
        return qemuMonitorJSONSaveVirtualMemory(mon, offset, length, path);
D
Daniel P. Berrange 已提交
2352
    else
2353
        return qemuMonitorTextSaveVirtualMemory(mon, offset, length, path);
2354 2355
}

2356 2357 2358 2359 2360 2361

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

2365
    QEMU_CHECK_MONITOR(mon);
2366

D
Daniel P. Berrange 已提交
2367
    if (mon->json)
2368
        return qemuMonitorJSONSavePhysicalMemory(mon, offset, length, path);
D
Daniel P. Berrange 已提交
2369
    else
2370
        return qemuMonitorTextSavePhysicalMemory(mon, offset, length, path);
2371 2372 2373
}


2374 2375 2376
int
qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon,
                             unsigned long bandwidth)
2377
{
2378
    VIR_DEBUG("bandwidth=%lu", bandwidth);
2379

2380
    QEMU_CHECK_MONITOR(mon);
2381

2382 2383 2384 2385 2386 2387 2388
    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 已提交
2389
    if (mon->json)
2390
        return qemuMonitorJSONSetMigrationSpeed(mon, bandwidth);
D
Daniel P. Berrange 已提交
2391
    else
2392
        return qemuMonitorTextSetMigrationSpeed(mon, bandwidth);
2393 2394
}

2395

2396 2397 2398
int
qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon,
                                unsigned long long downtime)
2399
{
2400
    VIR_DEBUG("downtime=%llu", downtime);
2401

2402
    QEMU_CHECK_MONITOR(mon);
2403 2404

    if (mon->json)
2405
        return qemuMonitorJSONSetMigrationDowntime(mon, downtime);
2406
    else
2407
        return qemuMonitorTextSetMigrationDowntime(mon, downtime);
2408 2409 2410
}


2411 2412 2413 2414
int
qemuMonitorGetMigrationCacheSize(qemuMonitorPtr mon,
                                 unsigned long long *cacheSize)
{
2415
    VIR_DEBUG("cacheSize=%p", cacheSize);
2416

2417
    QEMU_CHECK_MONITOR_JSON(mon);
2418 2419 2420 2421

    return qemuMonitorJSONGetMigrationCacheSize(mon, cacheSize);
}

2422

2423 2424 2425 2426
int
qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon,
                                 unsigned long long cacheSize)
{
2427
    VIR_DEBUG("cacheSize=%llu", cacheSize);
2428

2429
    QEMU_CHECK_MONITOR_JSON(mon);
2430 2431 2432 2433 2434

    return qemuMonitorJSONSetMigrationCacheSize(mon, cacheSize);
}


2435
int
2436 2437
qemuMonitorGetMigrationParams(qemuMonitorPtr mon,
                              qemuMonitorMigrationParamsPtr params)
2438 2439 2440
{
    QEMU_CHECK_MONITOR_JSON(mon);

2441
    return qemuMonitorJSONGetMigrationParams(mon, params);
2442 2443 2444
}

int
2445 2446
qemuMonitorSetMigrationParams(qemuMonitorPtr mon,
                              qemuMonitorMigrationParamsPtr params)
2447
{
2448
    VIR_DEBUG("compressLevel=%d:%d compressThreads=%d:%d "
2449 2450
              "decompressThreads=%d:%d cpuThrottleInitial=%d:%d "
              "cpuThrottleIncrement=%d:%d",
2451 2452
              params->compressLevel_set, params->compressLevel,
              params->compressThreads_set, params->compressThreads,
2453 2454 2455
              params->decompressThreads_set, params->decompressThreads,
              params->cpuThrottleInitial_set, params->cpuThrottleInitial,
              params->cpuThrottleIncrement_set, params->cpuThrottleIncrement);
2456 2457 2458

    QEMU_CHECK_MONITOR_JSON(mon);

2459 2460
    if (!params->compressLevel_set &&
        !params->compressThreads_set &&
2461 2462 2463
        !params->decompressThreads_set &&
        !params->cpuThrottleInitial_set &&
        !params->cpuThrottleIncrement_set)
2464 2465
        return 0;

2466
    return qemuMonitorJSONSetMigrationParams(mon, params);
2467 2468 2469
}


2470
int
2471 2472
qemuMonitorGetMigrationStats(qemuMonitorPtr mon,
                             qemuMonitorMigrationStatsPtr stats)
2473
{
2474
    QEMU_CHECK_MONITOR(mon);
2475

D
Daniel P. Berrange 已提交
2476
    if (mon->json)
2477
        return qemuMonitorJSONGetMigrationStats(mon, stats);
D
Daniel P. Berrange 已提交
2478
    else
2479
        return qemuMonitorTextGetMigrationStats(mon, stats);
2480 2481 2482
}


2483 2484 2485 2486
int
qemuMonitorMigrateToFd(qemuMonitorPtr mon,
                       unsigned int flags,
                       int fd)
E
Eric Blake 已提交
2487 2488
{
    int ret;
2489
    VIR_DEBUG("fd=%d flags=%x", fd, flags);
E
Eric Blake 已提交
2490

2491
    QEMU_CHECK_MONITOR(mon);
E
Eric Blake 已提交
2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502

    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)
2503
            VIR_WARN("failed to close migration handle");
E
Eric Blake 已提交
2504 2505 2506 2507 2508 2509
    }

    return ret;
}


2510 2511 2512 2513 2514 2515
int
qemuMonitorMigrateToHost(qemuMonitorPtr mon,
                         unsigned int flags,
                         const char *protocol,
                         const char *hostname,
                         int port)
2516
{
D
Daniel P. Berrange 已提交
2517
    int ret;
2518
    char *uri = NULL;
2519
    VIR_DEBUG("hostname=%s port=%d flags=%x", hostname, port, flags);
2520

2521
    QEMU_CHECK_MONITOR(mon);
2522

2523
    if (virAsprintf(&uri, "%s:%s:%d", protocol, hostname, port) < 0)
2524 2525
        return -1;

D
Daniel P. Berrange 已提交
2526
    if (mon->json)
2527
        ret = qemuMonitorJSONMigrate(mon, flags, uri);
D
Daniel P. Berrange 已提交
2528
    else
2529 2530 2531
        ret = qemuMonitorTextMigrate(mon, flags, uri);

    VIR_FREE(uri);
D
Daniel P. Berrange 已提交
2532
    return ret;
2533 2534 2535
}


2536 2537 2538 2539
int
qemuMonitorMigrateToCommand(qemuMonitorPtr mon,
                            unsigned int flags,
                            const char * const *argv)
2540
{
2541 2542 2543
    char *argstr;
    char *dest = NULL;
    int ret = -1;
2544
    VIR_DEBUG("argv=%p flags=%x", argv, flags);
2545

2546
    QEMU_CHECK_MONITOR(mon);
2547

2548
    argstr = virArgvToString(argv);
2549
    if (!argstr)
2550 2551
        goto cleanup;

2552
    if (virAsprintf(&dest, "exec:%s", argstr) < 0)
2553 2554
        goto cleanup;

D
Daniel P. Berrange 已提交
2555
    if (mon->json)
2556
        ret = qemuMonitorJSONMigrate(mon, flags, dest);
D
Daniel P. Berrange 已提交
2557
    else
2558 2559
        ret = qemuMonitorTextMigrate(mon, flags, dest);

2560
 cleanup:
2561 2562
    VIR_FREE(argstr);
    VIR_FREE(dest);
2563 2564 2565
    return ret;
}

2566 2567 2568 2569 2570

int
qemuMonitorMigrateToUnix(qemuMonitorPtr mon,
                         unsigned int flags,
                         const char *unixfile)
2571
{
2572 2573
    char *dest = NULL;
    int ret = -1;
2574
    VIR_DEBUG("unixfile=%s flags=%x", unixfile, flags);
2575

2576
    QEMU_CHECK_MONITOR(mon);
2577

2578
    if (virAsprintf(&dest, "unix:%s", unixfile) < 0)
2579 2580
        return -1;

D
Daniel P. Berrange 已提交
2581
    if (mon->json)
2582
        ret = qemuMonitorJSONMigrate(mon, flags, dest);
D
Daniel P. Berrange 已提交
2583
    else
2584 2585 2586
        ret = qemuMonitorTextMigrate(mon, flags, dest);

    VIR_FREE(dest);
D
Daniel P. Berrange 已提交
2587
    return ret;
2588 2589
}

2590 2591 2592

int
qemuMonitorMigrateCancel(qemuMonitorPtr mon)
2593
{
2594
    QEMU_CHECK_MONITOR(mon);
2595

D
Daniel P. Berrange 已提交
2596
    if (mon->json)
2597
        return qemuMonitorJSONMigrateCancel(mon);
D
Daniel P. Berrange 已提交
2598
    else
2599
        return qemuMonitorTextMigrateCancel(mon);
2600 2601
}

2602

2603 2604 2605
/**
 * Returns 1 if @capability is supported, 0 if it's not, or -1 on error.
 */
2606 2607 2608
int
qemuMonitorGetDumpGuestMemoryCapability(qemuMonitorPtr mon,
                                        const char *capability)
2609
{
2610
    VIR_DEBUG("capability=%s", capability);
2611

2612
    QEMU_CHECK_MONITOR(mon);
2613 2614 2615 2616 2617 2618 2619 2620

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

    return qemuMonitorJSONGetDumpGuestMemoryCapability(mon, capability);
}

2621

2622
int
2623
qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd, const char *dumpformat)
2624 2625
{
    int ret;
2626
    VIR_DEBUG("fd=%d dumpformat=%s", fd, dumpformat);
2627

2628
    QEMU_CHECK_MONITOR_JSON(mon);
2629 2630 2631 2632

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

2633
    ret = qemuMonitorJSONDump(mon, "fd:dump", dumpformat);
2634 2635 2636 2637 2638 2639 2640 2641

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

    return ret;
}
2642

2643 2644 2645 2646 2647 2648 2649 2650

int
qemuMonitorGraphicsRelocate(qemuMonitorPtr mon,
                            int type,
                            const char *hostname,
                            int port,
                            int tlsPort,
                            const char *tlsSubject)
2651
{
2652 2653 2654 2655
    VIR_DEBUG("type=%d hostname=%s port=%d tlsPort=%d tlsSubject=%s",
              type, hostname, port, tlsPort, NULLSTR(tlsSubject));

    QEMU_CHECK_MONITOR(mon);
2656 2657

    if (mon->json)
2658 2659 2660 2661 2662 2663
        return qemuMonitorJSONGraphicsRelocate(mon,
                                               type,
                                               hostname,
                                               port,
                                               tlsPort,
                                               tlsSubject);
2664
    else
2665 2666 2667 2668 2669 2670
        return qemuMonitorTextGraphicsRelocate(mon,
                                               type,
                                               hostname,
                                               port,
                                               tlsPort,
                                               tlsSubject);
2671 2672 2673
}


2674 2675 2676 2677
int
qemuMonitorSendFileHandle(qemuMonitorPtr mon,
                          const char *fdname,
                          int fd)
2678
{
2679
    VIR_DEBUG("fdname=%s fd=%d", fdname, fd);
2680

2681
    QEMU_CHECK_MONITOR(mon);
2682

2683
    if (fd < 0) {
2684 2685
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("fd must be valid"));
2686 2687 2688 2689
        return -1;
    }

    if (!mon->hasSendFD) {
2690
        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
2691 2692
                       _("qemu is not using a unix socket monitor, "
                         "cannot send fd %s"), fdname);
2693 2694 2695
        return -1;
    }

D
Daniel P. Berrange 已提交
2696
    if (mon->json)
2697
        return qemuMonitorJSONSendFileHandle(mon, fdname, fd);
D
Daniel P. Berrange 已提交
2698
    else
2699
        return qemuMonitorTextSendFileHandle(mon, fdname, fd);
2700 2701 2702
}


2703 2704 2705
int
qemuMonitorCloseFileHandle(qemuMonitorPtr mon,
                           const char *fdname)
2706
{
2707 2708 2709
    int ret = -1;
    virErrorPtr error;

2710
    VIR_DEBUG("fdname=%s", fdname);
2711

2712 2713
    error = virSaveLastError();

2714
    QEMU_CHECK_MONITOR_GOTO(mon, cleanup);
2715

D
Daniel P. Berrange 已提交
2716 2717 2718 2719
    if (mon->json)
        ret = qemuMonitorJSONCloseFileHandle(mon, fdname);
    else
        ret = qemuMonitorTextCloseFileHandle(mon, fdname);
2720

2721
 cleanup:
2722 2723 2724 2725
    if (error) {
        virSetError(error);
        virFreeError(error);
    }
D
Daniel P. Berrange 已提交
2726
    return ret;
2727 2728 2729
}


2730 2731 2732 2733 2734 2735
/* 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)
{
2736
    VIR_DEBUG("fdset=%d, fd=%d, name=%s", fdset, fd, NULLSTR(name));
2737

2738
    QEMU_CHECK_MONITOR_JSON(mon);
2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752

    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;
    }

2753
    return qemuMonitorJSONAddFd(mon, fdset, fd, name);
2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765
}


/* 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;

2766
    VIR_DEBUG("fdset=%d, fd=%d", fdset, fd);
2767 2768 2769

    error = virSaveLastError();

2770
    QEMU_CHECK_MONITOR_JSON_GOTO(mon, cleanup);
2771

2772
    ret = qemuMonitorJSONRemoveFd(mon, fdset, fd);
2773

2774
 cleanup:
2775 2776 2777 2778 2779 2780 2781 2782
    if (error) {
        virSetError(error);
        virFreeError(error);
    }
    return ret;
}


2783 2784 2785 2786 2787
int
qemuMonitorAddHostNetwork(qemuMonitorPtr mon,
                          const char *netstr,
                          int *tapfd, char **tapfdName, int tapfdSize,
                          int *vhostfd, char **vhostfdName, int vhostfdSize)
2788
{
2789
    int ret = -1;
2790
    size_t i = 0, j = 0;
2791

2792
    VIR_DEBUG("netstr=%s tapfd=%p tapfdName=%p tapfdSize=%d "
2793
              "vhostfd=%p vhostfdName=%p vhostfdSize=%d",
2794
              netstr, tapfd, tapfdName, tapfdSize,
2795
              vhostfd, vhostfdName, vhostfdSize);
2796

2797
    QEMU_CHECK_MONITOR(mon);
2798

2799 2800 2801 2802 2803 2804 2805
    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;
2806 2807
    }

D
Daniel P. Berrange 已提交
2808
    if (mon->json)
2809
        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2810
                       _("JSON monitor should be using AddNetdev"));
D
Daniel P. Berrange 已提交
2811 2812
    else
        ret = qemuMonitorTextAddHostNetwork(mon, netstr);
2813

2814
 cleanup:
2815
    if (ret < 0) {
2816 2817 2818 2819 2820 2821 2822 2823
        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]);
        }
2824 2825
    }

D
Daniel P. Berrange 已提交
2826
    return ret;
2827 2828 2829
}


2830 2831 2832 2833
int
qemuMonitorRemoveHostNetwork(qemuMonitorPtr mon,
                             int vlan,
                             const char *netname)
2834
{
2835
    VIR_DEBUG("netname=%s", netname);
2836

2837
    QEMU_CHECK_MONITOR(mon);
2838

2839
    if (mon->json) {
2840
        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2841
                       _("JSON monitor should be using RemoveNetdev"));
2842 2843 2844 2845
        return -1;
    }

    return qemuMonitorTextRemoveHostNetwork(mon, vlan, netname);
2846
}
2847

2848

2849 2850 2851 2852 2853
int
qemuMonitorAddNetdev(qemuMonitorPtr mon,
                     const char *netdevstr,
                     int *tapfd, char **tapfdName, int tapfdSize,
                     int *vhostfd, char **vhostfdName, int vhostfdSize)
2854
{
2855
    int ret = -1;
2856
    size_t i = 0, j = 0;
2857

2858
    VIR_DEBUG("netdevstr=%s tapfd=%p tapfdName=%p tapfdSize=%d"
2859
              "vhostfd=%p vhostfdName=%p vhostfdSize=%d",
2860
              netdevstr, tapfd, tapfdName, tapfdSize,
2861
              vhostfd, vhostfdName, vhostfdSize);
2862

2863
    QEMU_CHECK_MONITOR(mon);
2864

2865 2866 2867 2868 2869 2870 2871
    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;
2872 2873
    }

2874 2875 2876 2877
    if (mon->json)
        ret = qemuMonitorJSONAddNetdev(mon, netdevstr);
    else
        ret = qemuMonitorTextAddNetdev(mon, netdevstr);
2878

2879
 cleanup:
2880
    if (ret < 0) {
2881 2882 2883 2884 2885 2886 2887 2888
        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]);
        }
2889 2890
    }

2891 2892 2893
    return ret;
}

2894 2895 2896 2897

int
qemuMonitorRemoveNetdev(qemuMonitorPtr mon,
                        const char *alias)
2898
{
2899
    VIR_DEBUG("alias=%s", alias);
2900

2901
    QEMU_CHECK_MONITOR(mon);
2902 2903

    if (mon->json)
2904
        return qemuMonitorJSONRemoveNetdev(mon, alias);
2905
    else
2906
        return qemuMonitorTextRemoveNetdev(mon, alias);
2907 2908 2909
}


2910 2911 2912 2913
int
qemuMonitorQueryRxFilter(qemuMonitorPtr mon, const char *alias,
                         virNetDevRxFilterPtr *filter)
{
2914
    VIR_DEBUG("alias=%s filter=%p", alias, filter);
2915

2916
    QEMU_CHECK_MONITOR_JSON(mon);
2917 2918

    return qemuMonitorJSONQueryRxFilter(mon, alias, filter);
2919 2920 2921
}


2922
void
2923 2924 2925 2926 2927 2928 2929 2930 2931 2932
qemuMonitorChardevInfoFree(void *data,
                           const void *name ATTRIBUTE_UNUSED)
{
    qemuMonitorChardevInfoPtr info = data;

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


2933 2934 2935
int
qemuMonitorGetChardevInfo(qemuMonitorPtr mon,
                          virHashTablePtr *retinfo)
2936
{
2937
    int ret;
2938 2939
    virHashTablePtr info = NULL;

2940
    VIR_DEBUG("retinfo=%p", retinfo);
2941

2942
    QEMU_CHECK_MONITOR_GOTO(mon, error);
2943

2944
    if (!(info = virHashCreate(10, qemuMonitorChardevInfoFree)))
2945 2946
        goto error;

2947
    if (mon->json)
2948
        ret = qemuMonitorJSONGetChardevInfo(mon, info);
2949
    else
2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961
        ret = qemuMonitorTextGetChardevInfo(mon, info);

    if (ret < 0)
        goto error;

    *retinfo = info;
    return 0;

 error:
    virHashFree(info);
    *retinfo = NULL;
    return -1;
2962
}
2963 2964


2965 2966 2967 2968 2969 2970 2971
/**
 * 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 */
2972 2973 2974
int
qemuMonitorDriveDel(qemuMonitorPtr mon,
                    const char *drivestr)
2975
{
2976
    VIR_DEBUG("drivestr=%s", drivestr);
2977

2978
    QEMU_CHECK_MONITOR(mon);
2979

2980 2981
    /* there won't be a direct replacement for drive_del in QMP */
    return qemuMonitorTextDriveDel(mon, drivestr);
2982 2983
}

2984 2985 2986 2987

int
qemuMonitorDelDevice(qemuMonitorPtr mon,
                     const char *devalias)
2988
{
2989
    VIR_DEBUG("devalias=%s", devalias);
2990

2991
    QEMU_CHECK_MONITOR(mon);
2992

2993
    if (mon->json)
2994
        return qemuMonitorJSONDelDevice(mon, devalias);
2995
    else
2996
        return qemuMonitorTextDelDevice(mon, devalias);
2997 2998
}

2999

3000 3001 3002 3003 3004
int
qemuMonitorAddDeviceWithFd(qemuMonitorPtr mon,
                           const char *devicestr,
                           int fd,
                           const char *fdname)
3005
{
3006
    VIR_DEBUG("device=%s fd=%d fdname=%s", devicestr, fd, NULLSTR(fdname));
3007 3008
    int ret;

3009
    QEMU_CHECK_MONITOR(mon);
3010

3011 3012 3013
    if (fd >= 0 && qemuMonitorSendFileHandle(mon, fdname, fd) < 0)
        return -1;

3014 3015 3016 3017
    if (mon->json)
        ret = qemuMonitorJSONAddDevice(mon, devicestr);
    else
        ret = qemuMonitorTextAddDevice(mon, devicestr);
3018 3019 3020 3021 3022 3023

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

3024 3025 3026
    return ret;
}

3027 3028 3029 3030

int
qemuMonitorAddDevice(qemuMonitorPtr mon,
                     const char *devicestr)
3031 3032 3033 3034
{
    return qemuMonitorAddDeviceWithFd(mon, devicestr, -1, NULL);
}

3035

3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053
/**
 * 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);
}


3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069
/**
 * 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)
{
3070
    VIR_DEBUG("type=%s objalias=%s props=%p", type, objalias, props);
3071

3072
    QEMU_CHECK_MONITOR_JSON_GOTO(mon, error);
3073

3074
    return qemuMonitorJSONAddObject(mon, type, objalias, props);
3075 3076 3077 3078 3079

 error:
    virJSONValueFree(props);
    return -1;
}
3080 3081 3082 3083 3084 3085


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

3088
    QEMU_CHECK_MONITOR_JSON(mon);
3089

3090
    return qemuMonitorJSONDelObject(mon, objalias);
3091 3092 3093
}


3094 3095 3096
int
qemuMonitorAddDrive(qemuMonitorPtr mon,
                    const char *drivestr)
3097
{
3098
    VIR_DEBUG("drive=%s", drivestr);
3099

3100
    QEMU_CHECK_MONITOR(mon);
3101

3102 3103
    /* there won't ever be a direct QMP replacement for this function */
    return qemuMonitorTextAddDrive(mon, drivestr);
3104
}
3105 3106


3107 3108 3109 3110
int
qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon,
                              const char *alias,
                              const char *passphrase)
3111
{
3112
    VIR_DEBUG("alias=%s passphrase=%p(value hidden)", alias, passphrase);
3113

3114
    QEMU_CHECK_MONITOR(mon);
3115

3116
    if (mon->json)
3117
        return qemuMonitorJSONSetDrivePassphrase(mon, alias, passphrase);
3118
    else
3119
        return qemuMonitorTextSetDrivePassphrase(mon, alias, passphrase);
3120
}
C
Chris Lalancette 已提交
3121

3122 3123 3124

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

3128
    QEMU_CHECK_MONITOR(mon);
3129

C
Chris Lalancette 已提交
3130
    if (mon->json)
3131
        return qemuMonitorJSONCreateSnapshot(mon, name);
C
Chris Lalancette 已提交
3132
    else
3133
        return qemuMonitorTextCreateSnapshot(mon, name);
C
Chris Lalancette 已提交
3134 3135
}

3136 3137
int
qemuMonitorLoadSnapshot(qemuMonitorPtr mon, const char *name)
C
Chris Lalancette 已提交
3138
{
3139
    VIR_DEBUG("name=%s", name);
C
Chris Lalancette 已提交
3140

3141
    QEMU_CHECK_MONITOR(mon);
3142

C
Chris Lalancette 已提交
3143
    if (mon->json)
3144
        return qemuMonitorJSONLoadSnapshot(mon, name);
C
Chris Lalancette 已提交
3145
    else
3146
        return qemuMonitorTextLoadSnapshot(mon, name);
C
Chris Lalancette 已提交
3147 3148
}

3149 3150 3151

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

3155
    QEMU_CHECK_MONITOR(mon);
3156

C
Chris Lalancette 已提交
3157
    if (mon->json)
3158
        return qemuMonitorJSONDeleteSnapshot(mon, name);
C
Chris Lalancette 已提交
3159
    else
3160
        return qemuMonitorTextDeleteSnapshot(mon, name);
C
Chris Lalancette 已提交
3161
}
3162

3163

3164 3165 3166 3167
/* 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
3168
qemuMonitorDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions,
3169 3170
                        const char *device, const char *file,
                        const char *format, bool reuse)
3171
{
3172 3173
    VIR_DEBUG("actions=%p, device=%s, file=%s, format=%s, reuse=%d",
              actions, device, file, format, reuse);
3174

3175
    QEMU_CHECK_MONITOR_JSON(mon);
3176 3177

    return qemuMonitorJSONDiskSnapshot(mon, actions, device, file, format, reuse);
3178 3179
}

3180

3181
/* Start a drive-mirror block job.  bandwidth is in bytes/sec.  */
3182 3183 3184
int
qemuMonitorDriveMirror(qemuMonitorPtr mon,
                       const char *device, const char *file,
3185
                       const char *format, unsigned long long bandwidth,
3186
                       unsigned int granularity, unsigned long long buf_size,
3187 3188
                       unsigned int flags)
{
3189
    VIR_DEBUG("device=%s, file=%s, format=%s, bandwidth=%lld, "
3190
              "granularity=%#x, buf_size=%lld, flags=%x",
3191
              device, file, NULLSTR(format), bandwidth, granularity,
3192
              buf_size, flags);
3193

3194
    QEMU_CHECK_MONITOR_JSON(mon);
3195 3196 3197

    return qemuMonitorJSONDriveMirror(mon, device, file, format, bandwidth,
                                      granularity, buf_size, flags);
3198 3199
}

3200

3201 3202 3203 3204
/* Use the transaction QMP command to run atomic snapshot commands.  */
int
qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions)
{
3205
    VIR_DEBUG("actions=%p", actions);
3206

3207
    QEMU_CHECK_MONITOR_JSON(mon);
3208 3209

    return qemuMonitorJSONTransaction(mon, actions);
3210 3211
}

3212

3213
/* Start a block-commit block job.  bandwidth is in bytes/sec.  */
3214 3215 3216
int
qemuMonitorBlockCommit(qemuMonitorPtr mon, const char *device,
                       const char *top, const char *base,
3217
                       const char *backingName,
3218
                       unsigned long long bandwidth)
3219
{
3220 3221
    VIR_DEBUG("device=%s, top=%s, base=%s, backingName=%s, bandwidth=%llu",
              device, top, base, NULLSTR(backingName), bandwidth);
3222

3223
    QEMU_CHECK_MONITOR_JSON(mon);
3224 3225 3226

    return qemuMonitorJSONBlockCommit(mon, device, top, base,
                                         backingName, bandwidth);
3227 3228
}

3229 3230 3231 3232 3233

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

3237
    return qemuMonitorJSONBlockCommit(mon, "bogus", NULL, NULL, NULL, 0) == -2;
3238 3239 3240
}


3241 3242 3243 3244 3245 3246 3247 3248
/* 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)
{
3249
    QEMU_CHECK_MONITOR_JSON_NULL(mon);
3250 3251 3252 3253 3254

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


3255
/* Use the block-job-complete monitor command to pivot a block copy job.  */
3256
int
3257 3258
qemuMonitorDrivePivot(qemuMonitorPtr mon,
                      const char *device)
3259
{
3260
    VIR_DEBUG("device=%s", device);
3261

3262
    QEMU_CHECK_MONITOR_JSON(mon);
3263 3264

    return qemuMonitorJSONDrivePivot(mon, device);
3265 3266
}

3267 3268 3269 3270 3271 3272

int
qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
                            const char *cmd,
                            char **reply,
                            bool hmp)
3273
{
3274 3275 3276
    VIR_DEBUG("cmd=%s, reply=%p, hmp=%d", cmd, reply, hmp);

    QEMU_CHECK_MONITOR(mon);
3277 3278

    if (mon->json)
3279
        return qemuMonitorJSONArbitraryCommand(mon, cmd, reply, hmp);
3280
    else
3281
        return qemuMonitorTextArbitraryCommand(mon, cmd, reply);
3282
}
3283 3284


3285 3286
int
qemuMonitorInjectNMI(qemuMonitorPtr mon)
3287
{
3288
    QEMU_CHECK_MONITOR(mon);
3289 3290

    if (mon->json)
3291
        return qemuMonitorJSONInjectNMI(mon);
3292
    else
3293
        return qemuMonitorTextInjectNMI(mon);
3294
}
3295

3296 3297 3298 3299 3300 3301

int
qemuMonitorSendKey(qemuMonitorPtr mon,
                   unsigned int holdtime,
                   unsigned int *keycodes,
                   unsigned int nkeycodes)
3302
{
3303 3304 3305
    VIR_DEBUG("holdtime=%u, nkeycodes=%u", holdtime, nkeycodes);

    QEMU_CHECK_MONITOR(mon);
3306 3307

    if (mon->json)
3308
        return qemuMonitorJSONSendKey(mon, holdtime, keycodes, nkeycodes);
3309
    else
3310
        return qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
3311 3312
}

3313 3314 3315 3316

int
qemuMonitorScreendump(qemuMonitorPtr mon,
                      const char *file)
3317
{
3318
    VIR_DEBUG("file=%s", file);
3319

3320
    QEMU_CHECK_MONITOR(mon);
3321 3322

    if (mon->json)
3323
        return qemuMonitorJSONScreendump(mon, file);
3324
    else
3325
        return qemuMonitorTextScreendump(mon, file);
3326
}
3327

3328

3329
/* bandwidth is in bytes/sec */
3330
int
3331 3332 3333 3334 3335 3336
qemuMonitorBlockStream(qemuMonitorPtr mon,
                       const char *device,
                       const char *base,
                       const char *backingName,
                       unsigned long long bandwidth,
                       bool modern)
3337
{
3338 3339
    VIR_DEBUG("device=%s, base=%s, backingName=%s, bandwidth=%lluB, modern=%d",
              device, NULLSTR(base), NULLSTR(backingName), bandwidth, modern);
3340

3341
    QEMU_CHECK_MONITOR_JSON(mon);
3342 3343 3344

    return qemuMonitorJSONBlockStream(mon, device, base, backingName,
                                      bandwidth, modern);
3345
}
3346

3347

3348 3349 3350 3351 3352
int
qemuMonitorBlockJobCancel(qemuMonitorPtr mon,
                          const char *device,
                          bool modern)
{
3353
    VIR_DEBUG("device=%s, modern=%d", device, modern);
3354

3355
    QEMU_CHECK_MONITOR_JSON(mon);
3356 3357 3358 3359 3360

    return qemuMonitorJSONBlockJobCancel(mon, device, modern);
}


3361 3362 3363 3364 3365 3366
int
qemuMonitorBlockJobSetSpeed(qemuMonitorPtr mon,
                            const char *device,
                            unsigned long long bandwidth,
                            bool modern)
{
3367
    VIR_DEBUG("device=%s, bandwidth=%lluB, modern=%d", device, bandwidth, modern);
3368

3369
    QEMU_CHECK_MONITOR_JSON(mon);
3370 3371 3372 3373 3374

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


3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387
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.
 */
3388
int
3389 3390 3391
qemuMonitorGetBlockJobInfo(qemuMonitorPtr mon,
                           const char *alias,
                           qemuMonitorBlockJobInfoPtr info)
3392
{
3393 3394 3395
    virHashTablePtr all;
    qemuMonitorBlockJobInfoPtr data;
    int ret = 0;
3396

3397 3398 3399 3400
    VIR_DEBUG("alias=%s, info=%p", alias, info);

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

3402 3403 3404 3405 3406 3407 3408
    if ((data = virHashLookup(all, alias))) {
        *info = *data;
        ret = 1;
    }

    virHashFree(all);
    return ret;
3409 3410 3411
}


3412 3413 3414 3415 3416
int
qemuMonitorSetBlockIoThrottle(qemuMonitorPtr mon,
                              const char *device,
                              virDomainBlockIoTuneInfoPtr info,
                              bool supportMaxOptions)
3417
{
3418 3419 3420
    VIR_DEBUG("device=%p, info=%p", device, info);

    QEMU_CHECK_MONITOR(mon);
3421

3422 3423 3424 3425
    if (mon->json)
        return qemuMonitorJSONSetBlockIoThrottle(mon, device, info, supportMaxOptions);
    else
        return qemuMonitorTextSetBlockIoThrottle(mon, device, info);
3426 3427
}

3428 3429 3430 3431

int
qemuMonitorGetBlockIoThrottle(qemuMonitorPtr mon,
                              const char *device,
3432
                              virDomainBlockIoTuneInfoPtr reply)
3433
{
3434 3435 3436
    VIR_DEBUG("device=%p, reply=%p", device, reply);

    QEMU_CHECK_MONITOR(mon);
3437

3438
    if (mon->json)
3439
        return qemuMonitorJSONGetBlockIoThrottle(mon, device, reply);
3440 3441
    else
        return qemuMonitorTextGetBlockIoThrottle(mon, device, reply);
3442 3443 3444
}


3445 3446
int
qemuMonitorVMStatusToPausedReason(const char *status)
3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488
{
    int st;

    if (!status)
        return VIR_DOMAIN_PAUSED_UNKNOWN;

    if ((st = qemuMonitorVMStatusTypeFromString(status)) < 0) {
        VIR_WARN("Qemu reported unknown VM status: '%s'", status);
        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:
        VIR_WARN("Qemu reports the guest is paused but status is 'running'");
        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;

3489
    case QEMU_MONITOR_VM_STATUS_GUEST_PANICKED:
3490
        return VIR_DOMAIN_PAUSED_CRASHED;
3491

3492 3493 3494 3495 3496 3497
    /* unreachable from this point on */
    case QEMU_MONITOR_VM_STATUS_LAST:
        ;
    }
    return VIR_DOMAIN_PAUSED_UNKNOWN;
}
3498 3499


3500 3501 3502 3503 3504 3505
int
qemuMonitorOpenGraphics(qemuMonitorPtr mon,
                        const char *protocol,
                        int fd,
                        const char *fdname,
                        bool skipauth)
3506
{
3507 3508
    VIR_DEBUG("protocol=%s fd=%d fdname=%s skipauth=%d",
              protocol, fd, NULLSTR(fdname), skipauth);
3509 3510
    int ret;

3511
    QEMU_CHECK_MONITOR(mon);
3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527

    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;
}
3528

3529 3530 3531

int
qemuMonitorSystemWakeup(qemuMonitorPtr mon)
3532
{
3533
    QEMU_CHECK_MONITOR_JSON(mon);
3534 3535 3536

    return qemuMonitorJSONSystemWakeup(mon);
}
3537

3538 3539 3540 3541 3542 3543 3544

int
qemuMonitorGetVersion(qemuMonitorPtr mon,
                      int *major,
                      int *minor,
                      int *micro,
                      char **package)
3545
{
3546 3547
    VIR_DEBUG("major=%p minor=%p micro=%p package=%p",
              major, minor, micro, package);
3548

3549
    QEMU_CHECK_MONITOR_JSON(mon);
3550 3551 3552

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

3554 3555 3556 3557

int
qemuMonitorGetMachines(qemuMonitorPtr mon,
                       qemuMonitorMachineInfoPtr **machines)
3558
{
3559
    VIR_DEBUG("machines=%p", machines);
3560

3561
    QEMU_CHECK_MONITOR_JSON(mon);
3562 3563 3564 3565

    return qemuMonitorJSONGetMachines(mon, machines);
}

3566 3567 3568

void
qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine)
3569 3570 3571 3572 3573 3574 3575
{
    if (!machine)
        return;
    VIR_FREE(machine->name);
    VIR_FREE(machine->alias);
    VIR_FREE(machine);
}
3576

3577 3578 3579 3580

int
qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
                             char ***cpus)
3581
{
3582
    VIR_DEBUG("cpus=%p", cpus);
3583

3584
    QEMU_CHECK_MONITOR_JSON(mon);
3585 3586 3587

    return qemuMonitorJSONGetCPUDefinitions(mon, cpus);
}
3588 3589


3590 3591 3592
int
qemuMonitorGetCommands(qemuMonitorPtr mon,
                       char ***commands)
3593
{
3594
    VIR_DEBUG("commands=%p", commands);
3595

3596
    QEMU_CHECK_MONITOR_JSON(mon);
3597 3598 3599

    return qemuMonitorJSONGetCommands(mon, commands);
}
3600 3601


3602 3603 3604
int
qemuMonitorGetEvents(qemuMonitorPtr mon,
                     char ***events)
3605
{
3606
    VIR_DEBUG("events=%p", events);
3607

3608
    QEMU_CHECK_MONITOR_JSON(mon);
3609 3610 3611

    return qemuMonitorJSONGetEvents(mon, events);
}
3612 3613


3614 3615 3616 3617 3618
/* 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,
3619 3620
                                          char ***params,
                                          bool *found)
3621
{
3622
    VIR_DEBUG("option=%s params=%p", option, params);
3623

3624
    QEMU_CHECK_MONITOR_JSON(mon);
3625

3626 3627
    return qemuMonitorJSONGetCommandLineOptionParameters(mon, option,
                                                         params, found);
3628 3629 3630
}


3631 3632 3633 3634
int
qemuMonitorGetKVMState(qemuMonitorPtr mon,
                       bool *enabled,
                       bool *present)
3635
{
3636
    VIR_DEBUG("enabled=%p present=%p", enabled, present);
3637

3638
    QEMU_CHECK_MONITOR_JSON(mon);
3639 3640 3641 3642 3643

    return qemuMonitorJSONGetKVMState(mon, enabled, present);
}


3644 3645 3646
int
qemuMonitorGetObjectTypes(qemuMonitorPtr mon,
                          char ***types)
3647
{
3648
    VIR_DEBUG("types=%p", types);
3649

3650
    QEMU_CHECK_MONITOR_JSON(mon);
3651 3652 3653

    return qemuMonitorJSONGetObjectTypes(mon, types);
}
3654 3655


3656 3657 3658 3659
int
qemuMonitorGetObjectProps(qemuMonitorPtr mon,
                          const char *type,
                          char ***props)
3660
{
3661
    VIR_DEBUG("type=%s props=%p", type, props);
3662

3663
    QEMU_CHECK_MONITOR_JSON(mon);
3664 3665 3666

    return qemuMonitorJSONGetObjectProps(mon, type, props);
}
3667 3668


3669 3670
char *
qemuMonitorGetTargetArch(qemuMonitorPtr mon)
3671
{
3672
    QEMU_CHECK_MONITOR_JSON_NULL(mon);
3673 3674 3675

    return qemuMonitorJSONGetTargetArch(mon);
}
3676 3677


3678 3679 3680 3681
int
qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon,
                                    char ***capabilities)
{
3682
    QEMU_CHECK_MONITOR(mon);
3683 3684 3685 3686 3687 3688 3689 3690 3691

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

    return qemuMonitorJSONGetMigrationCapabilities(mon, capabilities);
}


3692 3693 3694
/**
 * Returns 1 if @capability is supported, 0 if it's not, or -1 on error.
 */
3695 3696 3697
int
qemuMonitorGetMigrationCapability(qemuMonitorPtr mon,
                                  qemuMonitorMigrationCaps capability)
3698
{
3699
    VIR_DEBUG("capability=%d", capability);
3700

3701
    QEMU_CHECK_MONITOR(mon);
3702 3703 3704 3705 3706 3707 3708 3709

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

    return qemuMonitorJSONGetMigrationCapability(mon, capability);
}

3710 3711 3712 3713 3714

int
qemuMonitorSetMigrationCapability(qemuMonitorPtr mon,
                                  qemuMonitorMigrationCaps capability,
                                  bool state)
3715
{
3716
    VIR_DEBUG("capability=%d", capability);
3717

3718
    QEMU_CHECK_MONITOR_JSON(mon);
3719

3720
    return qemuMonitorJSONSetMigrationCapability(mon, capability, state);
3721
}
3722

3723

A
Andrea Bolognani 已提交
3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740
/**
 * 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);
}


3741 3742 3743 3744
int
qemuMonitorNBDServerStart(qemuMonitorPtr mon,
                          const char *host,
                          unsigned int port)
3745
{
3746
    VIR_DEBUG("host=%s port=%u", host, port);
3747

3748
    QEMU_CHECK_MONITOR_JSON(mon);
3749 3750 3751

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

3753 3754 3755 3756 3757

int
qemuMonitorNBDServerAdd(qemuMonitorPtr mon,
                        const char *deviceID,
                        bool writable)
3758
{
3759
    VIR_DEBUG("deviceID=%s", deviceID);
3760

3761
    QEMU_CHECK_MONITOR_JSON(mon);
3762 3763 3764

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

3766 3767 3768

int
qemuMonitorNBDServerStop(qemuMonitorPtr mon)
3769
{
3770
    QEMU_CHECK_MONITOR_JSON(mon);
3771 3772 3773

    return qemuMonitorJSONNBDServerStop(mon);
}
S
Stefan Berger 已提交
3774 3775


3776 3777
int
qemuMonitorGetTPMModels(qemuMonitorPtr mon,
S
Stefan Berger 已提交
3778 3779
                            char ***tpmmodels)
{
3780
    VIR_DEBUG("tpmmodels=%p", tpmmodels);
S
Stefan Berger 已提交
3781

3782
    QEMU_CHECK_MONITOR_JSON(mon);
S
Stefan Berger 已提交
3783 3784 3785 3786 3787

    return qemuMonitorJSONGetTPMModels(mon, tpmmodels);
}


3788 3789 3790
int
qemuMonitorGetTPMTypes(qemuMonitorPtr mon,
                       char ***tpmtypes)
S
Stefan Berger 已提交
3791
{
3792
    VIR_DEBUG("tpmtypes=%p", tpmtypes);
S
Stefan Berger 已提交
3793

3794
    QEMU_CHECK_MONITOR_JSON(mon);
S
Stefan Berger 已提交
3795 3796 3797

    return qemuMonitorJSONGetTPMTypes(mon, tpmtypes);
}
3798

3799 3800 3801 3802 3803

int
qemuMonitorAttachCharDev(qemuMonitorPtr mon,
                         const char *chrID,
                         virDomainChrSourceDefPtr chr)
3804
{
3805
    VIR_DEBUG("chrID=%s chr=%p", chrID, chr);
3806

3807
    QEMU_CHECK_MONITOR_JSON(mon);
3808 3809 3810

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

3812 3813 3814 3815

int
qemuMonitorDetachCharDev(qemuMonitorPtr mon,
                         const char *chrID)
3816
{
3817
    VIR_DEBUG("chrID=%s", chrID);
3818

3819
    QEMU_CHECK_MONITOR_JSON(mon);
3820 3821 3822

    return qemuMonitorJSONDetachCharDev(mon, chrID);
}
3823

3824

3825 3826 3827 3828
int
qemuMonitorGetDeviceAliases(qemuMonitorPtr mon,
                            char ***aliases)
{
3829
    VIR_DEBUG("aliases=%p", aliases);
3830

3831
    QEMU_CHECK_MONITOR_JSON(mon);
3832 3833 3834

    return qemuMonitorJSONGetDeviceAliases(mon, aliases);
}
3835 3836 3837 3838 3839 3840 3841 3842


/**
 * 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
3843 3844 3845
 * @func: the callback to report errors
 * @opaque: data to pass to @func
 * @destroy: optional callback to free @opaque
3846
 */
3847 3848 3849 3850 3851
void
qemuMonitorSetDomainLog(qemuMonitorPtr mon,
                        qemuMonitorReportDomainLogError func,
                        void *opaque,
                        virFreeCallback destroy)
3852
{
3853 3854
    if (mon->logDestroy && mon->logOpaque)
        mon->logDestroy(mon->logOpaque);
3855

3856 3857 3858
    mon->logFunc = func;
    mon->logOpaque = opaque;
    mon->logDestroy = destroy;
3859
}
3860 3861 3862 3863 3864 3865


/**
 * qemuMonitorJSONGetGuestCPU:
 * @mon: Pointer to the monitor
 * @arch: arch of the guest
3866
 * @data: returns the cpu data
3867 3868 3869
 *
 * Retrieve the definition of the guest CPU from a running qemu instance.
 *
3870 3871
 * Returns 0 on success, -2 if the operation is not supported by the guest,
 * -1 on other errors.
3872
 */
3873
int
3874
qemuMonitorGetGuestCPU(qemuMonitorPtr mon,
3875 3876
                       virArch arch,
                       virCPUDataPtr *data)
3877
{
3878
    VIR_DEBUG("arch='%s' data='%p'", virArchToString(arch), data);
3879

3880
    QEMU_CHECK_MONITOR_JSON(mon);
3881

3882 3883 3884
    *data = NULL;

    return qemuMonitorJSONGetGuestCPU(mon, arch, data);
3885
}
3886

3887

3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902
/**
 * 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)
{
3903
    QEMU_CHECK_MONITOR_JSON(mon);
3904 3905 3906

    return qemuMonitorJSONRTCResetReinjection(mon);
}
3907

3908

3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921
/**
 * 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,
3922
                        qemuMonitorIOThreadInfoPtr **iothreads)
3923 3924
{

3925
    VIR_DEBUG("iothreads=%p", iothreads);
3926

3927
    QEMU_CHECK_MONITOR(mon);
3928

3929
    /* Requires JSON to make the query */
3930
    if (!mon->json) {
3931 3932
        *iothreads = NULL;
        return 0;
3933 3934 3935 3936 3937
    }

    return qemuMonitorJSONGetIOThreads(mon, iothreads);
}

3938

3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954
/**
 * 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)
{
3955
    VIR_DEBUG("info=%p", info);
3956 3957 3958 3959
    int ret;

    *info = NULL;

3960
    QEMU_CHECK_MONITOR(mon);
3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974

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

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

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

    return ret;
}
3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986


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

    QEMU_CHECK_MONITOR_JSON(mon);

    return qemuMonitorJSONMigrateIncoming(mon, uri);
}
3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997


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

    QEMU_CHECK_MONITOR_JSON(mon);

    return qemuMonitorJSONMigrateStartPostCopy(mon);
}
3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008

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

    QEMU_CHECK_MONITOR_JSON(mon);

    return qemuMonitorJSONGetRTCTime(mon, tm);
}