Fix QEMU memory stats JSON mode
[libvirt.git] / src / qemu / qemu_monitor_json.c
1 /*
2  * qemu_monitor_json.c: interaction with QEMU monitor console
3  *
4  * Copyright (C) 2006-2010 Red Hat, Inc.
5  * Copyright (C) 2006 Daniel P. Berrange
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
20  *
21  * Author: Daniel P. Berrange <berrange@redhat.com>
22  */
23
24 #include <config.h>
25
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <sys/un.h>
29 #include <poll.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <sys/time.h>
33
34 #include "qemu_monitor_json.h"
35 #include "qemu_conf.h"
36 #include "memory.h"
37 #include "logging.h"
38 #include "driver.h"
39 #include "datatypes.h"
40 #include "virterror_internal.h"
41 #include "json.h"
42
43 #define VIR_FROM_THIS VIR_FROM_QEMU
44
45
46 #define LINE_ENDING "\r\n"
47
48 static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data);
49 static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data);
50 static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data);
51 static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr data);
52 static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data);
53 static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValuePtr data);
54 static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data);
55 static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data);
56 static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data);
57 static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data);
58
59 struct {
60     const char *type;
61     void (*handler)(qemuMonitorPtr mon, virJSONValuePtr data);
62 } eventHandlers[] = {
63     { "SHUTDOWN", qemuMonitorJSONHandleShutdown, },
64     { "RESET", qemuMonitorJSONHandleReset, },
65     { "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
66     { "STOP", qemuMonitorJSONHandleStop, },
67     { "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
68     { "WATCHDOG", qemuMonitorJSONHandleWatchdog, },
69     { "BLOCK_IO_ERROR", qemuMonitorJSONHandleIOError, },
70     { "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
71     { "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
72     { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
73 };
74
75
76 static int
77 qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
78                               virJSONValuePtr obj)
79 {
80     const char *type;
81     int i;
82     VIR_DEBUG("mon=%p obj=%p", mon, obj);
83
84     type = virJSONValueObjectGetString(obj, "event");
85     if (!type) {
86         VIR_WARN0("missing event type in message");
87         errno = EINVAL;
88         return -1;
89     }
90
91     for (i = 0 ; i < ARRAY_CARDINALITY(eventHandlers) ; i++) {
92         if (STREQ(eventHandlers[i].type, type)) {
93             virJSONValuePtr data = virJSONValueObjectGet(obj, "data");
94             VIR_DEBUG("handle %s handler=%p data=%p", type,
95                       eventHandlers[i].handler, data);
96             (eventHandlers[i].handler)(mon, data);
97             break;
98         }
99     }
100     return 0;
101 }
102
103 static int
104 qemuMonitorJSONIOProcessLine(qemuMonitorPtr mon,
105                              const char *line,
106                              qemuMonitorMessagePtr msg)
107 {
108     virJSONValuePtr obj = NULL;
109     int ret = -1;
110
111     VIR_DEBUG("Line [%s]", line);
112
113     if (!(obj = virJSONValueFromString(line))) {
114         VIR_DEBUG0("Parsing JSON string failed");
115         errno = EINVAL;
116         goto cleanup;
117     }
118
119     if (obj->type != VIR_JSON_TYPE_OBJECT) {
120         VIR_DEBUG0("Parsed JSON string isn't an object");
121         errno = EINVAL;
122     }
123
124     if (virJSONValueObjectHasKey(obj, "QMP") == 1) {
125         VIR_DEBUG0("Got QMP capabilities data");
126         ret = 0;
127         goto cleanup;
128     }
129
130     if (virJSONValueObjectHasKey(obj, "event") == 1) {
131         ret = qemuMonitorJSONIOProcessEvent(mon, obj);
132         goto cleanup;
133     }
134
135     if (msg) {
136         if (!(msg->rxBuffer = strdup(line))) {
137             errno = ENOMEM;
138             goto cleanup;
139         }
140         msg->rxLength = strlen(line);
141         msg->finished = 1;
142     } else {
143         VIR_DEBUG("Ignoring unexpected JSON message [%s]", line);
144     }
145
146     ret = 0;
147
148 cleanup:
149     virJSONValueFree(obj);
150     return ret;
151 }
152
153 int qemuMonitorJSONIOProcess(qemuMonitorPtr mon,
154                              const char *data,
155                              size_t len,
156                              qemuMonitorMessagePtr msg)
157 {
158     int used = 0;
159     /*VIR_DEBUG("Data %d bytes [%s]", len, data);*/
160
161     while (used < len) {
162         char *nl = strstr(data + used, LINE_ENDING);
163
164         if (nl) {
165             int got = nl - (data + used);
166             char *line = strndup(data + used, got);
167             if (!line) {
168                 errno = ENOMEM;
169                 return -1;
170             }
171             used += got + strlen(LINE_ENDING);
172             line[got] = '\0'; /* kill \n */
173             if (qemuMonitorJSONIOProcessLine(mon, line, msg) < 0) {
174                 VIR_FREE(line);
175                 return -1;
176             }
177
178             VIR_FREE(line);
179         } else {
180             break;
181         }
182     }
183
184     VIR_DEBUG("Total used %d bytes out of %zd available in buffer", used, len);
185     return used;
186 }
187
188 static int
189 qemuMonitorJSONCommandWithFd(qemuMonitorPtr mon,
190                              virJSONValuePtr cmd,
191                              int scm_fd,
192                              virJSONValuePtr *reply)
193 {
194     int ret = -1;
195     qemuMonitorMessage msg;
196     char *cmdstr = NULL;
197
198     *reply = NULL;
199
200     memset(&msg, 0, sizeof msg);
201
202     if (!(cmdstr = virJSONValueToString(cmd))) {
203         virReportOOMError();
204         goto cleanup;
205     }
206     if (virAsprintf(&msg.txBuffer, "%s\r\n", cmdstr) < 0) {
207         virReportOOMError();
208         goto cleanup;
209     }
210     msg.txLength = strlen(msg.txBuffer);
211     msg.txFD = scm_fd;
212
213     VIR_DEBUG("Send command '%s' for write with FD %d", cmdstr, scm_fd);
214
215     ret = qemuMonitorSend(mon, &msg);
216
217     VIR_DEBUG("Receive command reply ret=%d errno=%d %d bytes '%s'",
218               ret, msg.lastErrno, msg.rxLength, msg.rxBuffer);
219
220
221     /* If we got ret==0, but not reply data something rather bad
222      * went wrong, so lets fake an EIO error */
223     if (!msg.rxBuffer && ret == 0) {
224         msg.lastErrno = EIO;
225         ret = -1;
226     }
227
228     if (ret == 0) {
229         if (!((*reply) = virJSONValueFromString(msg.rxBuffer))) {
230             qemuReportError(VIR_ERR_INTERNAL_ERROR,
231                             _("cannot parse JSON doc '%s'"), msg.rxBuffer);
232             goto cleanup;
233         }
234     }
235
236     if (ret < 0)
237         virReportSystemError(msg.lastErrno,
238                              _("cannot send monitor command '%s'"), cmdstr);
239
240 cleanup:
241     VIR_FREE(cmdstr);
242     VIR_FREE(msg.txBuffer);
243     VIR_FREE(msg.rxBuffer);
244
245     return ret;
246 }
247
248
249 static int
250 qemuMonitorJSONCommand(qemuMonitorPtr mon,
251                        virJSONValuePtr cmd,
252                        virJSONValuePtr *reply) {
253     return qemuMonitorJSONCommandWithFd(mon, cmd, -1, reply);
254 }
255
256 /* Ignoring OOM in this method, since we're already reporting
257  * a more important error
258  *
259  * XXX see qerror.h for different klasses & fill out useful params
260  */
261 static const char *
262 qemuMonitorJSONStringifyError(virJSONValuePtr error)
263 {
264     const char *klass = virJSONValueObjectGetString(error, "class");
265     const char *detail = NULL;
266
267     /* The QMP 'desc' field is usually sufficient for our generic
268      * error reporting needs.
269      */
270     if (klass)
271         detail = virJSONValueObjectGetString(error, "desc");
272
273
274     if (!detail)
275         detail = "unknown QEMU command error";
276
277     return detail;
278 }
279
280 static const char *
281 qemuMonitorJSONCommandName(virJSONValuePtr cmd)
282 {
283     const char *name = virJSONValueObjectGetString(cmd, "execute");
284     if (name)
285         return name;
286     else
287         return "<unknown>";
288 }
289
290 static int
291 qemuMonitorJSONCheckError(virJSONValuePtr cmd,
292                           virJSONValuePtr reply)
293 {
294     if (virJSONValueObjectHasKey(reply, "error")) {
295         virJSONValuePtr error = virJSONValueObjectGet(reply, "error");
296         char *cmdstr = virJSONValueToString(cmd);
297         char *replystr = virJSONValueToString(reply);
298
299         /* Log the full JSON formatted command & error */
300         VIR_DEBUG("unable to execute QEMU command %s: %s",
301                   cmdstr, replystr);
302
303         /* Only send the user the command name + friendly error */
304         if (!error)
305             qemuReportError(VIR_ERR_INTERNAL_ERROR,
306                             _("unable to execute QEMU command '%s'"),
307                             qemuMonitorJSONCommandName(cmd));
308         else
309             qemuReportError(VIR_ERR_INTERNAL_ERROR,
310                             _("unable to execute QEMU command '%s': %s"),
311                             qemuMonitorJSONCommandName(cmd),
312                             qemuMonitorJSONStringifyError(error));
313
314         VIR_FREE(cmdstr);
315         VIR_FREE(replystr);
316         return -1;
317     } else if (!virJSONValueObjectHasKey(reply, "return")) {
318         char *cmdstr = virJSONValueToString(cmd);
319         char *replystr = virJSONValueToString(reply);
320
321         VIR_DEBUG("Neither 'return' nor 'error' is set in the JSON reply %s: %s",
322                   cmdstr, replystr);
323         qemuReportError(VIR_ERR_INTERNAL_ERROR,
324                         _("unable to execute QEMU command '%s'"),
325                         qemuMonitorJSONCommandName(cmd));
326         VIR_FREE(cmdstr);
327         VIR_FREE(replystr);
328         return -1;
329     }
330     return 0;
331 }
332
333
334 static int
335 qemuMonitorJSONHasError(virJSONValuePtr reply,
336                         const char *klass)
337 {
338     virJSONValuePtr error;
339     const char *thisklass;
340
341     if (!virJSONValueObjectHasKey(reply, "error"))
342         return 0;
343
344     error = virJSONValueObjectGet(reply, "error");
345     if (!error)
346         return 0;
347
348     if (!virJSONValueObjectHasKey(error, "class"))
349         return 0;
350
351     thisklass = virJSONValueObjectGetString(error, "class");
352
353     if (!thisklass)
354         return 0;
355
356     return STREQ(klass, thisklass);
357 }
358
359 static int
360 qemuMonitorJSONCommandAddTimestamp(virJSONValuePtr obj)
361 {
362     struct timeval tv;
363     virJSONValuePtr timestamp = NULL;
364
365     if (gettimeofday(&tv, NULL) < 0) {
366         virReportSystemError(errno, "%s",
367                              _("cannot query time of day"));
368         return -1;
369     }
370
371     if (!(timestamp = virJSONValueNewObject()))
372         goto no_memory;
373
374     if (virJSONValueObjectAppendNumberLong(timestamp, "seconds", tv.tv_sec) < 0)
375         goto no_memory;
376     if (virJSONValueObjectAppendNumberLong(timestamp, "microseconds", tv.tv_usec) < 0)
377         goto no_memory;
378
379     if (virJSONValueObjectAppend(obj, "timestamp", timestamp) < 0)
380         goto no_memory;
381
382     return 0;
383
384 no_memory:
385     virReportOOMError();
386     virJSONValueFree(timestamp);
387     return -1;
388 }
389
390 static virJSONValuePtr ATTRIBUTE_SENTINEL
391 qemuMonitorJSONMakeCommand(const char *cmdname,
392                            ...)
393 {
394     virJSONValuePtr obj;
395     virJSONValuePtr jargs = NULL;
396     va_list args;
397     char *key;
398
399     va_start(args, cmdname);
400
401     if (!(obj = virJSONValueNewObject()))
402         goto no_memory;
403
404     if (virJSONValueObjectAppendString(obj, "execute", cmdname) < 0)
405         goto no_memory;
406
407     if (qemuMonitorJSONCommandAddTimestamp(obj) < 0)
408         goto error;
409
410     while ((key = va_arg(args, char *)) != NULL) {
411         int ret;
412         char type;
413
414         if (strlen(key) < 3) {
415             qemuReportError(VIR_ERR_INTERNAL_ERROR,
416                             _("argument key '%s' is too short, missing type prefix"),
417                             key);
418             goto error;
419         }
420
421         /* Keys look like   s:name  the first letter is a type code */
422         type = key[0];
423         key += 2;
424
425         if (!jargs &&
426             !(jargs = virJSONValueNewObject()))
427             goto no_memory;
428
429         /* This doesn't supports maps/arrays.  This hasn't
430          * proved to be a problem..... yet :-)  */
431         switch (type) {
432         case 's': {
433             char *val = va_arg(args, char *);
434             ret = virJSONValueObjectAppendString(jargs, key, val);
435         }   break;
436         case 'i': {
437             int val = va_arg(args, int);
438             ret = virJSONValueObjectAppendNumberInt(jargs, key, val);
439         }   break;
440         case 'u': {
441             unsigned int val = va_arg(args, unsigned int);
442             ret = virJSONValueObjectAppendNumberUint(jargs, key, val);
443         }   break;
444         case 'I': {
445             long long val = va_arg(args, long long);
446             ret = virJSONValueObjectAppendNumberLong(jargs, key, val);
447         }   break;
448         case 'U': {
449             unsigned long long val = va_arg(args, unsigned long long);
450             ret = virJSONValueObjectAppendNumberUlong(jargs, key, val);
451         }   break;
452         case 'd': {
453             double val = va_arg(args, double);
454             ret = virJSONValueObjectAppendNumberDouble(jargs, key, val);
455         }   break;
456         case 'b': {
457             int val = va_arg(args, int);
458             ret = virJSONValueObjectAppendBoolean(jargs, key, val);
459         }   break;
460         case 'n': {
461             ret = virJSONValueObjectAppendNull(jargs, key);
462         }   break;
463         default:
464             qemuReportError(VIR_ERR_INTERNAL_ERROR,
465                             _("unsupported data type '%c' for arg '%s'"), type, key - 2);
466             goto error;
467         }
468         if (ret < 0)
469             goto no_memory;
470     }
471
472     if (jargs &&
473         virJSONValueObjectAppend(obj, "arguments", jargs) < 0)
474         goto no_memory;
475
476     va_end(args);
477
478     return obj;
479
480 no_memory:
481     virReportOOMError();
482 error:
483     virJSONValueFree(obj);
484     virJSONValueFree(jargs);
485     va_end(args);
486     return NULL;
487 }
488
489
490 static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
491 {
492     qemuMonitorEmitShutdown(mon);
493 }
494
495 static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
496 {
497     qemuMonitorEmitReset(mon);
498 }
499
500 static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
501 {
502     qemuMonitorEmitPowerdown(mon);
503 }
504
505 static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
506 {
507     qemuMonitorEmitStop(mon);
508 }
509
510 static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data)
511 {
512     long long offset = 0;
513     if (virJSONValueObjectGetNumberLong(data, "offset", &offset) < 0) {
514         VIR_WARN0("missing offset in RTC change event");
515         offset = 0;
516     }
517     qemuMonitorEmitRTCChange(mon, offset);
518 }
519
520 VIR_ENUM_DECL(qemuMonitorWatchdogAction)
521 VIR_ENUM_IMPL(qemuMonitorWatchdogAction, VIR_DOMAIN_EVENT_WATCHDOG_DEBUG + 1,
522               "none", "pause", "reset", "poweroff", "shutdown", "debug");
523
524 static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValuePtr data)
525 {
526     const char *action;
527     int actionID;
528     if (!(action = virJSONValueObjectGetString(data, "action"))) {
529         VIR_WARN0("missing action in watchdog event");
530     }
531     if (action) {
532         if ((actionID = qemuMonitorWatchdogActionTypeFromString(action)) < 0) {
533             VIR_WARN("unknown action %s in watchdog event", action);
534             actionID = VIR_DOMAIN_EVENT_WATCHDOG_NONE;
535         }
536     } else {
537             actionID = VIR_DOMAIN_EVENT_WATCHDOG_NONE;
538     }
539     qemuMonitorEmitWatchdog(mon, actionID);
540 }
541
542 VIR_ENUM_DECL(qemuMonitorIOErrorAction)
543 VIR_ENUM_IMPL(qemuMonitorIOErrorAction, VIR_DOMAIN_EVENT_IO_ERROR_REPORT + 1,
544               "ignore", "stop", "report");
545
546
547 static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data)
548 {
549     const char *device;
550     const char *action;
551     int actionID;
552
553     /* Throughout here we try our best to carry on upon errors,
554        since it's imporatant to get as much info as possible out
555        to the application */
556
557     if ((action = virJSONValueObjectGetString(data, "action")) == NULL) {
558         VIR_WARN0("Missing action in disk io error event");
559         action = "ignore";
560     }
561
562     if ((device = virJSONValueObjectGetString(data, "device")) == NULL) {
563         VIR_WARN0("missing device in disk io error event");
564     }
565
566     if ((actionID = qemuMonitorIOErrorActionTypeFromString(action)) < 0) {
567         VIR_WARN("unknown disk io error action '%s'", action);
568         actionID = VIR_DOMAIN_EVENT_IO_ERROR_NONE;
569     }
570
571     qemuMonitorEmitIOError(mon, device, actionID);
572 }
573
574
575 VIR_ENUM_DECL(qemuMonitorGraphicsAddressFamily)
576 VIR_ENUM_IMPL(qemuMonitorGraphicsAddressFamily, VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6 + 1,
577               "ipv4", "ipv6");
578
579 static void qemuMonitorJSONHandleVNC(qemuMonitorPtr mon, virJSONValuePtr data, int phase)
580 {
581     const char *localNode, *localService, *localFamily;
582     const char *remoteNode, *remoteService, *remoteFamily;
583     const char *authScheme, *saslUsername, *x509dname;
584     int localFamilyID, remoteFamilyID;
585     virJSONValuePtr client;
586     virJSONValuePtr server;
587
588     if (!(client = virJSONValueObjectGet(data, "client"))) {
589         VIR_WARN0("missing client info in VNC event");
590         return;
591     }
592     if (!(server = virJSONValueObjectGet(data, "server"))) {
593         VIR_WARN0("missing server info in VNC event");
594         return;
595     }
596
597     authScheme = virJSONValueObjectGetString(server, "auth");
598
599     localFamily = virJSONValueObjectGetString(server, "family");
600     localNode = virJSONValueObjectGetString(server, "host");
601     localService = virJSONValueObjectGetString(server, "service");
602
603     remoteFamily = virJSONValueObjectGetString(client, "family");
604     remoteNode = virJSONValueObjectGetString(client, "host");
605     remoteService = virJSONValueObjectGetString(client, "service");
606
607     saslUsername = virJSONValueObjectGetString(client, "sasl_username");
608     x509dname = virJSONValueObjectGetString(client, "x509_dname");
609
610     if ((localFamilyID = qemuMonitorGraphicsAddressFamilyTypeFromString(localFamily)) < 0) {
611         VIR_WARN("unknown address family '%s'", localFamily);
612         localFamilyID = VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4;
613     }
614     if ((remoteFamilyID = qemuMonitorGraphicsAddressFamilyTypeFromString(remoteFamily)) < 0) {
615         VIR_WARN("unknown address family '%s'", remoteFamily);
616         remoteFamilyID = VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4;
617     }
618
619     qemuMonitorEmitGraphics(mon, phase,
620                             localFamilyID, localNode, localService,
621                             remoteFamilyID, remoteNode, remoteService,
622                             authScheme, x509dname, saslUsername);
623 }
624
625 static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data)
626 {
627     qemuMonitorJSONHandleVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT);
628 }
629
630
631 static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data)
632 {
633     qemuMonitorJSONHandleVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE);
634 }
635
636
637 static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data)
638 {
639     qemuMonitorJSONHandleVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT);
640 }
641
642
643 int
644 qemuMonitorJSONSetCapabilities(qemuMonitorPtr mon)
645 {
646     int ret;
647     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("qmp_capabilities", NULL);
648     virJSONValuePtr reply = NULL;
649     if (!cmd)
650         return -1;
651
652     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
653
654     if (ret == 0)
655         ret = qemuMonitorJSONCheckError(cmd, reply);
656
657     virJSONValueFree(cmd);
658     virJSONValueFree(reply);
659     return ret;
660 }
661
662
663 int
664 qemuMonitorJSONStartCPUs(qemuMonitorPtr mon,
665                          virConnectPtr conn ATTRIBUTE_UNUSED)
666 {
667     int ret;
668     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("cont", NULL);
669     virJSONValuePtr reply = NULL;
670     if (!cmd)
671         return -1;
672
673     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
674
675     if (ret == 0)
676         ret = qemuMonitorJSONCheckError(cmd, reply);
677
678     virJSONValueFree(cmd);
679     virJSONValueFree(reply);
680     return ret;
681 }
682
683
684 int
685 qemuMonitorJSONStopCPUs(qemuMonitorPtr mon)
686 {
687     int ret;
688     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("stop", NULL);
689     virJSONValuePtr reply = NULL;
690     if (!cmd)
691         return -1;
692
693     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
694
695     if (ret == 0)
696         ret = qemuMonitorJSONCheckError(cmd, reply);
697
698     virJSONValueFree(cmd);
699     virJSONValueFree(reply);
700     return ret;
701 }
702
703
704 int qemuMonitorJSONSystemPowerdown(qemuMonitorPtr mon)
705 {
706     int ret;
707     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("system_powerdown", NULL);
708     virJSONValuePtr reply = NULL;
709     if (!cmd)
710         return -1;
711
712     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
713
714     if (ret == 0)
715         ret = qemuMonitorJSONCheckError(cmd, reply);
716
717     virJSONValueFree(cmd);
718     virJSONValueFree(reply);
719     return ret;
720 }
721
722
723 /*
724  * [ { "CPU": 0, "current": true, "halted": false, "pc": 3227107138 },
725  *   { "CPU": 1, "current": false, "halted": true, "pc": 7108165 } ]
726  */
727 static int
728 qemuMonitorJSONExtractCPUInfo(virJSONValuePtr reply,
729                               int **pids)
730 {
731     virJSONValuePtr data;
732     int ret = -1;
733     int i;
734     int *threads = NULL;
735     int ncpus;
736
737     if (!(data = virJSONValueObjectGet(reply, "return"))) {
738         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
739                         _("cpu reply was missing return data"));
740         goto cleanup;
741     }
742
743     if (data->type != VIR_JSON_TYPE_ARRAY) {
744         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
745                         _("cpu information was not an array"));
746         goto cleanup;
747     }
748
749     if ((ncpus = virJSONValueArraySize(data)) <= 0) {
750         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
751                         _("cpu information was empty"));
752         goto cleanup;
753     }
754
755     if (VIR_REALLOC_N(threads, ncpus) < 0) {
756         virReportOOMError();
757         goto cleanup;
758     }
759
760     for (i = 0 ; i < ncpus ; i++) {
761         virJSONValuePtr entry = virJSONValueArrayGet(data, i);
762         int cpu;
763         int thread;
764         if (!entry) {
765             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
766                             _("character device information was missing aray element"));
767             goto cleanup;
768         }
769
770         if (virJSONValueObjectGetNumberInt(entry, "CPU", &cpu) < 0) {
771             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
772                             _("cpu information was missing cpu number"));
773             goto cleanup;
774         }
775
776         if (virJSONValueObjectGetNumberInt(entry, "thread_id", &thread) < 0) {
777             /* Only qemu-kvm tree includs thread_id, so treat this as
778                non-fatal, simply returning no data */
779             ret = 0;
780             goto cleanup;
781         }
782
783         if (cpu != i) {
784             qemuReportError(VIR_ERR_INTERNAL_ERROR,
785                             _("unexpected cpu index %d expecting %d"),
786                             i, cpu);
787             goto cleanup;
788         }
789
790         threads[i] = thread;
791     }
792
793     *pids = threads;
794     threads = NULL;
795     ret = ncpus;
796
797 cleanup:
798     VIR_FREE(threads);
799     return ret;
800 }
801
802
803 int qemuMonitorJSONGetCPUInfo(qemuMonitorPtr mon,
804                               int **pids)
805 {
806     int ret;
807     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-cpus",
808                                                      NULL);
809     virJSONValuePtr reply = NULL;
810
811     *pids = NULL;
812
813     if (!cmd)
814         return -1;
815
816     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
817
818     if (ret == 0)
819         ret = qemuMonitorJSONCheckError(cmd, reply);
820
821     if (ret == 0)
822         ret = qemuMonitorJSONExtractCPUInfo(reply, pids);
823
824     virJSONValueFree(cmd);
825     virJSONValueFree(reply);
826     return ret;
827 }
828
829
830 /*
831  * Returns: 0 if balloon not supported, +1 if balloon query worked
832  * or -1 on failure
833  */
834 int qemuMonitorJSONGetBalloonInfo(qemuMonitorPtr mon,
835                                   unsigned long *currmem)
836 {
837     int ret;
838     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-balloon",
839                                                      NULL);
840     virJSONValuePtr reply = NULL;
841
842     *currmem = 0;
843
844     if (!cmd)
845         return -1;
846
847     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
848
849     if (ret == 0) {
850         /* See if balloon soft-failed */
851         if (qemuMonitorJSONHasError(reply, "DeviceNotActive") ||
852             qemuMonitorJSONHasError(reply, "KVMMissingCap"))
853             goto cleanup;
854
855         /* See if any other fatal error occurred */
856         ret = qemuMonitorJSONCheckError(cmd, reply);
857
858         /* Success */
859         if (ret == 0) {
860             virJSONValuePtr data;
861             unsigned long long mem;
862
863             if (!(data = virJSONValueObjectGet(reply, "return"))) {
864                 qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
865                                 _("info balloon reply was missing return data"));
866                 ret = -1;
867                 goto cleanup;
868             }
869
870             if (virJSONValueObjectGetNumberUlong(data, "actual", &mem) < 0) {
871                 qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
872                                 _("info balloon reply was missing balloon data"));
873                 ret = -1;
874                 goto cleanup;
875             }
876
877             *currmem = (mem/1024);
878             ret = 1;
879         }
880     }
881
882 cleanup:
883     virJSONValueFree(cmd);
884     virJSONValueFree(reply);
885     return ret;
886 }
887
888
889 int qemuMonitorJSONGetMemoryStats(qemuMonitorPtr mon,
890                                   virDomainMemoryStatPtr stats,
891                                   unsigned int nr_stats)
892 {
893     int ret;
894     int got = 0;
895     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-balloon",
896                                                      NULL);
897     virJSONValuePtr reply = NULL;
898
899     if (!cmd)
900         return -1;
901
902     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
903
904     if (ret == 0) {
905         /* See if balloon soft-failed */
906         if (qemuMonitorJSONHasError(reply, "DeviceNotActive") ||
907             qemuMonitorJSONHasError(reply, "KVMMissingCap"))
908             goto cleanup;
909
910         /* See if any other fatal error occurred */
911         ret = qemuMonitorJSONCheckError(cmd, reply);
912
913         /* Success */
914         if (ret == 0) {
915             virJSONValuePtr data;
916             unsigned long long mem;
917
918             if (!(data = virJSONValueObjectGet(reply, "return"))) {
919                 qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
920                                 _("info balloon reply was missing return data"));
921                 ret = -1;
922                 goto cleanup;
923             }
924
925             if (virJSONValueObjectHasKey(data, "mem_swapped_in") && (got < nr_stats)) {
926                 if (virJSONValueObjectGetNumberUlong(data, "mem_swapped_in", &mem) < 0) {
927                     qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
928                                     _("info balloon reply was missing balloon mem_swapped_in"));
929                     ret = -1;
930                     goto cleanup;
931                 }
932                 stats[got].tag = VIR_DOMAIN_MEMORY_STAT_SWAP_IN;
933                 stats[got].val = (mem/1024);
934                 got++;
935             }
936             if (virJSONValueObjectHasKey(data, "mem_swapped_out") && (got < nr_stats)) {
937                 if (virJSONValueObjectGetNumberUlong(data, "mem_swapped_out", &mem) < 0) {
938                     qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
939                                     _("info balloon reply was missing balloon mem_swapped_out"));
940                     ret = -1;
941                     goto cleanup;
942                 }
943                 stats[got].tag = VIR_DOMAIN_MEMORY_STAT_SWAP_OUT;
944                 stats[got].val = (mem/1024);
945                 got++;
946             }
947             if (virJSONValueObjectHasKey(data, "major_page_faults") && (got < nr_stats)) {
948                 if (virJSONValueObjectGetNumberUlong(data, "major_page_faults", &mem) < 0) {
949                     qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
950                                     _("info balloon reply was missing balloon major_page_faults"));
951                     ret = -1;
952                     goto cleanup;
953                 }
954                 stats[got].tag = VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT;
955                 stats[got].val = mem;
956                 got++;
957             }
958             if (virJSONValueObjectHasKey(data, "minor_page_faults") && (got < nr_stats)) {
959                 if (virJSONValueObjectGetNumberUlong(data, "minor_page_faults", &mem) < 0) {
960                     qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
961                                     _("info balloon reply was missing balloon minor_page_faults"));
962                     ret = -1;
963                     goto cleanup;
964                 }
965                 stats[got].tag = VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT;
966                 stats[got].val = mem;
967                 got++;
968             }
969             if (virJSONValueObjectHasKey(data, "free_mem") && (got < nr_stats)) {
970                 if (virJSONValueObjectGetNumberUlong(data, "free_mem", &mem) < 0) {
971                     qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
972                                     _("info balloon reply was missing balloon free_mem"));
973                     ret = -1;
974                     goto cleanup;
975                 }
976                 stats[got].tag = VIR_DOMAIN_MEMORY_STAT_UNUSED;
977                 stats[got].val = (mem/1024);
978                 got++;
979             }
980             if (virJSONValueObjectHasKey(data, "total_mem") && (got < nr_stats)) {
981                 if (virJSONValueObjectGetNumberUlong(data, "total_mem", &mem) < 0) {
982                     qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
983                                     _("info balloon reply was missing balloon total_mem"));
984                     ret = -1;
985                     goto cleanup;
986                 }
987                 stats[got].tag = VIR_DOMAIN_MEMORY_STAT_AVAILABLE;
988                 stats[got].val = (mem/1024);
989                 got++;
990             }
991         }
992     }
993
994     if (got > 0)
995         ret = got;
996
997 cleanup:
998     virJSONValueFree(cmd);
999     virJSONValueFree(reply);
1000     return ret;
1001 }
1002
1003
1004 int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
1005                                      const char *devname,
1006                                      long long *rd_req,
1007                                      long long *rd_bytes,
1008                                      long long *wr_req,
1009                                      long long *wr_bytes,
1010                                      long long *errs)
1011 {
1012     int ret;
1013     int i;
1014     int found = 0;
1015     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-blockstats",
1016                                                      NULL);
1017     virJSONValuePtr reply = NULL;
1018     virJSONValuePtr devices;
1019
1020     *rd_req = *rd_bytes = *wr_req = *wr_bytes = *errs = 0;
1021
1022     if (!cmd)
1023         return -1;
1024
1025     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1026
1027     if (ret == 0) {
1028         ret = qemuMonitorJSONCheckError(cmd, reply);
1029         if (ret < 0)
1030             goto cleanup;
1031     }
1032     ret = -1;
1033
1034     devices = virJSONValueObjectGet(reply, "return");
1035     if (!devices || devices->type != VIR_JSON_TYPE_ARRAY) {
1036         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1037                         _("blockstats reply was missing device list"));
1038         goto cleanup;
1039     }
1040
1041     for (i = 0 ; i < virJSONValueArraySize(devices) ; i++) {
1042         virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
1043         virJSONValuePtr stats;
1044         const char *thisdev;
1045         if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
1046             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1047                             _("blockstats device entry was not in expected format"));
1048             goto cleanup;
1049         }
1050
1051         if ((thisdev = virJSONValueObjectGetString(dev, "device")) == NULL) {
1052             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1053                             _("blockstats device entry was not in expected format"));
1054             goto cleanup;
1055         }
1056
1057         /* New QEMU has separate names for host & guest side of the disk
1058          * and libvirt gives the host side a 'drive-' prefix. The passed
1059          * in devname is the guest side though
1060          */
1061         if (STRPREFIX(thisdev, QEMU_DRIVE_HOST_PREFIX))
1062             thisdev += strlen(QEMU_DRIVE_HOST_PREFIX);
1063
1064         if (STRNEQ(thisdev, devname))
1065             continue;
1066
1067         found = 1;
1068         if ((stats = virJSONValueObjectGet(dev, "stats")) == NULL ||
1069             stats->type != VIR_JSON_TYPE_OBJECT) {
1070             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1071                             _("blockstats stats entry was not in expected format"));
1072             goto cleanup;
1073         }
1074
1075         if (virJSONValueObjectGetNumberLong(stats, "rd_bytes", rd_bytes) < 0) {
1076             qemuReportError(VIR_ERR_INTERNAL_ERROR,
1077                             _("cannot read %s statistic"),
1078                             "rd_bytes");
1079             goto cleanup;
1080         }
1081         if (virJSONValueObjectGetNumberLong(stats, "rd_operations", rd_req) < 0) {
1082             qemuReportError(VIR_ERR_INTERNAL_ERROR,
1083                             _("cannot read %s statistic"),
1084                             "rd_operations");
1085             goto cleanup;
1086         }
1087         if (virJSONValueObjectGetNumberLong(stats, "wr_bytes", wr_bytes) < 0) {
1088             qemuReportError(VIR_ERR_INTERNAL_ERROR,
1089                             _("cannot read %s statistic"),
1090                             "wr_bytes");
1091             goto cleanup;
1092         }
1093         if (virJSONValueObjectGetNumberLong(stats, "wr_operations", wr_req) < 0) {
1094             qemuReportError(VIR_ERR_INTERNAL_ERROR,
1095                             _("cannot read %s statistic"),
1096                             "wr_operations");
1097             goto cleanup;
1098         }
1099     }
1100
1101     if (!found) {
1102         qemuReportError(VIR_ERR_INTERNAL_ERROR,
1103                         _("cannot find statistics for device '%s'"), devname);
1104         goto cleanup;
1105     }
1106     ret = 0;
1107
1108 cleanup:
1109     virJSONValueFree(cmd);
1110     virJSONValueFree(reply);
1111     return ret;
1112 }
1113
1114
1115 int qemuMonitorJSONSetVNCPassword(qemuMonitorPtr mon,
1116                                   const char *password)
1117 {
1118     int ret;
1119     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("change",
1120                                                      "s:device", "vnc",
1121                                                      "s:target", "password",
1122                                                      "s:arg", password,
1123                                                      NULL);
1124     virJSONValuePtr reply = NULL;
1125     if (!cmd)
1126         return -1;
1127
1128     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1129
1130     if (ret == 0)
1131         ret = qemuMonitorJSONCheckError(cmd, reply);
1132
1133     virJSONValueFree(cmd);
1134     virJSONValueFree(reply);
1135     return ret;
1136 }
1137
1138 /*
1139  * Returns: 0 if balloon not supported, +1 if balloon adjust worked
1140  * or -1 on failure
1141  */
1142 int qemuMonitorJSONSetBalloon(qemuMonitorPtr mon,
1143                               unsigned long newmem)
1144 {
1145     int ret;
1146     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("balloon",
1147                                                      "U:value", ((unsigned long long)newmem)*1024,
1148                                                      NULL);
1149     virJSONValuePtr reply = NULL;
1150     if (!cmd)
1151         return -1;
1152
1153     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1154
1155     if (ret == 0) {
1156         /* See if balloon soft-failed */
1157         if (qemuMonitorJSONHasError(reply, "DeviceNotActive") ||
1158             qemuMonitorJSONHasError(reply, "KVMMissingCap"))
1159             goto cleanup;
1160
1161         /* See if any other fatal error occurred */
1162         ret = qemuMonitorJSONCheckError(cmd, reply);
1163
1164         /* Real success */
1165         if (ret == 0)
1166             ret = 1;
1167     }
1168
1169 cleanup:
1170     virJSONValueFree(cmd);
1171     virJSONValueFree(reply);
1172     return ret;
1173 }
1174
1175
1176 /*
1177  * Returns: 0 if CPU hotplug not supported, +1 if CPU hotplug worked
1178  * or -1 on failure
1179  */
1180 int qemuMonitorJSONSetCPU(qemuMonitorPtr mon,
1181                           int cpu, int online)
1182 {
1183     int ret;
1184     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("balloon",
1185                                                      "U:cpu", (unsigned long long)cpu,
1186                                                      "s:state", online ? "online" : "offline",
1187                                                      NULL);
1188     virJSONValuePtr reply = NULL;
1189     if (!cmd)
1190         return -1;
1191
1192     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1193
1194     if (ret == 0) {
1195         /* XXX See if CPU soft-failed due to lack of ACPI */
1196 #if 0
1197         if (qemuMonitorJSONHasError(reply, "DeviceNotActive") ||
1198             qemuMonitorJSONHasError(reply, "KVMMissingCap"))
1199             goto cleanup;
1200 #endif
1201
1202         /* See if any other fatal error occurred */
1203         ret = qemuMonitorJSONCheckError(cmd, reply);
1204
1205         /* Real success */
1206         if (ret == 0)
1207             ret = 1;
1208     }
1209
1210 #if 0
1211 cleanup:
1212 #endif
1213
1214     virJSONValueFree(cmd);
1215     virJSONValueFree(reply);
1216     return ret;
1217 }
1218
1219
1220 int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon,
1221                               const char *devname)
1222 {
1223     int ret;
1224     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("eject",
1225                                                      "s:device", devname,
1226                                                      "i:force", 0,
1227                                                      NULL);
1228     virJSONValuePtr reply = NULL;
1229     if (!cmd)
1230         return -1;
1231
1232     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1233
1234     if (ret == 0)
1235         ret = qemuMonitorJSONCheckError(cmd, reply);
1236
1237     virJSONValueFree(cmd);
1238     virJSONValueFree(reply);
1239     return ret;
1240 }
1241
1242
1243 int qemuMonitorJSONChangeMedia(qemuMonitorPtr mon,
1244                                const char *devname,
1245                                const char *newmedia,
1246                                const char *format)
1247 {
1248     int ret;
1249     virJSONValuePtr cmd;
1250     if (format)
1251         cmd = qemuMonitorJSONMakeCommand("change",
1252                                          "s:device", devname,
1253                                          "s:target", newmedia,
1254                                          "s:arg", format,
1255                                          NULL);
1256     else
1257         cmd = qemuMonitorJSONMakeCommand("change",
1258                                          "s:device", devname,
1259                                          "s:target", newmedia,
1260                                          NULL);
1261
1262     virJSONValuePtr reply = NULL;
1263     if (!cmd)
1264         return -1;
1265
1266     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1267
1268     if (ret == 0)
1269         ret = qemuMonitorJSONCheckError(cmd, reply);
1270
1271     virJSONValueFree(cmd);
1272     virJSONValueFree(reply);
1273     return ret;
1274 }
1275
1276
1277 static int qemuMonitorJSONSaveMemory(qemuMonitorPtr mon,
1278                                      const char *cmdtype,
1279                                      unsigned long long offset,
1280                                      size_t length,
1281                                      const char *path)
1282 {
1283     int ret;
1284     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand(cmdtype,
1285                                                      "U:val", offset,
1286                                                      "u:size", length,
1287                                                      "s:filename", path,
1288                                                      NULL);
1289     virJSONValuePtr reply = NULL;
1290     if (!cmd)
1291         return -1;
1292
1293     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1294
1295     if (ret == 0)
1296         ret = qemuMonitorJSONCheckError(cmd, reply);
1297
1298     virJSONValueFree(cmd);
1299     virJSONValueFree(reply);
1300     return ret;
1301 }
1302
1303
1304 int qemuMonitorJSONSaveVirtualMemory(qemuMonitorPtr mon,
1305                                      unsigned long long offset,
1306                                      size_t length,
1307                                      const char *path)
1308 {
1309     return qemuMonitorJSONSaveMemory(mon, "memsave", offset, length, path);
1310 }
1311
1312 int qemuMonitorJSONSavePhysicalMemory(qemuMonitorPtr mon,
1313                                       unsigned long long offset,
1314                                       size_t length,
1315                                       const char *path)
1316 {
1317     return qemuMonitorJSONSaveMemory(mon, "pmemsave", offset, length, path);
1318 }
1319
1320
1321 int qemuMonitorJSONSetMigrationSpeed(qemuMonitorPtr mon,
1322                                      unsigned long bandwidth)
1323 {
1324     int ret;
1325     char *bandwidthstr;
1326     virJSONValuePtr cmd;
1327     virJSONValuePtr reply = NULL;
1328     if (virAsprintf(&bandwidthstr, "%lum", bandwidth) < 0) {
1329         virReportOOMError();
1330         return -1;
1331     }
1332     cmd = qemuMonitorJSONMakeCommand("migrate_set_speed",
1333                                      "s:value", bandwidthstr,
1334                                      NULL);
1335     VIR_FREE(bandwidthstr);
1336     if (!cmd)
1337         return -1;
1338
1339     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1340
1341     if (ret == 0)
1342         ret = qemuMonitorJSONCheckError(cmd, reply);
1343
1344     virJSONValueFree(cmd);
1345     virJSONValueFree(reply);
1346     return ret;
1347 }
1348
1349
1350 int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon,
1351                                         unsigned long long downtime)
1352 {
1353     int ret;
1354     char *downtimestr;
1355     virJSONValuePtr cmd;
1356     virJSONValuePtr reply = NULL;
1357     if (virAsprintf(&downtimestr, "%llums", downtime) < 0) {
1358         virReportOOMError();
1359         return -1;
1360     }
1361     cmd = qemuMonitorJSONMakeCommand("migrate_set_downtime",
1362                                      "s:value", downtimestr,
1363                                      NULL);
1364     VIR_FREE(downtimestr);
1365     if (!cmd)
1366         return -1;
1367
1368     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1369
1370     if (ret == 0)
1371         ret = qemuMonitorJSONCheckError(cmd, reply);
1372
1373     virJSONValueFree(cmd);
1374     virJSONValueFree(reply);
1375     return ret;
1376 }
1377
1378
1379 static int
1380 qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
1381                                        int *status,
1382                                        unsigned long long *transferred,
1383                                        unsigned long long *remaining,
1384                                        unsigned long long *total)
1385 {
1386     virJSONValuePtr ret;
1387     const char *statusstr;
1388
1389     if (!(ret = virJSONValueObjectGet(reply, "return"))) {
1390         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1391                         _("info migration reply was missing return data"));
1392         return -1;
1393     }
1394
1395     if (!(statusstr = virJSONValueObjectGetString(ret, "status"))) {
1396         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1397                         _("info migration reply was missing return status"));
1398         return -1;
1399     }
1400
1401     if ((*status = qemuMonitorMigrationStatusTypeFromString(statusstr)) < 0) {
1402         qemuReportError(VIR_ERR_INTERNAL_ERROR,
1403                         _("unexpected migration status in %s"), statusstr);
1404         return -1;
1405     }
1406
1407     if (*status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
1408         virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram");
1409         if (!ram) {
1410             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1411                             _("migration was active, but no RAM info was set"));
1412             return -1;
1413         }
1414
1415         if (virJSONValueObjectGetNumberUlong(ram, "transferred", transferred) < 0) {
1416             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1417                             _("migration was active, but RAM 'transferred' data was missing"));
1418             return -1;
1419         }
1420         if (virJSONValueObjectGetNumberUlong(ram, "remaining", remaining) < 0) {
1421             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1422                             _("migration was active, but RAM 'remaining' data was missing"));
1423             return -1;
1424         }
1425         if (virJSONValueObjectGetNumberUlong(ram, "total", total) < 0) {
1426             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1427                             _("migration was active, but RAM 'total' data was missing"));
1428             return -1;
1429         }
1430     }
1431
1432     return 0;
1433 }
1434
1435
1436 int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
1437                                       int *status,
1438                                       unsigned long long *transferred,
1439                                       unsigned long long *remaining,
1440                                       unsigned long long *total)
1441 {
1442     int ret;
1443     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-migrate",
1444                                                      NULL);
1445     virJSONValuePtr reply = NULL;
1446
1447     *status = 0;
1448     *transferred = *remaining = *total = 0;
1449
1450     if (!cmd)
1451         return -1;
1452
1453     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1454
1455     if (ret == 0)
1456         ret = qemuMonitorJSONCheckError(cmd, reply);
1457
1458     if (ret == 0 &&
1459         qemuMonitorJSONGetMigrationStatusReply(reply,
1460                                                status,
1461                                                transferred,
1462                                                remaining,
1463                                                total) < 0)
1464         ret = -1;
1465
1466     virJSONValueFree(cmd);
1467     virJSONValueFree(reply);
1468     return ret;
1469 }
1470
1471
1472 static int qemuMonitorJSONMigrate(qemuMonitorPtr mon,
1473                                   int background,
1474                                   const char *uri)
1475 {
1476     int ret;
1477     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("migrate",
1478                                                      "i:detach", background ? 1 : 0,
1479                                                      "s:uri", uri,
1480                                                      NULL);
1481     virJSONValuePtr reply = NULL;
1482
1483     if (!cmd)
1484         return -1;
1485
1486     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1487
1488     if (ret == 0)
1489         ret = qemuMonitorJSONCheckError(cmd, reply);
1490
1491     virJSONValueFree(cmd);
1492     virJSONValueFree(reply);
1493     return ret;
1494 }
1495
1496
1497 int qemuMonitorJSONMigrateToHost(qemuMonitorPtr mon,
1498                                  int background,
1499                                  const char *hostname,
1500                                  int port)
1501 {
1502     char *uri = NULL;
1503     int ret;
1504
1505     if (virAsprintf(&uri, "tcp:%s:%d", hostname, port) < 0) {
1506         virReportOOMError();
1507         return -1;
1508     }
1509
1510     ret = qemuMonitorJSONMigrate(mon, background, uri);
1511
1512     VIR_FREE(uri);
1513
1514     return ret;
1515 }
1516
1517
1518 int qemuMonitorJSONMigrateToCommand(qemuMonitorPtr mon,
1519                                     int background,
1520                                     const char * const *argv,
1521                                     const char *target)
1522 {
1523     char *argstr;
1524     char *dest = NULL;
1525     int ret = -1;
1526     char *safe_target = NULL;
1527
1528     argstr = virArgvToString(argv);
1529     if (!argstr) {
1530         virReportOOMError();
1531         goto cleanup;
1532     }
1533
1534     /* Migrate to file */
1535     safe_target = qemuMonitorEscapeShell(target);
1536     if (!safe_target) {
1537         virReportOOMError();
1538         goto cleanup;
1539     }
1540
1541     if (virAsprintf(&dest, "exec:%s >>%s 2>/dev/null", argstr, safe_target) < 0) {
1542         virReportOOMError();
1543         goto cleanup;
1544     }
1545
1546     ret = qemuMonitorJSONMigrate(mon, background, dest);
1547
1548 cleanup:
1549     VIR_FREE(safe_target);
1550     VIR_FREE(argstr);
1551     VIR_FREE(dest);
1552     return ret;
1553 }
1554
1555 int qemuMonitorJSONMigrateToUnix(qemuMonitorPtr mon,
1556                                  int background,
1557                                  const char *unixfile)
1558 {
1559     char *dest = NULL;
1560     int ret = -1;
1561
1562     if (virAsprintf(&dest, "unix:%s", unixfile) < 0) {
1563         virReportOOMError();
1564         return -1;
1565     }
1566
1567     ret = qemuMonitorJSONMigrate(mon, background, dest);
1568
1569     VIR_FREE(dest);
1570
1571     return ret;
1572 }
1573
1574
1575 int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon)
1576 {
1577     int ret;
1578     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("migrate_cancel", NULL);
1579     virJSONValuePtr reply = NULL;
1580     if (!cmd)
1581         return -1;
1582
1583     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1584
1585     if (ret == 0)
1586         ret = qemuMonitorJSONCheckError(cmd, reply);
1587
1588     virJSONValueFree(cmd);
1589     virJSONValueFree(reply);
1590     return ret;
1591 }
1592
1593
1594 static int qemuMonitorJSONAddUSB(qemuMonitorPtr mon,
1595                                  const char *dev)
1596 {
1597     int ret;
1598     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("usb_add",
1599                                                      "s:devname", dev,
1600                                                      NULL);
1601     virJSONValuePtr reply = NULL;
1602
1603     if (!cmd)
1604         return -1;
1605
1606     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1607
1608     if (ret == 0)
1609         ret = qemuMonitorJSONCheckError(cmd, reply);
1610
1611     virJSONValueFree(cmd);
1612     virJSONValueFree(reply);
1613     return ret;
1614 }
1615
1616
1617 int qemuMonitorJSONAddUSBDisk(qemuMonitorPtr mon,
1618                               const char *path)
1619 {
1620     int ret;
1621     char *disk;
1622
1623     if (virAsprintf(&disk, "disk:%s", path) < 0) {
1624         virReportOOMError();
1625         return -1;
1626     }
1627
1628     ret = qemuMonitorJSONAddUSB(mon, disk);
1629
1630     VIR_FREE(disk);
1631
1632     return ret;
1633 }
1634
1635
1636 int qemuMonitorJSONAddUSBDeviceExact(qemuMonitorPtr mon,
1637                                      int bus,
1638                                      int dev)
1639 {
1640     int ret;
1641     char *addr;
1642
1643     if (virAsprintf(&addr, "host:%.3d.%.3d", bus, dev) < 0) {
1644         virReportOOMError();
1645         return -1;
1646     }
1647
1648     ret = qemuMonitorJSONAddUSB(mon, addr);
1649
1650     VIR_FREE(addr);
1651     return ret;
1652 }
1653
1654
1655 int qemuMonitorJSONAddUSBDeviceMatch(qemuMonitorPtr mon,
1656                                      int vendor,
1657                                      int product)
1658 {
1659     int ret;
1660     char *addr;
1661
1662     if (virAsprintf(&addr, "host:%.4x:%.4x", vendor, product) < 0) {
1663         virReportOOMError();
1664         return -1;
1665     }
1666
1667     ret = qemuMonitorJSONAddUSB(mon, addr);
1668
1669     VIR_FREE(addr);
1670     return ret;
1671 }
1672
1673
1674 static int
1675 qemuMonitorJSONGetGuestPCIAddress(virJSONValuePtr reply,
1676                                   virDomainDevicePCIAddress *guestAddr)
1677 {
1678     virJSONValuePtr addr;
1679
1680     addr = virJSONValueObjectGet(reply, "return");
1681     if (!addr || addr->type != VIR_JSON_TYPE_OBJECT) {
1682         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1683                         _("pci_add reply was missing device address"));
1684         return -1;
1685     }
1686
1687     if (virJSONValueObjectGetNumberUint(addr, "domain", &guestAddr->domain) < 0) {
1688         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1689                         _("pci_add reply was missing device domain number"));
1690         return -1;
1691     }
1692
1693     if (virJSONValueObjectGetNumberUint(addr, "bus", &guestAddr->bus) < 0) {
1694         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1695                         _("pci_add reply was missing device bus number"));
1696         return -1;
1697     }
1698
1699     if (virJSONValueObjectGetNumberUint(addr, "slot", &guestAddr->slot) < 0) {
1700         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1701                         _("pci_add reply was missing device slot number"));
1702         return -1;
1703     }
1704
1705     if (virJSONValueObjectGetNumberUint(addr, "function", &guestAddr->function) < 0) {
1706         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1707                         _("pci_add reply was missing device function number"));
1708         return -1;
1709     }
1710
1711     return 0;
1712 }
1713
1714
1715 int qemuMonitorJSONAddPCIHostDevice(qemuMonitorPtr mon,
1716                                     virDomainDevicePCIAddress *hostAddr,
1717                                     virDomainDevicePCIAddress *guestAddr)
1718 {
1719     int ret;
1720     virJSONValuePtr cmd;
1721     virJSONValuePtr reply = NULL;
1722     char *dev;
1723
1724     memset(guestAddr, 0, sizeof(*guestAddr));
1725
1726     /* XXX hostDomain */
1727     if (virAsprintf(&dev, "host=%.2x:%.2x.%.1x",
1728                     hostAddr->bus, hostAddr->slot, hostAddr->function) < 0) {
1729         virReportOOMError();
1730         return -1;
1731     }
1732
1733     cmd = qemuMonitorJSONMakeCommand("pci_add",
1734                                      "s:pci_addr", "auto"
1735                                      "s:type", "host",
1736                                      "s:opts", dev,
1737                                      NULL);
1738     VIR_FREE(dev);
1739     if (!cmd)
1740         return -1;
1741
1742     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1743
1744     if (ret == 0)
1745         ret = qemuMonitorJSONCheckError(cmd, reply);
1746
1747     if (ret == 0 &&
1748         qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0)
1749         ret = -1;
1750
1751     virJSONValueFree(cmd);
1752     virJSONValueFree(reply);
1753     return ret;
1754 }
1755
1756
1757 int qemuMonitorJSONAddPCIDisk(qemuMonitorPtr mon,
1758                               const char *path,
1759                               const char *bus,
1760                               virDomainDevicePCIAddress *guestAddr)
1761 {
1762     int ret;
1763     virJSONValuePtr cmd;
1764     virJSONValuePtr reply = NULL;
1765     char *dev;
1766
1767     memset(guestAddr, 0, sizeof(*guestAddr));
1768
1769     if (virAsprintf(&dev, "file=%s,if=%s", path, bus) < 0) {
1770         virReportOOMError();
1771         return -1;
1772     }
1773
1774     cmd = qemuMonitorJSONMakeCommand("pci_add",
1775                                      "s:pci_addr", "auto",
1776                                      "s:type", "storage",
1777                                      "s:opts", dev,
1778                                      NULL);
1779     VIR_FREE(dev);
1780     if (!cmd)
1781         return -1;
1782
1783     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1784
1785     if (ret == 0)
1786         ret = qemuMonitorJSONCheckError(cmd, reply);
1787
1788     if (ret == 0 &&
1789         qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0)
1790         ret = -1;
1791
1792     virJSONValueFree(cmd);
1793     virJSONValueFree(reply);
1794     return ret;
1795 }
1796
1797
1798 int qemuMonitorJSONAddPCINetwork(qemuMonitorPtr mon,
1799                                  const char *nicstr,
1800                                  virDomainDevicePCIAddress *guestAddr)
1801 {
1802     int ret;
1803     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("pci_add",
1804                                                      "s:pci_addr", "auto",
1805                                                      "s:type", "nic",
1806                                                      "s:opts", nicstr,
1807                                                      NULL);
1808     virJSONValuePtr reply = NULL;
1809
1810     memset(guestAddr, 0, sizeof(*guestAddr));
1811
1812     if (!cmd)
1813         return -1;
1814
1815     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1816
1817     if (ret == 0)
1818         ret = qemuMonitorJSONCheckError(cmd, reply);
1819
1820     if (ret == 0 &&
1821         qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0)
1822         ret = -1;
1823
1824     virJSONValueFree(cmd);
1825     virJSONValueFree(reply);
1826     return ret;
1827 }
1828
1829
1830 int qemuMonitorJSONRemovePCIDevice(qemuMonitorPtr mon,
1831                                    virDomainDevicePCIAddress *guestAddr)
1832 {
1833     int ret;
1834     virJSONValuePtr cmd;
1835     virJSONValuePtr reply = NULL;
1836     char *addr;
1837
1838     /* XXX what about function ? */
1839     if (virAsprintf(&addr, "%.4x:%.2x:%.2x",
1840                     guestAddr->domain, guestAddr->bus, guestAddr->slot) < 0) {
1841         virReportOOMError();
1842         return -1;
1843     }
1844
1845     cmd = qemuMonitorJSONMakeCommand("pci_del",
1846                                      "s:pci_addr", addr,
1847                                      NULL);
1848     VIR_FREE(addr);
1849     if (!cmd)
1850         return -1;
1851
1852     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1853
1854     if (ret == 0)
1855         ret = qemuMonitorJSONCheckError(cmd, reply);
1856
1857     virJSONValueFree(cmd);
1858     virJSONValueFree(reply);
1859     return ret;
1860 }
1861
1862
1863 int qemuMonitorJSONSendFileHandle(qemuMonitorPtr mon,
1864                                   const char *fdname,
1865                                   int fd)
1866 {
1867     int ret;
1868     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("getfd",
1869                                                      "s:fdname", fdname,
1870                                                      NULL);
1871     virJSONValuePtr reply = NULL;
1872     if (!cmd)
1873         return -1;
1874
1875     ret = qemuMonitorJSONCommandWithFd(mon, cmd, fd, &reply);
1876
1877     if (ret == 0)
1878         ret = qemuMonitorJSONCheckError(cmd, reply);
1879
1880     virJSONValueFree(cmd);
1881     virJSONValueFree(reply);
1882     return ret;
1883 }
1884
1885
1886 int qemuMonitorJSONCloseFileHandle(qemuMonitorPtr mon,
1887                                    const char *fdname)
1888 {
1889     int ret;
1890     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("closefd",
1891                                                      "s:fdname", fdname,
1892                                                      NULL);
1893     virJSONValuePtr reply = NULL;
1894     if (!cmd)
1895         return -1;
1896
1897     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1898
1899     if (ret == 0)
1900         ret = qemuMonitorJSONCheckError(cmd, reply);
1901
1902     virJSONValueFree(cmd);
1903     virJSONValueFree(reply);
1904     return ret;
1905 }
1906
1907
1908 int qemuMonitorJSONAddHostNetwork(qemuMonitorPtr mon,
1909                                   const char *netstr)
1910 {
1911     int ret;
1912     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("host_net_add",
1913                                                      "s:device", netstr,
1914                                                      NULL);
1915     virJSONValuePtr reply = NULL;
1916     if (!cmd)
1917         return -1;
1918
1919     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1920
1921     if (ret == 0)
1922         ret = qemuMonitorJSONCheckError(cmd, reply);
1923
1924     virJSONValueFree(cmd);
1925     virJSONValueFree(reply);
1926     return ret;
1927 }
1928
1929
1930 int qemuMonitorJSONRemoveHostNetwork(qemuMonitorPtr mon,
1931                                      int vlan,
1932                                      const char *netname)
1933 {
1934     int ret;
1935     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("host_net_remove",
1936                                                      "i:vlan", vlan,
1937                                                      "s:device", netname,
1938                                                      NULL);
1939     virJSONValuePtr reply = NULL;
1940     if (!cmd)
1941         return -1;
1942
1943     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
1944
1945     if (ret == 0)
1946         ret = qemuMonitorJSONCheckError(cmd, reply);
1947
1948     virJSONValueFree(cmd);
1949     virJSONValueFree(reply);
1950     return ret;
1951 }
1952
1953
1954 /*
1955  * Example return data
1956  *
1957  * {"return": [
1958  *      {"filename": "stdio", "label": "monitor"},
1959  *      {"filename": "pty:/dev/pts/6", "label": "serial0"},
1960  *      {"filename": "pty:/dev/pts/7", "label": "parallel0"}
1961  * ]}
1962  *
1963  */
1964 static int qemuMonitorJSONExtractPtyPaths(virJSONValuePtr reply,
1965                                           virHashTablePtr paths)
1966 {
1967     virJSONValuePtr data;
1968     int ret = -1;
1969     int i;
1970
1971     if (!(data = virJSONValueObjectGet(reply, "return"))) {
1972         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1973                         _("character device reply was missing return data"));
1974         goto cleanup;
1975     }
1976
1977     if (data->type != VIR_JSON_TYPE_ARRAY) {
1978         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1979                         _("character device information was not an array"));
1980         goto cleanup;
1981     }
1982
1983     for (i = 0 ; i < virJSONValueArraySize(data) ; i++) {
1984         virJSONValuePtr entry = virJSONValueArrayGet(data, i);
1985         const char *type;
1986         const char *id;
1987         if (!entry) {
1988             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1989                             _("character device information was missing aray element"));
1990             goto cleanup;
1991         }
1992
1993         if (!(type = virJSONValueObjectGetString(entry, "filename"))) {
1994             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1995                             _("character device information was missing filename"));
1996             goto cleanup;
1997         }
1998
1999         if (!(id = virJSONValueObjectGetString(entry, "label"))) {
2000             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2001                             _("character device information was missing filename"));
2002             goto cleanup;
2003         }
2004
2005         if (STRPREFIX(type, "pty:")) {
2006             char *path = strdup(type + strlen("pty:"));
2007             if (!path) {
2008                 virReportOOMError();
2009                 goto cleanup;
2010             }
2011
2012             if (virHashAddEntry(paths, id, path) < 0) {
2013                 qemuReportError(VIR_ERR_OPERATION_FAILED,
2014                                 _("failed to save chardev path '%s'"), path);
2015                 VIR_FREE(path);
2016                 goto cleanup;
2017             }
2018         }
2019     }
2020
2021     ret = 0;
2022
2023 cleanup:
2024     return ret;
2025 }
2026
2027 int qemuMonitorJSONGetPtyPaths(qemuMonitorPtr mon,
2028                                virHashTablePtr paths)
2029
2030 {
2031     int ret;
2032     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-chardev",
2033                                                      NULL);
2034     virJSONValuePtr reply = NULL;
2035
2036     if (!cmd)
2037         return -1;
2038
2039     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2040
2041     if (ret == 0)
2042         ret = qemuMonitorJSONCheckError(cmd, reply);
2043
2044     if (ret == 0)
2045         ret = qemuMonitorJSONExtractPtyPaths(reply, paths);
2046
2047     virJSONValueFree(cmd);
2048     virJSONValueFree(reply);
2049     return ret;
2050 }
2051
2052
2053 int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon,
2054                                            const char *bus,
2055                                            virDomainDevicePCIAddress *guestAddr)
2056 {
2057     int ret;
2058     virJSONValuePtr cmd;
2059     virJSONValuePtr reply = NULL;
2060     char *dev;
2061
2062     memset(guestAddr, 0, sizeof(*guestAddr));
2063
2064     if (virAsprintf(&dev, "if=%s", bus) < 0) {
2065         virReportOOMError();
2066         return -1;
2067     }
2068
2069     cmd = qemuMonitorJSONMakeCommand("pci_add",
2070                                      "s:pci_addr", "auto",
2071                                      "s:type", "storage",
2072                                      "s:opts", dev,
2073                                      NULL);
2074     VIR_FREE(dev);
2075     if (!cmd)
2076         return -1;
2077
2078     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2079
2080     if (ret == 0)
2081         ret = qemuMonitorJSONCheckError(cmd, reply);
2082
2083     if (ret == 0 &&
2084         qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0)
2085         ret = -1;
2086
2087     virJSONValueFree(cmd);
2088     virJSONValueFree(reply);
2089     return ret;
2090 }
2091
2092
2093 static int
2094 qemuMonitorJSONGetGuestDriveAddress(virJSONValuePtr reply,
2095                                     virDomainDeviceDriveAddress *driveAddr)
2096 {
2097     virJSONValuePtr addr;
2098
2099     addr = virJSONValueObjectGet(reply, "return");
2100     if (!addr || addr->type != VIR_JSON_TYPE_OBJECT) {
2101         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2102                         _("drive_add reply was missing device address"));
2103         return -1;
2104     }
2105
2106     if (virJSONValueObjectGetNumberUint(addr, "bus", &driveAddr->bus) < 0) {
2107         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2108                         _("drive_add reply was missing device bus number"));
2109         return -1;
2110     }
2111
2112     if (virJSONValueObjectGetNumberUint(addr, "unit", &driveAddr->unit) < 0) {
2113         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2114                         _("drive_add reply was missing device unit number"));
2115         return -1;
2116     }
2117
2118     return 0;
2119 }
2120
2121
2122 int qemuMonitorJSONAttachDrive(qemuMonitorPtr mon,
2123                                const char *drivestr,
2124                                virDomainDevicePCIAddress* controllerAddr,
2125                                virDomainDeviceDriveAddress* driveAddr)
2126 {
2127     int ret;
2128     virJSONValuePtr cmd = NULL;
2129     virJSONValuePtr reply = NULL;
2130     char *dev;
2131
2132     if (virAsprintf(&dev, "%.2x:%.2x.%.1x",
2133                     controllerAddr->bus, controllerAddr->slot, controllerAddr->function) < 0) {
2134         virReportOOMError();
2135         return -1;
2136     }
2137
2138     cmd = qemuMonitorJSONMakeCommand("drive_add",
2139                                      "s:pci_addr", dev,
2140                                      "s:opts", drivestr,
2141                                      NULL);
2142     VIR_FREE(dev);
2143     if (!cmd)
2144         return -1;
2145
2146     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2147
2148     if (ret == 0)
2149         ret = qemuMonitorJSONCheckError(cmd, reply);
2150
2151     if (ret == 0 &&
2152         qemuMonitorJSONGetGuestDriveAddress(reply, driveAddr) < 0)
2153         ret = -1;
2154
2155     virJSONValueFree(cmd);
2156     virJSONValueFree(reply);
2157     return ret;
2158 }
2159
2160
2161 int qemuMonitorJSONGetAllPCIAddresses(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
2162                                       qemuMonitorPCIAddress **addrs ATTRIBUTE_UNUSED)
2163 {
2164     qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2165                     _("query-pci not suppported in JSON mode"));
2166     return -1;
2167 }
2168
2169
2170 int qemuMonitorJSONDelDevice(qemuMonitorPtr mon,
2171                              const char *devicestr)
2172 {
2173     int ret;
2174     virJSONValuePtr cmd;
2175     virJSONValuePtr reply = NULL;
2176
2177     cmd = qemuMonitorJSONMakeCommand("device_del",
2178                                      "s:config", devicestr,
2179                                      NULL);
2180     if (!cmd)
2181         return -1;
2182
2183     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2184
2185     if (ret == 0)
2186         ret = qemuMonitorJSONCheckError(cmd, reply);
2187
2188     virJSONValueFree(cmd);
2189     virJSONValueFree(reply);
2190     return ret;
2191 }
2192
2193
2194 int qemuMonitorJSONAddDevice(qemuMonitorPtr mon,
2195                              const char *devicestr)
2196 {
2197     int ret;
2198     virJSONValuePtr cmd;
2199     virJSONValuePtr reply = NULL;
2200
2201     cmd = qemuMonitorJSONMakeCommand("device_add",
2202                                      "s:config", devicestr,
2203                                      NULL);
2204     if (!cmd)
2205         return -1;
2206
2207     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2208
2209     if (ret == 0)
2210         ret = qemuMonitorJSONCheckError(cmd, reply);
2211
2212     virJSONValueFree(cmd);
2213     virJSONValueFree(reply);
2214     return ret;
2215 }
2216
2217
2218 int qemuMonitorJSONAddDrive(qemuMonitorPtr mon,
2219                             const char *drivestr)
2220 {
2221     int ret;
2222     virJSONValuePtr cmd;
2223     virJSONValuePtr reply = NULL;
2224
2225     cmd = qemuMonitorJSONMakeCommand("drive_add",
2226                                      "s:pci_addr", "dummy",
2227                                      "s:opts", drivestr,
2228                                      NULL);
2229     if (!cmd)
2230         return -1;
2231
2232     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2233
2234     if (ret == 0)
2235         ret = qemuMonitorJSONCheckError(cmd, reply);
2236
2237     virJSONValueFree(cmd);
2238     virJSONValueFree(reply);
2239     return ret;
2240 }
2241
2242
2243 int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
2244                                       const char *alias,
2245                                       const char *passphrase)
2246 {
2247     int ret;
2248     virJSONValuePtr cmd;
2249     virJSONValuePtr reply = NULL;
2250     char *drive;
2251
2252     if (virAsprintf(&drive, "%s%s", QEMU_DRIVE_HOST_PREFIX, alias) < 0) {
2253         virReportOOMError();
2254         return -1;
2255     }
2256
2257     cmd = qemuMonitorJSONMakeCommand("block_passwd",
2258                                      "s:device", drive,
2259                                      "s:password", passphrase,
2260                                      NULL);
2261     VIR_FREE(drive);
2262     if (!cmd)
2263         return -1;
2264
2265     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2266
2267     if (ret == 0)
2268         ret = qemuMonitorJSONCheckError(cmd, reply);
2269
2270     virJSONValueFree(cmd);
2271     virJSONValueFree(reply);
2272     return ret;
2273 }
2274
2275 int qemuMonitorJSONCreateSnapshot(qemuMonitorPtr mon, const char *name)
2276 {
2277     int ret;
2278     virJSONValuePtr cmd;
2279     virJSONValuePtr reply = NULL;
2280
2281     cmd = qemuMonitorJSONMakeCommand("savevm",
2282                                      "s:name", name,
2283                                      NULL);
2284     if (!cmd)
2285         return -1;
2286
2287     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2288
2289     if (ret == 0)
2290         ret = qemuMonitorJSONCheckError(cmd, reply);
2291
2292     virJSONValueFree(cmd);
2293     virJSONValueFree(reply);
2294     return ret;
2295 }
2296
2297 int qemuMonitorJSONLoadSnapshot(qemuMonitorPtr mon, const char *name)
2298 {
2299     int ret;
2300     virJSONValuePtr cmd;
2301     virJSONValuePtr reply = NULL;
2302
2303     cmd = qemuMonitorJSONMakeCommand("loadvm",
2304                                      "s:name", name,
2305                                      NULL);
2306     if (!cmd)
2307         return -1;
2308
2309     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2310
2311     if (ret == 0)
2312         ret = qemuMonitorJSONCheckError(cmd, reply);
2313
2314     virJSONValueFree(cmd);
2315     virJSONValueFree(reply);
2316     return ret;
2317 }
2318
2319 int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name)
2320 {
2321     int ret;
2322     virJSONValuePtr cmd;
2323     virJSONValuePtr reply = NULL;
2324
2325     cmd = qemuMonitorJSONMakeCommand("delvm",
2326                                      "s:name", name,
2327                                      NULL);
2328     if (!cmd)
2329         return -1;
2330
2331     ret = qemuMonitorJSONCommand(mon, cmd, &reply);
2332
2333     if (ret == 0)
2334         ret = qemuMonitorJSONCheckError(cmd, reply);
2335
2336     virJSONValueFree(cmd);
2337     virJSONValueFree(reply);
2338     return ret;
2339 }