4 * Copyright IBM, Corp. 2012
5 * Copyright Red Hat, Inc. 2012
6 * Copyright SUSE LINUX Products GmbH 2013
9 * Anthony Liguori <aliguori@us.ibm.com>
10 * Paolo Bonzini <pbonzini@redhat.com>
11 * Andreas Färber <afaerber@suse.de>
13 * This work is licensed under the terms of the GNU GPL, version 2 or later.
14 * See the COPYING file in the top-level directory.
17 #include "qemu/osdep.h"
22 #include <sys/socket.h>
25 #include "qemu/cutils.h"
26 #include "qapi/error.h"
27 #include "qapi/qmp/json-parser.h"
28 #include "qapi/qmp/qjson.h"
30 #define SOCKET_MAX_FDS 16
33 JSONMessageParser parser
;
37 static void socket_send(int fd
, const char *buf
, size_t size
)
39 size_t res
= qemu_write_full(fd
, buf
, size
);
44 static void qmp_response(void *opaque
, QObject
*obj
, Error
*err
)
46 QMPResponseParser
*qmp
= opaque
;
51 error_prepend(&err
, "QMP JSON response parsing failed: ");
52 error_report_err(err
);
56 g_assert(!qmp
->response
);
57 qmp
->response
= qobject_to(QDict
, obj
);
58 g_assert(qmp
->response
);
61 QDict
*qmp_fd_receive(int fd
)
63 QMPResponseParser qmp
;
64 bool log
= getenv("QTEST_LOG") != NULL
;
67 json_message_parser_init(&qmp
.parser
, qmp_response
, &qmp
, NULL
);
68 while (!qmp
.response
) {
72 len
= read(fd
, &c
, 1);
73 if (len
== -1 && errno
== EINTR
) {
77 if (len
== -1 || len
== 0) {
78 fprintf(stderr
, "Broken pipe\n");
83 g_assert(write(2, &c
, 1) == 1);
85 json_message_parser_feed(&qmp
.parser
, &c
, 1);
88 g_assert(write(2, "\n", 1) == 1);
90 json_message_parser_destroy(&qmp
.parser
);
96 /* Sends a message and file descriptors to the socket.
97 * It's needed for qmp-commands like getfd/add-fd */
98 static void socket_send_fds(int socket_fd
, int *fds
, size_t fds_num
,
99 const char *buf
, size_t buf_size
)
102 struct msghdr msg
= { 0 };
103 char control
[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS
)] = { 0 };
104 size_t fdsize
= sizeof(int) * fds_num
;
105 struct cmsghdr
*cmsg
;
106 struct iovec iov
= { .iov_base
= (char *)buf
, .iov_len
= buf_size
};
111 if (fds
&& fds_num
> 0) {
112 g_assert_cmpuint(fds_num
, <, SOCKET_MAX_FDS
);
114 msg
.msg_control
= control
;
115 msg
.msg_controllen
= CMSG_SPACE(fdsize
);
117 cmsg
= CMSG_FIRSTHDR(&msg
);
118 cmsg
->cmsg_len
= CMSG_LEN(fdsize
);
119 cmsg
->cmsg_level
= SOL_SOCKET
;
120 cmsg
->cmsg_type
= SCM_RIGHTS
;
121 memcpy(CMSG_DATA(cmsg
), fds
, fdsize
);
125 ret
= sendmsg(socket_fd
, &msg
, 0);
126 } while (ret
< 0 && errno
== EINTR
);
127 g_assert_cmpint(ret
, >, 0);
132 * Allow users to send a message without waiting for the reply,
133 * in the case that they choose to discard all replies up until
134 * a particular EVENT is received.
137 _qmp_fd_vsend_fds(int fd
, int *fds
, size_t fds_num
,
138 const char *fmt
, va_list ap
)
143 assert(fds_num
== 0);
146 /* Going through qobject ensures we escape strings properly */
147 qobj
= qobject_from_vjsonf_nofail(fmt
, ap
);
149 /* No need to send anything for an empty QObject. */
151 int log
= getenv("QTEST_LOG") != NULL
;
152 GString
*str
= qobject_to_json(qobj
);
155 * BUG: QMP doesn't react to input until it sees a newline, an
156 * object, or an array. Work-around: give it a newline.
158 g_string_append_c(str
, '\n');
161 fprintf(stderr
, "%s", str
->str
);
165 /* Send QMP request */
166 if (fds
&& fds_num
> 0) {
167 socket_send_fds(fd
, fds
, fds_num
, str
->str
, str
->len
);
171 socket_send(fd
, str
->str
, str
->len
);
174 g_string_free(str
, true);
180 void qmp_fd_vsend_fds(int fd
, int *fds
, size_t fds_num
,
181 const char *fmt
, va_list ap
)
183 _qmp_fd_vsend_fds(fd
, fds
, fds_num
, fmt
, ap
);
187 void qmp_fd_vsend(int fd
, const char *fmt
, va_list ap
)
189 _qmp_fd_vsend_fds(fd
, NULL
, 0, fmt
, ap
);
193 QDict
*qmp_fdv(int fd
, const char *fmt
, va_list ap
)
195 _qmp_fd_vsend_fds(fd
, NULL
, 0, fmt
, ap
);
197 return qmp_fd_receive(fd
);
200 QDict
*qmp_fd(int fd
, const char *fmt
, ...)
206 response
= qmp_fdv(fd
, fmt
, ap
);
211 void qmp_fd_send(int fd
, const char *fmt
, ...)
216 qmp_fd_vsend(fd
, fmt
, ap
);
220 void qmp_fd_vsend_raw(int fd
, const char *fmt
, va_list ap
)
222 bool log
= getenv("QTEST_LOG") != NULL
;
223 char *str
= g_strdup_vprintf(fmt
, ap
);
226 fprintf(stderr
, "%s", str
);
228 socket_send(fd
, str
, strlen(str
));
232 void qmp_fd_send_raw(int fd
, const char *fmt
, ...)
237 qmp_fd_vsend_raw(fd
, fmt
, ap
);
241 bool qmp_rsp_is_err(QDict
*rsp
)
243 QDict
*error
= qdict_get_qdict(rsp
, "error");
248 void qmp_expect_error_and_unref(QDict
*rsp
, const char *class)
250 QDict
*error
= qdict_get_qdict(rsp
, "error");
252 g_assert_cmpstr(qdict_get_try_str(error
, "class"), ==, class);
253 g_assert_nonnull(qdict_get_try_str(error
, "desc"));
254 g_assert(!qdict_haskey(rsp
, "return"));