qemu_monitor.c 68.4 KB
Newer Older
1 2 3
/*
 * qemu_monitor.c: interaction with QEMU monitor console
 *
4
 * Copyright (C) 2006-2011 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 * 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
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

#include <config.h>

#include <poll.h>
#include <sys/un.h>
#include <unistd.h>
#include <fcntl.h>

#include "qemu_monitor.h"
32
#include "qemu_monitor_text.h"
D
Daniel P. Berrange 已提交
33
#include "qemu_monitor_json.h"
34 35
#include "qemu_conf.h"
#include "virterror_internal.h"
36 37
#include "memory.h"
#include "logging.h"
E
Eric Blake 已提交
38
#include "virfile.h"
39 40 41

#define VIR_FROM_THIS VIR_FROM_QEMU

42 43
#define DEBUG_IO 0
#define DEBUG_RAW_IO 0
44

45
struct _qemuMonitor {
S
Stefan Berger 已提交
46
    virMutex lock; /* also used to protect fd */
47 48
    virCond notify;

49
    int refs;
50

51 52 53 54 55 56
    int fd;
    int watch;
    int hasSendFD;

    virDomainObjPtr vm;

57
    qemuMonitorCallbacksPtr cb;
58 59 60 61 62 63 64 65 66 67 68 69 70

    /* 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 */
71 72 73
    virError lastError;

    int nextSerial;
74

D
Daniel P. Berrange 已提交
75
    unsigned json: 1;
76
    unsigned json_hmp: 1;
77 78
};

79

80 81 82 83
VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
              QEMU_MONITOR_MIGRATION_STATUS_LAST,
              "inactive", "active", "completed", "failed", "cancelled")

84 85 86 87 88 89
VIR_ENUM_IMPL(qemuMonitorVMStatus,
              QEMU_MONITOR_VM_STATUS_LAST,
              "debug", "inmigrate", "internal-error", "io-error", "paused",
              "postmigrate", "prelaunch", "finish-migrate", "restore-vm",
              "running", "save-vm", "shutdown", "watchdog")

90
char *qemuMonitorEscapeArg(const char *in)
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
{
    int len = 0;
    int i, j;
    char *out;

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

    for (i = 0; in[i] != '\0'; i++) {
        switch(in[i]) {
        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++) {
        switch(in[i]) {
        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;
}

char *qemuMonitorEscapeShell(const char *in)
{
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
    int len = 2; /* leading and trailing single quote */
    int i, j;
    char *out;

    for (i = 0; in[i] != '\0'; i++) {
        switch(in[i]) {
        case '\'':
            len += 4; /* '\'' */
            break;
        default:
            len += 1;
            break;
        }
    }

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

    j = 0;
    out[j++] = '\'';
    for (i = 0; in[i] != '\0'; i++) {
        switch(in[i]) {
        case '\'':
            out[j++] = '\'';
            out[j++] = '\\';
            out[j++] = '\'';
            out[j++] = '\'';
            break;
        default:
            out[j++] = in[i];
            break;
        }
    }
    out[j++] = '\'';
    out[j] = '\0';

    return out;
181 182 183
}


J
Jiri Denemark 已提交
184
#if DEBUG_RAW_IO
185
# include <c-ctype.h>
186 187 188 189 190 191 192 193
static char * qemuMonitorEscapeNonPrintable(const char *text)
{
    int i;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    for (i = 0 ; text[i] != '\0' ; i++) {
        if (c_isprint(text[i]) ||
            text[i] == '\n' ||
            (text[i] == '\r' && text[i+1] == '\n'))
194
            virBufferAsprintf(&buf,"%c", text[i]);
195
        else
196
            virBufferAsprintf(&buf, "0x%02x", text[i]);
197 198 199 200 201
    }
    return virBufferContentAndReset(&buf);
}
#endif

202 203 204 205 206 207 208 209 210 211
void qemuMonitorLock(qemuMonitorPtr mon)
{
    virMutexLock(&mon->lock);
}

void qemuMonitorUnlock(qemuMonitorPtr mon)
{
    virMutexUnlock(&mon->lock);
}

212

213
static void qemuMonitorFree(qemuMonitorPtr mon)
214
{
215
    VIR_DEBUG("mon=%p", mon);
216
    if (mon->cb && mon->cb->destroy)
217
        (mon->cb->destroy)(mon, mon->vm);
218 219 220
    if (virCondDestroy(&mon->notify) < 0)
    {}
    virMutexDestroy(&mon->lock);
E
Eric Blake 已提交
221
    VIR_FREE(mon->buffer);
222
    VIR_FREE(mon);
223 224
}

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
int qemuMonitorRef(qemuMonitorPtr mon)
{
    mon->refs++;
    return mon->refs;
}

int qemuMonitorUnref(qemuMonitorPtr mon)
{
    mon->refs--;

    if (mon->refs == 0) {
        qemuMonitorUnlock(mon);
        qemuMonitorFree(mon);
        return 0;
    }

    return mon->refs;
}

244 245 246 247 248 249
static void
qemuMonitorUnwatch(void *monitor)
{
    qemuMonitorPtr mon = monitor;

    qemuMonitorLock(mon);
250 251
    if (qemuMonitorUnref(mon) > 0)
        qemuMonitorUnlock(mon);
252
}
253 254

static int
255
qemuMonitorOpenUnix(const char *monitor, pid_t cpid)
256 257 258 259 260 261 262
{
    struct sockaddr_un addr;
    int monfd;
    int timeout = 3; /* In seconds */
    int ret, i = 0;

    if ((monfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
263
        virReportSystemError(errno,
264 265 266 267 268 269 270
                             "%s", _("failed to create socket"));
        return -1;
    }

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    if (virStrcpyStatic(addr.sun_path, monitor) == NULL) {
271 272
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Monitor path %s too big for destination"), monitor);
273 274 275 276 277 278 279 280 281
        goto error;
    }

    do {
        ret = connect(monfd, (struct sockaddr *) &addr, sizeof(addr));

        if (ret == 0)
            break;

282 283
        if ((errno == ENOENT || errno == ECONNREFUSED) &&
            virKillProcess(cpid, 0) == 0) {
284 285 286 287 288
            /* ENOENT       : Socket may not have shown up yet
             * ECONNREFUSED : Leftover socket hasn't been removed yet */
            continue;
        }

289
        virReportSystemError(errno, "%s",
290 291 292 293 294 295
                             _("failed to connect to monitor socket"));
        goto error;

    } while ((++i <= timeout*5) && (usleep(.2 * 1000000) <= 0));

    if (ret != 0) {
296
        virReportSystemError(errno, "%s",
297 298 299 300
                             _("monitor socket did not show up."));
        goto error;
    }

301
    return monfd;
302 303

error:
304
    VIR_FORCE_CLOSE(monfd);
305 306 307 308
    return -1;
}

static int
309
qemuMonitorOpenPty(const char *monitor)
310 311 312 313
{
    int monfd;

    if ((monfd = open(monitor, O_RDWR)) < 0) {
314 315
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Unable to open monitor path %s"), monitor);
316 317 318
        return -1;
    }

319
    return monfd;
320
}
321

322

323 324 325 326
/* This method processes data that has been received
 * from the monitor. Looking for async events and
 * replies/errors.
 */
327 328 329 330 331 332 333 334 335 336 337
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;

338
#if DEBUG_IO
339
# if DEBUG_RAW_IO
340 341
    char *str1 = qemuMonitorEscapeNonPrintable(msg ? msg->txBuffer : "");
    char *str2 = qemuMonitorEscapeNonPrintable(mon->buffer);
342
    VIR_ERROR(_("Process %d %p %p [[[[%s]]][[[%s]]]"), (int)mon->bufferOffset, mon->msg, msg, str1, str2);
343 344
    VIR_FREE(str1);
    VIR_FREE(str2);
345
# else
346
    VIR_DEBUG("Process %d", (int)mon->bufferOffset);
347
# endif
348 349
#endif

D
Daniel P. Berrange 已提交
350 351 352 353 354 355 356 357
    if (mon->json)
        len = qemuMonitorJSONIOProcess(mon,
                                       mon->buffer, mon->bufferOffset,
                                       msg);
    else
        len = qemuMonitorTextIOProcess(mon,
                                       mon->buffer, mon->bufferOffset,
                                       msg);
358

359
    if (len < 0)
360 361 362 363 364 365 366 367 368
        return -1;

    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;
    }
369
#if DEBUG_IO
370
    VIR_DEBUG("Process done %d used %d", (int)mon->bufferOffset, len);
371
#endif
372 373 374 375 376 377
    if (msg && msg->finished)
        virCondBroadcast(&mon->notify);
    return len;
}


S
Stefan Berger 已提交
378
/* Call this function while holding the monitor lock. */
379 380 381 382 383 384 385 386 387 388 389 390 391
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));
392
    memset(control, 0, sizeof(control));
393 394 395 396 397 398 399 400 401 402 403

    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);
404 405 406
    /* 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);
407 408 409 410 411 412 413 414 415 416 417 418
    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;
}

S
Stefan Berger 已提交
419 420 421 422
/*
 * Called when the monitor is able to write data
 * Call this function while holding the monitor lock.
 */
423 424 425 426 427 428 429 430 431
static int
qemuMonitorIOWrite(qemuMonitorPtr mon)
{
    int done;

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

432 433 434 435 436 437
    if (mon->msg->txFD != -1 && !mon->hasSendFD) {
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Monitor does not support sending of file descriptors"));
        return -1;
    }

438 439 440 441 442 443 444 445 446 447 448 449 450 451
    if (mon->msg->txFD == -1)
        done = write(mon->fd,
                     mon->msg->txBuffer + mon->msg->txOffset,
                     mon->msg->txLength - mon->msg->txOffset);
    else
        done = qemuMonitorIOWriteWithFD(mon,
                                        mon->msg->txBuffer + mon->msg->txOffset,
                                        mon->msg->txLength - mon->msg->txOffset,
                                        mon->msg->txFD);

    if (done < 0) {
        if (errno == EAGAIN)
            return 0;

452 453
        virReportSystemError(errno, "%s",
                             _("Unable to write to monitor"));
454 455 456 457 458 459 460 461
        return -1;
    }
    mon->msg->txOffset += done;
    return done;
}

/*
 * Called when the monitor has incoming data to read
S
Stefan Berger 已提交
462
 * Call this function while holding the monitor lock.
463 464 465 466 467 468 469 470 471 472 473 474
 *
 * 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,
                          mon->bufferLength + 1024) < 0) {
475
            virReportOOMError();
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
            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;
492 493
            virReportSystemError(errno, "%s",
                                 _("Unable to read from monitor"));
494 495 496 497 498 499 500 501 502 503 504 505
            ret = -1;
            break;
        }
        if (got == 0)
            break;

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

506
#if DEBUG_IO
507
    VIR_DEBUG("Now read %d bytes of data", (int)mon->bufferOffset);
508
#endif
509 510 511 512 513 514 515 516 517 518 519

    return ret;
}


static void qemuMonitorUpdateWatch(qemuMonitorPtr mon)
{
    int events =
        VIR_EVENT_HANDLE_HANGUP |
        VIR_EVENT_HANDLE_ERROR;

520
    if (mon->lastError.code == VIR_ERR_OK) {
521 522 523 524 525 526 527
        events |= VIR_EVENT_HANDLE_READABLE;

        if (mon->msg && mon->msg->txOffset < mon->msg->txLength)
            events |= VIR_EVENT_HANDLE_WRITABLE;
    }

    virEventUpdateHandle(mon->watch, events);
528 529
}

530 531 532 533

static void
qemuMonitorIO(int watch, int fd, int events, void *opaque) {
    qemuMonitorPtr mon = opaque;
534 535
    bool error = false;
    bool eof = false;
536

S
Stefan Berger 已提交
537
    /* lock access to the monitor and protect fd */
538
    qemuMonitorLock(mon);
539
    qemuMonitorRef(mon);
540
#if DEBUG_IO
541
    VIR_DEBUG("Monitor %p I/O on watch %d fd %d events %d", mon, watch, fd, events);
542
#endif
543

544
    if (mon->fd != fd || mon->watch != watch) {
545
        if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
546 547 548 549 550 551
            eof = true;
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
                        _("event from unexpected fd %d!=%d / watch %d!=%d"),
                        mon->fd, fd, mon->watch, watch);
        error = true;
    } else if (mon->lastError.code != VIR_ERR_OK) {
552
        if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
553
            eof = true;
554
        error = true;
555
    } else {
556 557 558
        if (events & VIR_EVENT_HANDLE_WRITABLE) {
            if (qemuMonitorIOWrite(mon) < 0)
                error = true;
559 560
            events &= ~VIR_EVENT_HANDLE_WRITABLE;
        }
561 562

        if (!error &&
563 564
            events & VIR_EVENT_HANDLE_READABLE) {
            int got = qemuMonitorIORead(mon);
565 566
            events &= ~VIR_EVENT_HANDLE_READABLE;
            if (got < 0) {
567
                error = true;
568 569 570 571 572
            } 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 */
573 574 575
                events = 0;

                if (qemuMonitorIOProcess(mon) < 0)
576
                    error = true;
577
            }
578 579
        }

580 581 582 583 584 585
        if (!error &&
            events & VIR_EVENT_HANDLE_HANGUP) {
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
                            _("End of file from monitor"));
            eof = 1;
            events &= ~VIR_EVENT_HANDLE_HANGUP;
586 587
        }

588 589 590
        if (!error && !eof &&
            events & VIR_EVENT_HANDLE_ERROR) {
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
591 592 593
                            _("Invalid file descriptor while waiting for monitor"));
            eof = 1;
            events &= ~VIR_EVENT_HANDLE_ERROR;
594 595 596 597 598
        }
        if (!error && events) {
            qemuReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Unhandled event %d for monitor fd %d"),
                            events, mon->fd);
599
            error = 1;
600 601 602
        }
    }

603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
    if (error || eof) {
        if (mon->lastError.code != VIR_ERR_OK) {
            /* Already have an error, so clear any new error */
            virResetLastError();
        } else {
            virErrorPtr err = virGetLastError();
            if (!err)
                qemuReportError(VIR_ERR_INTERNAL_ERROR,
                                _("Error while processing monitor IO"));
            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);
        }
    }
624 625 626

    qemuMonitorUpdateWatch(mon);

627 628 629
    /* 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 */
630 631
    if (eof) {
        void (*eofNotify)(qemuMonitorPtr, virDomainObjPtr)
632
            = mon->cb->eofNotify;
633
        virDomainObjPtr vm = mon->vm;
634

635 636 637 638 639 640 641 642 643 644
        /* Make sure anyone waiting wakes up now */
        virCondSignal(&mon->notify);
        if (qemuMonitorUnref(mon) > 0)
            qemuMonitorUnlock(mon);
        VIR_DEBUG("Triggering EOF callback");
        (eofNotify)(mon, vm);
    } else if (error) {
        void (*errorNotify)(qemuMonitorPtr, virDomainObjPtr)
            = mon->cb->errorNotify;
        virDomainObjPtr vm = mon->vm;
645

646 647
        /* Make sure anyone waiting wakes up now */
        virCondSignal(&mon->notify);
648
        if (qemuMonitorUnref(mon) > 0)
649
            qemuMonitorUnlock(mon);
650 651
        VIR_DEBUG("Triggering error callback");
        (errorNotify)(mon, vm);
652
    } else {
653 654
        if (qemuMonitorUnref(mon) > 0)
            qemuMonitorUnlock(mon);
655
    }
656 657 658 659
}


qemuMonitorPtr
660
qemuMonitorOpen(virDomainObjPtr vm,
661
                virDomainChrSourceDefPtr config,
D
Daniel P. Berrange 已提交
662
                int json,
663
                qemuMonitorCallbacksPtr cb)
664
{
665 666
    qemuMonitorPtr mon;

667
    if (!cb || !cb->eofNotify) {
668 669
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("EOF notify callback must be supplied"));
670 671 672
        return NULL;
    }

673
    if (VIR_ALLOC(mon) < 0) {
674
        virReportOOMError();
675 676 677
        return NULL;
    }

678
    if (virMutexInit(&mon->lock) < 0) {
679 680
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("cannot initialize monitor mutex"));
681 682 683
        VIR_FREE(mon);
        return NULL;
    }
684
    if (virCondInit(&mon->notify) < 0) {
685 686
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("cannot initialize monitor condition"));
687 688 689 690
        virMutexDestroy(&mon->lock);
        VIR_FREE(mon);
        return NULL;
    }
691
    mon->fd = -1;
692
    mon->refs = 1;
693
    mon->vm = vm;
D
Daniel P. Berrange 已提交
694
    mon->json = json;
695
    mon->cb = cb;
696
    qemuMonitorLock(mon);
697

698
    switch (config->type) {
699
    case VIR_DOMAIN_CHR_TYPE_UNIX:
700
        mon->hasSendFD = 1;
701
        mon->fd = qemuMonitorOpenUnix(config->data.nix.path, vm->pid);
702 703
        break;

704
    case VIR_DOMAIN_CHR_TYPE_PTY:
705
        mon->fd = qemuMonitorOpenPty(config->data.file.path);
706 707
        break;

708
    default:
709 710
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unable to handle monitor type: %s"),
711
                        virDomainChrTypeToString(config->type));
712 713 714
        goto cleanup;
    }

715 716
    if (mon->fd == -1) goto cleanup;

717
    if (virSetCloseExec(mon->fd) < 0) {
718 719
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
                        "%s", _("Unable to set monitor close-on-exec flag"));
720 721 722
        goto cleanup;
    }
    if (virSetNonBlock(mon->fd) < 0) {
723 724
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
                        "%s", _("Unable to put monitor into non-blocking mode"));
725 726 727 728
        goto cleanup;
    }


729
    if ((mon->watch = virEventAddHandle(mon->fd,
730 731 732
                                        VIR_EVENT_HANDLE_HANGUP |
                                        VIR_EVENT_HANDLE_ERROR |
                                        VIR_EVENT_HANDLE_READABLE,
733
                                        qemuMonitorIO,
734
                                        mon, qemuMonitorUnwatch)) < 0) {
735 736
        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("unable to register monitor events"));
737 738
        goto cleanup;
    }
739
    qemuMonitorRef(mon);
740

741 742
    VIR_DEBUG("New mon %p fd =%d watch=%d", mon, mon->fd, mon->watch);
    qemuMonitorUnlock(mon);
743

744 745 746
    return mon;

cleanup:
747 748 749 750 751 752
    /* 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;
753
    qemuMonitorUnlock(mon);
754 755 756 757 758
    qemuMonitorClose(mon);
    return NULL;
}


759
void qemuMonitorClose(qemuMonitorPtr mon)
760 761
{
    if (!mon)
762
        return;
763 764

    VIR_DEBUG("mon=%p", mon);
765

766
    qemuMonitorLock(mon);
S
Stefan Berger 已提交
767 768

    if (mon->fd >= 0) {
769 770
        if (mon->watch)
            virEventRemoveHandle(mon->watch);
S
Stefan Berger 已提交
771
        VIR_FORCE_CLOSE(mon->fd);
772
    }
773

E
Eric Blake 已提交
774
    if (qemuMonitorUnref(mon) > 0)
775
        qemuMonitorUnlock(mon);
776 777 778
}


779 780 781 782 783 784 785 786 787 788 789 790
char *qemuMonitorNextCommandID(qemuMonitorPtr mon)
{
    char *id;

    if (virAsprintf(&id, "libvirt-%d", ++mon->nextSerial) < 0) {
        virReportOOMError();
        return NULL;
    }
    return id;
}


791 792
int qemuMonitorSend(qemuMonitorPtr mon,
                    qemuMonitorMessagePtr msg)
793
{
794
    int ret = -1;
795

796
    /* Check whether qemu quited unexpectedly */
797 798 799 800
    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);
801 802 803
        return -1;
    }

804 805
    mon->msg = msg;
    qemuMonitorUpdateWatch(mon);
806

807
    while (!mon->msg->finished) {
808 809 810
        if (virCondWait(&mon->notify, &mon->lock) < 0) {
            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Unable to wait on monitor condition"));
811
            goto cleanup;
812 813 814 815 816 817 818 819
        }
    }

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

822
    ret = 0;
823

824 825 826
cleanup:
    mon->msg = NULL;
    qemuMonitorUpdateWatch(mon);
827

828
    return ret;
829
}
830 831


832 833 834 835
int qemuMonitorHMPCommandWithFd(qemuMonitorPtr mon,
                                const char *cmd,
                                int scm_fd,
                                char **reply)
836 837 838 839 840 841 842
{
    if (mon->json)
        return qemuMonitorJSONHumanCommandWithFd(mon, cmd, scm_fd, reply);
    else
        return qemuMonitorTextCommandWithFd(mon, cmd, scm_fd, reply);
}

E
Eric Blake 已提交
843 844 845 846 847 848 849 850
/* Ensure proper locking around callbacks.  */
#define QEMU_MONITOR_CALLBACK(mon, ret, callback, ...)          \
    do {                                                        \
        qemuMonitorRef(mon);                                    \
        qemuMonitorUnlock(mon);                                 \
        if ((mon)->cb && (mon)->cb->callback)                   \
            (ret) = ((mon)->cb->callback)(mon, __VA_ARGS__);    \
        qemuMonitorLock(mon);                                   \
851
        ignore_value(qemuMonitorUnref(mon));                    \
E
Eric Blake 已提交
852
    } while (0)
853

854 855 856 857 858 859
int qemuMonitorGetDiskSecret(qemuMonitorPtr mon,
                             virConnectPtr conn,
                             const char *path,
                             char **secret,
                             size_t *secretLen)
{
860
    int ret = -1;
861 862 863
    *secret = NULL;
    *secretLen = 0;

E
Eric Blake 已提交
864 865
    QEMU_MONITOR_CALLBACK(mon, ret, diskSecretLookup, conn, mon->vm,
                          path, secret, secretLen);
866
    return ret;
867
}
868 869


870 871 872 873 874
int qemuMonitorEmitShutdown(qemuMonitorPtr mon)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
875
    QEMU_MONITOR_CALLBACK(mon, ret, domainShutdown, mon->vm);
876 877 878 879 880 881 882 883 884
    return ret;
}


int qemuMonitorEmitReset(qemuMonitorPtr mon)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
885
    QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm);
886 887 888 889 890 891 892 893 894
    return ret;
}


int qemuMonitorEmitPowerdown(qemuMonitorPtr mon)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
895
    QEMU_MONITOR_CALLBACK(mon, ret, domainPowerdown, mon->vm);
896 897 898 899 900 901 902 903 904
    return ret;
}


int qemuMonitorEmitStop(qemuMonitorPtr mon)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
905
    QEMU_MONITOR_CALLBACK(mon, ret, domainStop, mon->vm);
906 907 908 909
    return ret;
}


910 911 912 913 914
int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
915
    QEMU_MONITOR_CALLBACK(mon, ret, domainRTCChange, mon->vm, offset);
916 917 918 919
    return ret;
}


920 921 922 923 924
int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
925
    QEMU_MONITOR_CALLBACK(mon, ret, domainWatchdog, mon->vm, action);
926 927 928 929
    return ret;
}


930 931
int qemuMonitorEmitIOError(qemuMonitorPtr mon,
                           const char *diskAlias,
932 933
                           int action,
                           const char *reason)
934 935 936 937
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
938 939
    QEMU_MONITOR_CALLBACK(mon, ret, domainIOError, mon->vm,
                          diskAlias, action, reason);
940 941 942 943
    return ret;
}


944 945 946 947 948 949 950 951 952 953 954 955 956 957 958
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)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

E
Eric Blake 已提交
959 960 961 962
    QEMU_MONITOR_CALLBACK(mon, ret, domainGraphics, mon->vm, phase,
                          localFamily, localNode, localService,
                          remoteFamily, remoteNode, remoteService,
                          authScheme, x509dname, saslUsername);
963 964 965
    return ret;
}

966 967 968 969 970 971 972 973 974 975 976 977 978
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
                            const char *diskAlias,
                            int type,
                            int status)
{
    int ret = -1;
    VIR_DEBUG("mon=%p", mon);

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

979 980


981 982 983
int qemuMonitorSetCapabilities(qemuMonitorPtr mon)
{
    int ret;
984
    VIR_DEBUG("mon=%p", mon);
985 986 987 988 989 990

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
991

992
    if (mon->json) {
993
        ret = qemuMonitorJSONSetCapabilities(mon);
994 995 996 997 998 999 1000 1001 1002 1003
        if (ret == 0) {
            int hmp = qemuMonitorJSONCheckHMP(mon);
            if (hmp < 0) {
                /* qemu may quited unexpectedly when we call
                 * qemuMonitorJSONCheckHMP() */
                ret = -1;
            } else {
                mon->json_hmp = hmp > 0;
            }
        }
1004
    } else {
1005
        ret = 0;
1006
    }
1007 1008 1009 1010
    return ret;
}


1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
int
qemuMonitorCheckHMP(qemuMonitorPtr mon, const char *cmd)
{
    if (!mon->json || mon->json_hmp)
        return 1;

    if (cmd) {
        VIR_DEBUG("HMP passthrough not supported by qemu process;"
                  " not trying HMP for command %s", cmd);
    }

    return 0;
}


1026 1027 1028 1029
int
qemuMonitorStartCPUs(qemuMonitorPtr mon,
                     virConnectPtr conn)
{
D
Daniel P. Berrange 已提交
1030
    int ret;
1031
    VIR_DEBUG("mon=%p", mon);
1032 1033 1034 1035 1036 1037

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1038

D
Daniel P. Berrange 已提交
1039 1040 1041 1042 1043
    if (mon->json)
        ret = qemuMonitorJSONStartCPUs(mon, conn);
    else
        ret = qemuMonitorTextStartCPUs(mon, conn);
    return ret;
1044 1045 1046 1047 1048 1049
}


int
qemuMonitorStopCPUs(qemuMonitorPtr mon)
{
D
Daniel P. Berrange 已提交
1050
    int ret;
1051
    VIR_DEBUG("mon=%p", mon);
1052 1053 1054 1055 1056 1057

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1058

D
Daniel P. Berrange 已提交
1059 1060 1061 1062 1063
    if (mon->json)
        ret = qemuMonitorJSONStopCPUs(mon);
    else
        ret = qemuMonitorTextStopCPUs(mon);
    return ret;
1064 1065 1066
}


1067
int
1068 1069 1070
qemuMonitorGetStatus(qemuMonitorPtr mon,
                     bool *running,
                     virDomainPausedReason *reason)
1071 1072
{
    int ret;
1073
    VIR_DEBUG("mon=%p, running=%p, reason=%p", mon, running, reason);
1074 1075 1076 1077 1078 1079 1080 1081

    if (!mon || !running) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("both monitor and running must not be NULL"));
        return -1;
    }

    if (mon->json)
1082
        ret = qemuMonitorJSONGetStatus(mon, running, reason);
1083
    else
1084
        ret = qemuMonitorTextGetStatus(mon, running, reason);
1085 1086 1087 1088
    return ret;
}


1089 1090
int qemuMonitorSystemPowerdown(qemuMonitorPtr mon)
{
D
Daniel P. Berrange 已提交
1091
    int ret;
1092
    VIR_DEBUG("mon=%p", mon);
1093 1094 1095 1096 1097 1098

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1099

D
Daniel P. Berrange 已提交
1100 1101 1102 1103 1104
    if (mon->json)
        ret = qemuMonitorJSONSystemPowerdown(mon);
    else
        ret = qemuMonitorTextSystemPowerdown(mon);
    return ret;
1105 1106 1107
}


1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
int qemuMonitorSystemReset(qemuMonitorPtr mon)
{
    int ret;
    VIR_DEBUG("mon=%p", mon);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

    if (mon->json)
        ret = qemuMonitorJSONSystemReset(mon);
    else
        ret = qemuMonitorTextSystemReset(mon);
    return ret;
}


1127 1128 1129
int qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
                          int **pids)
{
D
Daniel P. Berrange 已提交
1130
    int ret;
1131
    VIR_DEBUG("mon=%p", mon);
1132 1133 1134 1135 1136 1137

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1138

D
Daniel P. Berrange 已提交
1139 1140 1141 1142 1143
    if (mon->json)
        ret = qemuMonitorJSONGetCPUInfo(mon, pids);
    else
        ret = qemuMonitorTextGetCPUInfo(mon, pids);
    return ret;
1144 1145
}

1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
int qemuMonitorSetLink(qemuMonitorPtr mon,
                       const char *name,
                       enum virDomainNetInterfaceLinkState state)
{
    int ret;
    VIR_DEBUG("mon=%p, name=%p:%s, state=%u", mon, name, name, state);

    if (!mon || !name) {
        qemuReportError(VIR_ERR_INVALID_ARG,
                        _("monitor || name must not be NULL"));
        return -1;
    }

    if (mon->json)
        ret = qemuMonitorJSONSetLink(mon, name, state);
    else
        ret = qemuMonitorTextSetLink(mon, name, state);
    return ret;
}
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185

int qemuMonitorGetVirtType(qemuMonitorPtr mon,
                           int *virtType)
{
    int ret;
    VIR_DEBUG("mon=%p", mon);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

    if (mon->json)
        ret = qemuMonitorJSONGetVirtType(mon, virtType);
    else
        ret = qemuMonitorTextGetVirtType(mon, virtType);
    return ret;
}


1186 1187 1188
int qemuMonitorGetBalloonInfo(qemuMonitorPtr mon,
                              unsigned long *currmem)
{
D
Daniel P. Berrange 已提交
1189
    int ret;
1190
    VIR_DEBUG("mon=%p", mon);
1191 1192 1193 1194 1195 1196

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1197

D
Daniel P. Berrange 已提交
1198 1199 1200 1201 1202
    if (mon->json)
        ret = qemuMonitorJSONGetBalloonInfo(mon, currmem);
    else
        ret = qemuMonitorTextGetBalloonInfo(mon, currmem);
    return ret;
1203 1204 1205
}


1206 1207 1208 1209 1210
int qemuMonitorGetMemoryStats(qemuMonitorPtr mon,
                              virDomainMemoryStatPtr stats,
                              unsigned int nr_stats)
{
    int ret;
1211
    VIR_DEBUG("mon=%p stats=%p nstats=%u", mon, stats, nr_stats);
1212 1213 1214 1215 1216 1217

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1218 1219 1220 1221 1222 1223 1224 1225 1226

    if (mon->json)
        ret = qemuMonitorJSONGetMemoryStats(mon, stats, nr_stats);
    else
        ret = qemuMonitorTextGetMemoryStats(mon, stats, nr_stats);
    return ret;
}


1227
int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
1228
                                 const char *dev_name,
1229 1230
                                 long long *rd_req,
                                 long long *rd_bytes,
1231
                                 long long *rd_total_times,
1232 1233
                                 long long *wr_req,
                                 long long *wr_bytes,
1234 1235 1236
                                 long long *wr_total_times,
                                 long long *flush_req,
                                 long long *flush_total_times,
1237 1238
                                 long long *errs)
{
D
Daniel P. Berrange 已提交
1239
    int ret;
1240
    VIR_DEBUG("mon=%p dev=%s", mon, dev_name);
1241 1242 1243 1244 1245 1246

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1247

D
Daniel P. Berrange 已提交
1248
    if (mon->json)
1249
        ret = qemuMonitorJSONGetBlockStatsInfo(mon, dev_name,
D
Daniel P. Berrange 已提交
1250
                                               rd_req, rd_bytes,
1251
                                               rd_total_times,
D
Daniel P. Berrange 已提交
1252
                                               wr_req, wr_bytes,
1253 1254 1255
                                               wr_total_times,
                                               flush_req,
                                               flush_total_times,
D
Daniel P. Berrange 已提交
1256 1257
                                               errs);
    else
1258
        ret = qemuMonitorTextGetBlockStatsInfo(mon, dev_name,
D
Daniel P. Berrange 已提交
1259
                                               rd_req, rd_bytes,
1260
                                               rd_total_times,
D
Daniel P. Berrange 已提交
1261
                                               wr_req, wr_bytes,
1262 1263 1264
                                               wr_total_times,
                                               flush_req,
                                               flush_total_times,
D
Daniel P. Berrange 已提交
1265 1266
                                               errs);
    return ret;
1267 1268
}

1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291
/* Return 0 and update @nparams with the number of block stats
 * QEMU supports if success. Return -1 if failure.
 */
int qemuMonitorGetBlockStatsParamsNumber(qemuMonitorPtr mon,
                                         int *nparams)
{
    int ret;
    VIR_DEBUG("mon=%p nparams=%p", mon, nparams);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

    if (mon->json)
        ret = qemuMonitorJSONGetBlockStatsParamsNumber(mon, nparams);
    else
        ret = qemuMonitorTextGetBlockStatsParamsNumber(mon, nparams);

    return ret;
}

1292
int qemuMonitorGetBlockExtent(qemuMonitorPtr mon,
1293
                              const char *dev_name,
1294 1295 1296
                              unsigned long long *extent)
{
    int ret;
1297 1298
    VIR_DEBUG("mon=%p, fd=%d, dev_name=%p",
          mon, mon->fd, dev_name);
1299 1300

    if (mon->json)
1301
        ret = qemuMonitorJSONGetBlockExtent(mon, dev_name, extent);
1302
    else
1303
        ret = qemuMonitorTextGetBlockExtent(mon, dev_name, extent);
1304 1305 1306 1307

    return ret;
}

1308 1309 1310 1311

int qemuMonitorSetVNCPassword(qemuMonitorPtr mon,
                              const char *password)
{
D
Daniel P. Berrange 已提交
1312
    int ret;
1313
    VIR_DEBUG("mon=%p, password=%p",
1314 1315 1316 1317 1318 1319 1320
          mon, password);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1321

1322 1323 1324
    if (!password)
        password = "";

D
Daniel P. Berrange 已提交
1325 1326 1327 1328 1329
    if (mon->json)
        ret = qemuMonitorJSONSetVNCPassword(mon, password);
    else
        ret = qemuMonitorTextSetVNCPassword(mon, password);
    return ret;
1330 1331
}

1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358
static const char* qemuMonitorTypeToProtocol(int type)
{
    switch (type) {
    case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
        return "vnc";
    case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
        return "spice";
    default:
        qemuReportError(VIR_ERR_INVALID_ARG,
                        _("unsupported protocol type %s"),
                        virDomainGraphicsTypeToString(type));
        return NULL;
    }
}

/* Returns -2 if not supported with this monitor connection */
int qemuMonitorSetPassword(qemuMonitorPtr mon,
                           int type,
                           const char *password,
                           const char *action_if_connected)
{
    const char *protocol = qemuMonitorTypeToProtocol(type);
    int ret;

    if (!protocol)
        return -1;

1359
    VIR_DEBUG("mon=%p, protocol=%s, password=%p, action_if_connected=%s",
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390
          mon, protocol, password, action_if_connected);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

    if (!password)
        password = "";

    if (!action_if_connected)
        action_if_connected = "keep";

    if (mon->json)
        ret = qemuMonitorJSONSetPassword(mon, protocol, password, action_if_connected);
    else
        ret = qemuMonitorTextSetPassword(mon, protocol, password, action_if_connected);
    return ret;
}

int qemuMonitorExpirePassword(qemuMonitorPtr mon,
                              int type,
                              const char *expire_time)
{
    const char *protocol = qemuMonitorTypeToProtocol(type);
    int ret;

    if (!protocol)
        return -1;

1391
    VIR_DEBUG("mon=%p, protocol=%s, expire_time=%s",
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
          mon, protocol, expire_time);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

    if (!expire_time)
        expire_time = "now";

    if (mon->json)
        ret = qemuMonitorJSONExpirePassword(mon, protocol, expire_time);
    else
        ret = qemuMonitorTextExpirePassword(mon, protocol, expire_time);
    return ret;
}
1409 1410 1411 1412

int qemuMonitorSetBalloon(qemuMonitorPtr mon,
                          unsigned long newmem)
{
D
Daniel P. Berrange 已提交
1413
    int ret;
1414
    VIR_DEBUG("mon=%p newmem=%lu", mon, newmem);
1415 1416 1417 1418 1419 1420

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1421

D
Daniel P. Berrange 已提交
1422 1423 1424 1425 1426
    if (mon->json)
        ret = qemuMonitorJSONSetBalloon(mon, newmem);
    else
        ret = qemuMonitorTextSetBalloon(mon, newmem);
    return ret;
1427 1428
}

1429 1430 1431 1432

int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, int online)
{
    int ret;
1433
    VIR_DEBUG("mon=%p cpu=%d online=%d", mon, cpu, online);
1434 1435 1436 1437 1438 1439

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1440 1441 1442 1443 1444 1445 1446 1447 1448

    if (mon->json)
        ret = qemuMonitorJSONSetCPU(mon, cpu, online);
    else
        ret = qemuMonitorTextSetCPU(mon, cpu, online);
    return ret;
}


1449
int qemuMonitorEjectMedia(qemuMonitorPtr mon,
1450
                          const char *dev_name,
1451
                          bool force)
1452
{
D
Daniel P. Berrange 已提交
1453
    int ret;
1454
    VIR_DEBUG("mon=%p dev_name=%s force=%d", mon, dev_name, force);
1455 1456 1457 1458 1459 1460

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1461

D
Daniel P. Berrange 已提交
1462
    if (mon->json)
1463
        ret = qemuMonitorJSONEjectMedia(mon, dev_name, force);
D
Daniel P. Berrange 已提交
1464
    else
1465
        ret = qemuMonitorTextEjectMedia(mon, dev_name, force);
D
Daniel P. Berrange 已提交
1466
    return ret;
1467 1468 1469 1470
}


int qemuMonitorChangeMedia(qemuMonitorPtr mon,
1471
                           const char *dev_name,
1472 1473
                           const char *newmedia,
                           const char *format)
1474
{
D
Daniel P. Berrange 已提交
1475
    int ret;
1476 1477
    VIR_DEBUG("mon=%p dev_name=%s newmedia=%s format=%s",
          mon, dev_name, newmedia, format);
1478 1479 1480 1481 1482 1483

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1484

D
Daniel P. Berrange 已提交
1485
    if (mon->json)
1486
        ret = qemuMonitorJSONChangeMedia(mon, dev_name, newmedia, format);
D
Daniel P. Berrange 已提交
1487
    else
1488
        ret = qemuMonitorTextChangeMedia(mon, dev_name, newmedia, format);
D
Daniel P. Berrange 已提交
1489
    return ret;
1490 1491 1492 1493 1494 1495 1496 1497
}


int qemuMonitorSaveVirtualMemory(qemuMonitorPtr mon,
                                 unsigned long long offset,
                                 size_t length,
                                 const char *path)
{
D
Daniel P. Berrange 已提交
1498
    int ret;
1499
    VIR_DEBUG("mon=%p offset=%llu length=%zu path=%s",
1500 1501 1502 1503 1504 1505 1506
          mon, offset, length, path);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1507

D
Daniel P. Berrange 已提交
1508 1509 1510 1511 1512
    if (mon->json)
        ret = qemuMonitorJSONSaveVirtualMemory(mon, offset, length, path);
    else
        ret = qemuMonitorTextSaveVirtualMemory(mon, offset, length, path);
    return ret;
1513 1514 1515 1516 1517 1518 1519
}

int qemuMonitorSavePhysicalMemory(qemuMonitorPtr mon,
                                  unsigned long long offset,
                                  size_t length,
                                  const char *path)
{
D
Daniel P. Berrange 已提交
1520
    int ret;
1521
    VIR_DEBUG("mon=%p offset=%llu length=%zu path=%s",
1522 1523 1524 1525 1526 1527 1528
          mon, offset, length, path);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1529

D
Daniel P. Berrange 已提交
1530 1531 1532 1533 1534
    if (mon->json)
        ret = qemuMonitorJSONSavePhysicalMemory(mon, offset, length, path);
    else
        ret = qemuMonitorTextSavePhysicalMemory(mon, offset, length, path);
    return ret;
1535 1536 1537 1538 1539 1540
}


int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon,
                                 unsigned long bandwidth)
{
D
Daniel P. Berrange 已提交
1541
    int ret;
1542
    VIR_DEBUG("mon=%p bandwidth=%lu", mon, bandwidth);
1543 1544 1545 1546 1547 1548

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1549

D
Daniel P. Berrange 已提交
1550 1551 1552 1553 1554
    if (mon->json)
        ret = qemuMonitorJSONSetMigrationSpeed(mon, bandwidth);
    else
        ret = qemuMonitorTextSetMigrationSpeed(mon, bandwidth);
    return ret;
1555 1556
}

1557 1558 1559 1560 1561

int qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon,
                                    unsigned long long downtime)
{
    int ret;
1562
    VIR_DEBUG("mon=%p downtime=%llu", mon, downtime);
1563 1564 1565 1566 1567 1568

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1569 1570 1571 1572 1573 1574 1575 1576 1577

    if (mon->json)
        ret = qemuMonitorJSONSetMigrationDowntime(mon, downtime);
    else
        ret = qemuMonitorTextSetMigrationDowntime(mon, downtime);
    return ret;
}


1578 1579 1580 1581 1582 1583
int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
                                  int *status,
                                  unsigned long long *transferred,
                                  unsigned long long *remaining,
                                  unsigned long long *total)
{
D
Daniel P. Berrange 已提交
1584
    int ret;
1585
    VIR_DEBUG("mon=%p", mon);
1586 1587 1588 1589 1590 1591

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1592

D
Daniel P. Berrange 已提交
1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603
    if (mon->json)
        ret = qemuMonitorJSONGetMigrationStatus(mon, status,
                                                transferred,
                                                remaining,
                                                total);
    else
        ret = qemuMonitorTextGetMigrationStatus(mon, status,
                                                transferred,
                                                remaining,
                                                total);
    return ret;
1604 1605 1606
}


E
Eric Blake 已提交
1607 1608 1609 1610 1611
int qemuMonitorMigrateToFd(qemuMonitorPtr mon,
                           unsigned int flags,
                           int fd)
{
    int ret;
1612
    VIR_DEBUG("mon=%p fd=%d flags=%x",
E
Eric Blake 已提交
1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630
          mon, fd, flags);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

    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)
1631
            VIR_WARN("failed to close migration handle");
E
Eric Blake 已提交
1632 1633 1634 1635 1636 1637
    }

    return ret;
}


1638
int qemuMonitorMigrateToHost(qemuMonitorPtr mon,
1639
                             unsigned int flags,
1640 1641 1642
                             const char *hostname,
                             int port)
{
D
Daniel P. Berrange 已提交
1643
    int ret;
1644
    char *uri = NULL;
1645
    VIR_DEBUG("mon=%p hostname=%s port=%d flags=%x",
1646
          mon, hostname, port, flags);
1647 1648 1649 1650 1651 1652

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1653

1654 1655 1656 1657 1658 1659

    if (virAsprintf(&uri, "tcp:%s:%d", hostname, port) < 0) {
        virReportOOMError();
        return -1;
    }

D
Daniel P. Berrange 已提交
1660
    if (mon->json)
1661
        ret = qemuMonitorJSONMigrate(mon, flags, uri);
D
Daniel P. Berrange 已提交
1662
    else
1663 1664 1665
        ret = qemuMonitorTextMigrate(mon, flags, uri);

    VIR_FREE(uri);
D
Daniel P. Berrange 已提交
1666
    return ret;
1667 1668 1669 1670
}


int qemuMonitorMigrateToCommand(qemuMonitorPtr mon,
1671
                                unsigned int flags,
1672
                                const char * const *argv)
1673
{
1674 1675 1676
    char *argstr;
    char *dest = NULL;
    int ret = -1;
1677
    VIR_DEBUG("mon=%p argv=%p flags=%x",
1678
          mon, argv, flags);
1679 1680 1681 1682 1683 1684

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1685

1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
    argstr = virArgvToString(argv);
    if (!argstr) {
        virReportOOMError();
        goto cleanup;
    }

    if (virAsprintf(&dest, "exec:%s", argstr) < 0) {
        virReportOOMError();
        goto cleanup;
    }

D
Daniel P. Berrange 已提交
1697
    if (mon->json)
1698
        ret = qemuMonitorJSONMigrate(mon, flags, dest);
D
Daniel P. Berrange 已提交
1699
    else
1700 1701 1702 1703 1704
        ret = qemuMonitorTextMigrate(mon, flags, dest);

cleanup:
    VIR_FREE(argstr);
    VIR_FREE(dest);
1705 1706 1707 1708
    return ret;
}

int qemuMonitorMigrateToFile(qemuMonitorPtr mon,
1709
                             unsigned int flags,
1710 1711 1712 1713
                             const char * const *argv,
                             const char *target,
                             unsigned long long offset)
{
1714 1715 1716 1717
    char *argstr;
    char *dest = NULL;
    int ret = -1;
    char *safe_target = NULL;
1718
    VIR_DEBUG("mon=%p argv=%p target=%s offset=%llu flags=%x",
1719
          mon, argv, target, offset, flags);
1720 1721 1722 1723 1724 1725

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1726 1727 1728 1729 1730 1731 1732 1733

    if (offset % QEMU_MONITOR_MIGRATE_TO_FILE_BS) {
        qemuReportError(VIR_ERR_INTERNAL_ERROR,
                        _("file offset must be a multiple of %llu"),
                        QEMU_MONITOR_MIGRATE_TO_FILE_BS);
        return -1;
    }

1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752
    argstr = virArgvToString(argv);
    if (!argstr) {
        virReportOOMError();
        goto cleanup;
    }

    /* Migrate to file */
    safe_target = qemuMonitorEscapeShell(target);
    if (!safe_target) {
        virReportOOMError();
        goto cleanup;
    }

    /* Two dd processes, sharing the same stdout, are necessary to
     * allow starting at an alignment of 512, but without wasting
     * padding to get to the larger alignment useful for speed.  Use
     * <> redirection to avoid truncating a regular file.  */
    if (virAsprintf(&dest, "exec:" VIR_WRAPPER_SHELL_PREFIX "%s | "
                    "{ dd bs=%llu seek=%llu if=/dev/null && "
1753
                    "dd ibs=%llu obs=%llu; } 1<>%s" VIR_WRAPPER_SHELL_SUFFIX,
1754 1755 1756
                    argstr, QEMU_MONITOR_MIGRATE_TO_FILE_BS,
                    offset / QEMU_MONITOR_MIGRATE_TO_FILE_BS,
                    QEMU_MONITOR_MIGRATE_TO_FILE_TRANSFER_SIZE,
1757
                    QEMU_MONITOR_MIGRATE_TO_FILE_TRANSFER_SIZE,
1758 1759 1760 1761 1762
                    safe_target) < 0) {
        virReportOOMError();
        goto cleanup;
    }

1763
    if (mon->json)
1764
        ret = qemuMonitorJSONMigrate(mon, flags, dest);
1765
    else
1766 1767 1768 1769 1770 1771
        ret = qemuMonitorTextMigrate(mon, flags, dest);

cleanup:
    VIR_FREE(safe_target);
    VIR_FREE(argstr);
    VIR_FREE(dest);
D
Daniel P. Berrange 已提交
1772
    return ret;
1773 1774 1775
}

int qemuMonitorMigrateToUnix(qemuMonitorPtr mon,
1776
                             unsigned int flags,
1777 1778
                             const char *unixfile)
{
1779 1780
    char *dest = NULL;
    int ret = -1;
1781
    VIR_DEBUG("mon=%p, unixfile=%s flags=%x",
1782
          mon, unixfile, flags);
1783 1784 1785 1786 1787 1788

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1789

1790 1791 1792 1793 1794
    if (virAsprintf(&dest, "unix:%s", unixfile) < 0) {
        virReportOOMError();
        return -1;
    }

D
Daniel P. Berrange 已提交
1795
    if (mon->json)
1796
        ret = qemuMonitorJSONMigrate(mon, flags, dest);
D
Daniel P. Berrange 已提交
1797
    else
1798 1799 1800
        ret = qemuMonitorTextMigrate(mon, flags, dest);

    VIR_FREE(dest);
D
Daniel P. Berrange 已提交
1801
    return ret;
1802 1803 1804 1805
}

int qemuMonitorMigrateCancel(qemuMonitorPtr mon)
{
D
Daniel P. Berrange 已提交
1806
    int ret;
1807
    VIR_DEBUG("mon=%p", mon);
1808 1809 1810 1811 1812 1813

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1814

D
Daniel P. Berrange 已提交
1815 1816 1817 1818 1819
    if (mon->json)
        ret = qemuMonitorJSONMigrateCancel(mon);
    else
        ret = qemuMonitorTextMigrateCancel(mon);
    return ret;
1820 1821
}

1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852

int qemuMonitorGraphicsRelocate(qemuMonitorPtr mon,
                                int type,
                                const char *hostname,
                                int port,
                                int tlsPort,
                                const char *tlsSubject)
{
    int ret;
    VIR_DEBUG("mon=%p type=%d hostname=%s port=%d tlsPort=%d tlsSubject=%s",
              mon, type, hostname, port, tlsPort, NULLSTR(tlsSubject));

    if (mon->json)
        ret = qemuMonitorJSONGraphicsRelocate(mon,
                                              type,
                                              hostname,
                                              port,
                                              tlsPort,
                                              tlsSubject);
    else
        ret = qemuMonitorTextGraphicsRelocate(mon,
                                              type,
                                              hostname,
                                              port,
                                              tlsPort,
                                              tlsSubject);

    return ret;
}


1853 1854 1855
int qemuMonitorAddUSBDisk(qemuMonitorPtr mon,
                          const char *path)
{
D
Daniel P. Berrange 已提交
1856
    int ret;
1857
    VIR_DEBUG("mon=%p path=%s", mon, path);
1858 1859 1860 1861 1862 1863

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1864

D
Daniel P. Berrange 已提交
1865 1866 1867 1868 1869
    if (mon->json)
        ret = qemuMonitorJSONAddUSBDisk(mon, path);
    else
        ret = qemuMonitorTextAddUSBDisk(mon, path);
    return ret;
1870 1871 1872 1873 1874 1875 1876
}


int qemuMonitorAddUSBDeviceExact(qemuMonitorPtr mon,
                                 int bus,
                                 int dev)
{
D
Daniel P. Berrange 已提交
1877
    int ret;
1878
    VIR_DEBUG("mon=%p bus=%d dev=%d", mon, bus, dev);
1879 1880 1881 1882 1883 1884

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1885

D
Daniel P. Berrange 已提交
1886 1887 1888 1889 1890
    if (mon->json)
        ret = qemuMonitorJSONAddUSBDeviceExact(mon, bus, dev);
    else
        ret = qemuMonitorTextAddUSBDeviceExact(mon, bus, dev);
    return ret;
1891 1892 1893 1894 1895 1896
}

int qemuMonitorAddUSBDeviceMatch(qemuMonitorPtr mon,
                                 int vendor,
                                 int product)
{
D
Daniel P. Berrange 已提交
1897
    int ret;
1898
    VIR_DEBUG("mon=%p vendor=%d product=%d",
1899 1900 1901 1902 1903 1904 1905
          mon, vendor, product);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1906

D
Daniel P. Berrange 已提交
1907 1908 1909 1910 1911
    if (mon->json)
        ret = qemuMonitorJSONAddUSBDeviceMatch(mon, vendor, product);
    else
        ret = qemuMonitorTextAddUSBDeviceMatch(mon, vendor, product);
    return ret;
1912 1913 1914 1915
}


int qemuMonitorAddPCIHostDevice(qemuMonitorPtr mon,
1916 1917
                                virDomainDevicePCIAddress *hostAddr,
                                virDomainDevicePCIAddress *guestAddr)
1918
{
D
Daniel P. Berrange 已提交
1919
    int ret;
1920
    VIR_DEBUG("mon=%p domain=%d bus=%d slot=%d function=%d",
1921
          mon,
1922
          hostAddr->domain, hostAddr->bus, hostAddr->slot, hostAddr->function);
1923

1924 1925 1926 1927 1928 1929
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

D
Daniel P. Berrange 已提交
1930
    if (mon->json)
1931
        ret = qemuMonitorJSONAddPCIHostDevice(mon, hostAddr, guestAddr);
D
Daniel P. Berrange 已提交
1932
    else
1933
        ret = qemuMonitorTextAddPCIHostDevice(mon, hostAddr, guestAddr);
D
Daniel P. Berrange 已提交
1934
    return ret;
1935 1936 1937 1938 1939 1940
}


int qemuMonitorAddPCIDisk(qemuMonitorPtr mon,
                          const char *path,
                          const char *bus,
1941
                          virDomainDevicePCIAddress *guestAddr)
1942
{
D
Daniel P. Berrange 已提交
1943
    int ret;
1944
    VIR_DEBUG("mon=%p path=%s bus=%s",
1945 1946 1947 1948 1949 1950 1951
          mon, path, bus);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1952

D
Daniel P. Berrange 已提交
1953
    if (mon->json)
1954
        ret = qemuMonitorJSONAddPCIDisk(mon, path, bus, guestAddr);
D
Daniel P. Berrange 已提交
1955
    else
1956
        ret = qemuMonitorTextAddPCIDisk(mon, path, bus, guestAddr);
D
Daniel P. Berrange 已提交
1957
    return ret;
1958 1959 1960 1961 1962
}


int qemuMonitorAddPCINetwork(qemuMonitorPtr mon,
                             const char *nicstr,
1963
                             virDomainDevicePCIAddress *guestAddr)
1964
{
D
Daniel P. Berrange 已提交
1965
    int ret;
1966
    VIR_DEBUG("mon=%p nicstr=%s", mon, nicstr);
1967 1968 1969 1970 1971 1972

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
1973

D
Daniel P. Berrange 已提交
1974
    if (mon->json)
1975
        ret = qemuMonitorJSONAddPCINetwork(mon, nicstr, guestAddr);
D
Daniel P. Berrange 已提交
1976
    else
1977
        ret = qemuMonitorTextAddPCINetwork(mon, nicstr, guestAddr);
D
Daniel P. Berrange 已提交
1978
    return ret;
1979 1980 1981 1982
}


int qemuMonitorRemovePCIDevice(qemuMonitorPtr mon,
1983
                               virDomainDevicePCIAddress *guestAddr)
1984
{
D
Daniel P. Berrange 已提交
1985
    int ret;
1986
    VIR_DEBUG("mon=%p domain=%d bus=%d slot=%d function=%d",
1987
          mon, guestAddr->domain, guestAddr->bus,
1988
          guestAddr->slot, guestAddr->function);
1989

1990 1991 1992 1993 1994 1995
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

D
Daniel P. Berrange 已提交
1996
    if (mon->json)
1997
        ret = qemuMonitorJSONRemovePCIDevice(mon, guestAddr);
D
Daniel P. Berrange 已提交
1998
    else
1999
        ret = qemuMonitorTextRemovePCIDevice(mon, guestAddr);
D
Daniel P. Berrange 已提交
2000
    return ret;
2001 2002 2003 2004 2005 2006 2007
}


int qemuMonitorSendFileHandle(qemuMonitorPtr mon,
                              const char *fdname,
                              int fd)
{
D
Daniel P. Berrange 已提交
2008
    int ret;
2009
    VIR_DEBUG("mon=%p, fdname=%s fd=%d",
2010 2011 2012 2013 2014 2015 2016
          mon, fdname, fd);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
2017

2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030
    if (fd < 0) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("fd must be valid"));
        return -1;
    }

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

D
Daniel P. Berrange 已提交
2031 2032 2033 2034 2035
    if (mon->json)
        ret = qemuMonitorJSONSendFileHandle(mon, fdname, fd);
    else
        ret = qemuMonitorTextSendFileHandle(mon, fdname, fd);
    return ret;
2036 2037 2038 2039 2040 2041
}


int qemuMonitorCloseFileHandle(qemuMonitorPtr mon,
                               const char *fdname)
{
2042 2043 2044
    int ret = -1;
    virErrorPtr error;

2045
    VIR_DEBUG("mon=%p fdname=%s",
2046 2047
          mon, fdname);

2048 2049
    error = virSaveLastError();

2050 2051 2052
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
2053
        goto cleanup;
2054
    }
2055

D
Daniel P. Berrange 已提交
2056 2057 2058 2059
    if (mon->json)
        ret = qemuMonitorJSONCloseFileHandle(mon, fdname);
    else
        ret = qemuMonitorTextCloseFileHandle(mon, fdname);
2060 2061 2062 2063 2064 2065

cleanup:
    if (error) {
        virSetError(error);
        virFreeError(error);
    }
D
Daniel P. Berrange 已提交
2066
    return ret;
2067 2068 2069 2070
}


int qemuMonitorAddHostNetwork(qemuMonitorPtr mon,
2071 2072 2073
                              const char *netstr,
                              int tapfd, const char *tapfd_name,
                              int vhostfd, const char *vhostfd_name)
2074
{
2075 2076 2077 2078 2079
    int ret = -1;
    VIR_DEBUG("mon=%p netstr=%s tapfd=%d tapfd_name=%s "
              "vhostfd=%d vhostfd_name=%s",
              mon, netstr, tapfd, NULLSTR(tapfd_name),
              vhostfd, NULLSTR(vhostfd_name));
2080 2081 2082 2083 2084 2085

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
2086

2087 2088 2089 2090 2091 2092 2093 2094
    if (tapfd >= 0 && qemuMonitorSendFileHandle(mon, tapfd_name, tapfd) < 0)
        return -1;
    if (vhostfd >= 0 &&
        qemuMonitorSendFileHandle(mon, vhostfd_name, vhostfd) < 0) {
        vhostfd = -1;
        goto cleanup;
    }

D
Daniel P. Berrange 已提交
2095 2096 2097 2098
    if (mon->json)
        ret = qemuMonitorJSONAddHostNetwork(mon, netstr);
    else
        ret = qemuMonitorTextAddHostNetwork(mon, netstr);
2099 2100 2101 2102 2103 2104 2105 2106 2107

cleanup:
    if (ret < 0) {
        if (tapfd >= 0 && qemuMonitorCloseFileHandle(mon, tapfd_name) < 0)
            VIR_WARN("failed to close device handle '%s'", tapfd_name);
        if (vhostfd >= 0 && qemuMonitorCloseFileHandle(mon, vhostfd_name) < 0)
            VIR_WARN("failed to close device handle '%s'", vhostfd_name);
    }

D
Daniel P. Berrange 已提交
2108
    return ret;
2109 2110 2111 2112 2113 2114 2115
}


int qemuMonitorRemoveHostNetwork(qemuMonitorPtr mon,
                                 int vlan,
                                 const char *netname)
{
D
Daniel P. Berrange 已提交
2116
    int ret;
2117
    VIR_DEBUG("mon=%p netname=%s",
2118 2119 2120 2121 2122 2123 2124
          mon, netname);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
2125

D
Daniel P. Berrange 已提交
2126 2127 2128 2129 2130
    if (mon->json)
        ret = qemuMonitorJSONRemoveHostNetwork(mon, vlan, netname);
    else
        ret = qemuMonitorTextRemoveHostNetwork(mon, vlan, netname);
    return ret;
2131
}
2132

2133 2134

int qemuMonitorAddNetdev(qemuMonitorPtr mon,
2135 2136 2137
                         const char *netdevstr,
                         int tapfd, const char *tapfd_name,
                         int vhostfd, const char *vhostfd_name)
2138
{
2139 2140 2141 2142 2143
    int ret = -1;
    VIR_DEBUG("mon=%p netdevstr=%s tapfd=%d tapfd_name=%s "
              "vhostfd=%d vhostfd_name=%s",
              mon, netdevstr, tapfd, NULLSTR(tapfd_name),
              vhostfd, NULLSTR(vhostfd_name));
2144 2145 2146 2147 2148 2149

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
2150

2151 2152 2153 2154 2155 2156 2157 2158
    if (tapfd >= 0 && qemuMonitorSendFileHandle(mon, tapfd_name, tapfd) < 0)
        return -1;
    if (vhostfd >= 0 &&
        qemuMonitorSendFileHandle(mon, vhostfd_name, vhostfd) < 0) {
        vhostfd = -1;
        goto cleanup;
    }

2159 2160 2161 2162
    if (mon->json)
        ret = qemuMonitorJSONAddNetdev(mon, netdevstr);
    else
        ret = qemuMonitorTextAddNetdev(mon, netdevstr);
2163 2164 2165 2166 2167 2168 2169 2170 2171

cleanup:
    if (ret < 0) {
        if (tapfd >= 0 && qemuMonitorCloseFileHandle(mon, tapfd_name) < 0)
            VIR_WARN("failed to close device handle '%s'", tapfd_name);
        if (vhostfd >= 0 && qemuMonitorCloseFileHandle(mon, vhostfd_name) < 0)
            VIR_WARN("failed to close device handle '%s'", vhostfd_name);
    }

2172 2173 2174 2175 2176 2177 2178
    return ret;
}

int qemuMonitorRemoveNetdev(qemuMonitorPtr mon,
                            const char *alias)
{
    int ret;
2179
    VIR_DEBUG("mon=%p alias=%s",
2180 2181 2182 2183 2184 2185 2186
          mon, alias);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
2187 2188 2189 2190 2191 2192 2193 2194 2195

    if (mon->json)
        ret = qemuMonitorJSONRemoveNetdev(mon, alias);
    else
        ret = qemuMonitorTextRemoveNetdev(mon, alias);
    return ret;
}


2196 2197 2198
int qemuMonitorGetPtyPaths(qemuMonitorPtr mon,
                           virHashTablePtr paths)
{
2199
    int ret;
2200
    VIR_DEBUG("mon=%p",
2201 2202 2203 2204 2205 2206 2207
          mon);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }
2208

2209 2210 2211 2212 2213
    if (mon->json)
        ret = qemuMonitorJSONGetPtyPaths(mon, paths);
    else
        ret = qemuMonitorTextGetPtyPaths(mon, paths);
    return ret;
2214
}
2215 2216 2217 2218 2219 2220


int qemuMonitorAttachPCIDiskController(qemuMonitorPtr mon,
                                       const char *bus,
                                       virDomainDevicePCIAddress *guestAddr)
{
2221
    VIR_DEBUG("mon=%p type=%s", mon, bus);
2222 2223
    int ret;

2224 2225 2226 2227 2228 2229
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

2230 2231 2232 2233 2234 2235 2236
    if (mon->json)
        ret = qemuMonitorJSONAttachPCIDiskController(mon, bus, guestAddr);
    else
        ret = qemuMonitorTextAttachPCIDiskController(mon, bus, guestAddr);

    return ret;
}
2237 2238 2239 2240 2241 2242 2243


int qemuMonitorAttachDrive(qemuMonitorPtr mon,
                           const char *drivestr,
                           virDomainDevicePCIAddress *controllerAddr,
                           virDomainDeviceDriveAddress *driveAddr)
{
2244
    VIR_DEBUG("mon=%p drivestr=%s domain=%d bus=%d slot=%d function=%d",
2245
          mon, drivestr,
2246 2247 2248 2249
          controllerAddr->domain, controllerAddr->bus,
          controllerAddr->slot, controllerAddr->function);
    int ret;

2250 2251 2252 2253 2254 2255
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

2256 2257 2258 2259 2260 2261 2262
    if (mon->json)
        ret = qemuMonitorJSONAttachDrive(mon, drivestr, controllerAddr, driveAddr);
    else
        ret = qemuMonitorTextAttachDrive(mon, drivestr, controllerAddr, driveAddr);

    return ret;
}
2263 2264 2265 2266

int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon,
                                  qemuMonitorPCIAddress **addrs)
{
2267
    VIR_DEBUG("mon=%p addrs=%p", mon, addrs);
2268 2269
    int ret;

2270 2271 2272 2273 2274 2275
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

2276 2277 2278 2279 2280 2281
    if (mon->json)
        ret = qemuMonitorJSONGetAllPCIAddresses(mon, addrs);
    else
        ret = qemuMonitorTextGetAllPCIAddresses(mon, addrs);
    return ret;
}
2282

2283 2284
int qemuMonitorDriveDel(qemuMonitorPtr mon,
                        const char *drivestr)
2285
{
2286
    VIR_DEBUG("mon=%p drivestr=%s", mon, drivestr);
2287 2288 2289 2290 2291 2292 2293 2294 2295
    int ret;

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

    if (mon->json)
2296
        ret = qemuMonitorJSONDriveDel(mon, drivestr);
2297
    else
2298
        ret = qemuMonitorTextDriveDel(mon, drivestr);
2299 2300 2301
    return ret;
}

2302
int qemuMonitorDelDevice(qemuMonitorPtr mon,
2303
                         const char *devalias)
2304
{
2305
    VIR_DEBUG("mon=%p devalias=%s", mon, devalias);
2306 2307
    int ret;

2308 2309 2310 2311 2312 2313
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

2314
    if (mon->json)
2315
        ret = qemuMonitorJSONDelDevice(mon, devalias);
2316
    else
2317
        ret = qemuMonitorTextDelDevice(mon, devalias);
2318 2319 2320
    return ret;
}

2321

2322 2323 2324 2325
int qemuMonitorAddDeviceWithFd(qemuMonitorPtr mon,
                               const char *devicestr,
                               int fd,
                               const char *fdname)
2326
{
2327 2328
    VIR_DEBUG("mon=%p device=%s fd=%d fdname=%s", mon, devicestr, fd,
              NULLSTR(fdname));
2329 2330
    int ret;

2331 2332 2333 2334 2335 2336
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

2337 2338 2339
    if (fd >= 0 && qemuMonitorSendFileHandle(mon, fdname, fd) < 0)
        return -1;

2340 2341 2342 2343
    if (mon->json)
        ret = qemuMonitorJSONAddDevice(mon, devicestr);
    else
        ret = qemuMonitorTextAddDevice(mon, devicestr);
2344 2345 2346 2347 2348 2349

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

2350 2351 2352
    return ret;
}

2353 2354 2355 2356 2357 2358
int qemuMonitorAddDevice(qemuMonitorPtr mon,
                         const char *devicestr)
{
    return qemuMonitorAddDeviceWithFd(mon, devicestr, -1, NULL);
}

2359 2360 2361
int qemuMonitorAddDrive(qemuMonitorPtr mon,
                        const char *drivestr)
{
2362
    VIR_DEBUG("mon=%p drive=%s", mon, drivestr);
2363 2364
    int ret;

2365 2366 2367 2368 2369 2370
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

2371 2372 2373 2374 2375 2376
    if (mon->json)
        ret = qemuMonitorJSONAddDrive(mon, drivestr);
    else
        ret = qemuMonitorTextAddDrive(mon, drivestr);
    return ret;
}
2377 2378 2379 2380 2381 2382


int qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon,
                                  const char *alias,
                                  const char *passphrase)
{
2383
    VIR_DEBUG("mon=%p alias=%s passphrase=%p(value hidden)", mon, alias, passphrase);
2384 2385
    int ret;

2386 2387 2388 2389 2390 2391
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

2392 2393 2394 2395 2396 2397
    if (mon->json)
        ret = qemuMonitorJSONSetDrivePassphrase(mon, alias, passphrase);
    else
        ret = qemuMonitorTextSetDrivePassphrase(mon, alias, passphrase);
    return ret;
}
C
Chris Lalancette 已提交
2398 2399 2400 2401 2402

int qemuMonitorCreateSnapshot(qemuMonitorPtr mon, const char *name)
{
    int ret;

2403
    VIR_DEBUG("mon=%p, name=%s",mon,name);
C
Chris Lalancette 已提交
2404

2405 2406 2407 2408 2409 2410
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

C
Chris Lalancette 已提交
2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421
    if (mon->json)
        ret = qemuMonitorJSONCreateSnapshot(mon, name);
    else
        ret = qemuMonitorTextCreateSnapshot(mon, name);
    return ret;
}

int qemuMonitorLoadSnapshot(qemuMonitorPtr mon, const char *name)
{
    int ret;

2422
    VIR_DEBUG("mon=%p, name=%s",mon,name);
C
Chris Lalancette 已提交
2423

2424 2425 2426 2427 2428 2429
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

C
Chris Lalancette 已提交
2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440
    if (mon->json)
        ret = qemuMonitorJSONLoadSnapshot(mon, name);
    else
        ret = qemuMonitorTextLoadSnapshot(mon, name);
    return ret;
}

int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name)
{
    int ret;

2441
    VIR_DEBUG("mon=%p, name=%s",mon,name);
C
Chris Lalancette 已提交
2442

2443 2444 2445 2446 2447 2448
    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

C
Chris Lalancette 已提交
2449 2450 2451 2452 2453 2454
    if (mon->json)
        ret = qemuMonitorJSONDeleteSnapshot(mon, name);
    else
        ret = qemuMonitorTextDeleteSnapshot(mon, name);
    return ret;
}
2455

2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479
/* 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
qemuMonitorDiskSnapshot(qemuMonitorPtr mon, const char *device,
                        const char *file)
{
    int ret;

    VIR_DEBUG("mon=%p, device=%s, file=%s", mon, device, file);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
                        _("monitor must not be NULL"));
        return -1;
    }

    if (mon->json)
        ret = qemuMonitorJSONDiskSnapshot(mon, device, file);
    else
        ret = qemuMonitorTextDiskSnapshot(mon, device, file);
    return ret;
}

2480 2481 2482 2483
int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
                                const char *cmd,
                                char **reply,
                                bool hmp)
2484 2485 2486
{
    int ret;

2487
    VIR_DEBUG("mon=%p, cmd=%s, reply=%p, hmp=%d", mon, cmd, reply, hmp);
2488 2489

    if (mon->json)
2490
        ret = qemuMonitorJSONArbitraryCommand(mon, cmd, reply, hmp);
2491 2492 2493 2494
    else
        ret = qemuMonitorTextArbitraryCommand(mon, cmd, reply);
    return ret;
}
2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508


int qemuMonitorInjectNMI(qemuMonitorPtr mon)
{
    int ret;

    VIR_DEBUG("mon=%p", mon);

    if (mon->json)
        ret = qemuMonitorJSONInjectNMI(mon);
    else
        ret = qemuMonitorTextInjectNMI(mon);
    return ret;
}
2509

2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526
int qemuMonitorSendKey(qemuMonitorPtr mon,
                       unsigned int holdtime,
                       unsigned int *keycodes,
                       unsigned int nkeycodes)
{
    int ret;

    VIR_DEBUG("mon=%p, holdtime=%u, nkeycodes=%u",
              mon, holdtime, nkeycodes);

    if (mon->json)
        ret = qemuMonitorJSONSendKey(mon, holdtime, keycodes, nkeycodes);
    else
        ret = qemuMonitorTextSendKey(mon, holdtime, keycodes, nkeycodes);
    return ret;
}

2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545
int qemuMonitorScreendump(qemuMonitorPtr mon,
                          const char *file)
{
    int ret;

    VIR_DEBUG("mon=%p, file=%s", mon, file);

    if (!mon) {
        qemuReportError(VIR_ERR_INVALID_ARG,"%s",
                        _("monitor must not be NULL"));
        return -1;
    }

    if (mon->json)
        ret = qemuMonitorJSONScreendump(mon, file);
    else
        ret = qemuMonitorTextScreendump(mon, file);
    return ret;
}
2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563

int qemuMonitorBlockJob(qemuMonitorPtr mon,
                        const char *device,
                        unsigned long bandwidth,
                        virDomainBlockJobInfoPtr info,
                        int mode)
{
    int ret;

    VIR_DEBUG("mon=%p, device=%p, bandwidth=%lu, info=%p, mode=%o",
              mon, device, bandwidth, info, mode);

    if (mon->json)
        ret = qemuMonitorJSONBlockJob(mon, device, bandwidth, info, mode);
    else
        ret = qemuMonitorTextBlockJob(mon, device, bandwidth, info, mode);
    return ret;
}
2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613

int qemuMonitorVMStatusToPausedReason(const char *status)
{
    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;

    /* unreachable from this point on */
    case QEMU_MONITOR_VM_STATUS_LAST:
        ;
    }
    return VIR_DOMAIN_PAUSED_UNKNOWN;
}