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 "qemu/sockets.h"
27 #include "qapi/error.h"
28 #include "qapi/qmp/json-parser.h"
29 #include "qapi/qmp/qjson.h"
31 #define SOCKET_MAX_FDS 16
34 JSONMessageParser parser
;
38 static void socket_send(int fd
, const char *buf
, size_t size
)
40 ssize_t res
= qemu_send_full(fd
, buf
, size
);
45 static void qmp_response(void *opaque
, QObject
*obj
, Error
*err
)
47 QMPResponseParser
*qmp
= opaque
;
52 error_prepend(&err
, "QMP JSON response parsing failed: ");
53 error_report_err(err
);
57 g_assert(!qmp
->response
);
58 qmp
->response
= qobject_to(QDict
, obj
);
59 g_assert(qmp
->response
);
62 QDict
*qmp_fd_receive(int fd
)
64 QMPResponseParser qmp
;
65 bool log
= getenv("QTEST_LOG") != NULL
;
68 json_message_parser_init(&qmp
.parser
, qmp_response
, &qmp
, NULL
);
69 while (!qmp
.response
) {
73 len
= recv(fd
, &c
, 1, 0);
74 if (len
== -1 && errno
== EINTR
) {
78 if (len
== -1 || len
== 0) {
79 fprintf(stderr
, "Broken pipe\n");
84 g_assert(write(2, &c
, 1) == 1);
86 json_message_parser_feed(&qmp
.parser
, &c
, 1);
89 g_assert(write(2, "\n", 1) == 1);
91 json_message_parser_destroy(&qmp
.parser
);
97 /* Sends a message and file descriptors to the socket.
98 * It's needed for qmp-commands like getfd/add-fd */
99 static void socket_send_fds(int socket_fd
, int *fds
, size_t fds_num
,
100 const char *buf
, size_t buf_size
)
103 struct msghdr msg
= { 0 };
104 char control
[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS
)] = { 0 };
105 size_t fdsize
= sizeof(int) * fds_num
;
106 struct cmsghdr
*cmsg
;
107 struct iovec iov
= { .iov_base
= (char *)buf
, .iov_len
= buf_size
};
112 if (fds
&& fds_num
> 0) {
113 g_assert_cmpuint(fds_num
, <, SOCKET_MAX_FDS
);
115 msg
.msg_control
= control
;
116 msg
.msg_controllen
= CMSG_SPACE(fdsize
);
118 cmsg
= CMSG_FIRSTHDR(&msg
);
119 cmsg
->cmsg_len
= CMSG_LEN(fdsize
);
120 cmsg
->cmsg_level
= SOL_SOCKET
;
121 cmsg
->cmsg_type
= SCM_RIGHTS
;
122 memcpy(CMSG_DATA(cmsg
), fds
, fdsize
);
126 ret
= sendmsg(socket_fd
, &msg
, 0);
127 } while (ret
< 0 && errno
== EINTR
);
128 g_assert_cmpint(ret
, >, 0);
133 * Allow users to send a message without waiting for the reply,
134 * in the case that they choose to discard all replies up until
135 * a particular EVENT is received.
138 _qmp_fd_vsend_fds(int fd
, int *fds
, size_t fds_num
,
139 const char *fmt
, va_list ap
)
144 assert(fds_num
== 0);
147 /* Going through qobject ensures we escape strings properly */
148 qobj
= qobject_from_vjsonf_nofail(fmt
, ap
);
150 /* No need to send anything for an empty QObject. */
152 int log
= getenv("QTEST_LOG") != NULL
;
153 GString
*str
= qobject_to_json(qobj
);
156 * BUG: QMP doesn't react to input until it sees a newline, an
157 * object, or an array. Work-around: give it a newline.
159 g_string_append_c(str
, '\n');
162 fprintf(stderr
, "%s", str
->str
);
166 /* Send QMP request */
167 if (fds
&& fds_num
> 0) {
168 socket_send_fds(fd
, fds
, fds_num
, str
->str
, str
->len
);
172 socket_send(fd
, str
->str
, str
->len
);
175 g_string_free(str
, true);
181 void qmp_fd_vsend_fds(int fd
, int *fds
, size_t fds_num
,
182 const char *fmt
, va_list ap
)
184 _qmp_fd_vsend_fds(fd
, fds
, fds_num
, fmt
, ap
);
188 void qmp_fd_vsend(int fd
, const char *fmt
, va_list ap
)
190 _qmp_fd_vsend_fds(fd
, NULL
, 0, fmt
, ap
);
194 QDict
*qmp_fdv(int fd
, const char *fmt
, va_list ap
)
196 _qmp_fd_vsend_fds(fd
, NULL
, 0, fmt
, ap
);
198 return qmp_fd_receive(fd
);
201 QDict
*qmp_fd(int fd
, const char *fmt
, ...)
207 response
= qmp_fdv(fd
, fmt
, ap
);
212 void qmp_fd_send(int fd
, const char *fmt
, ...)
217 qmp_fd_vsend(fd
, fmt
, ap
);
221 void qmp_fd_vsend_raw(int fd
, const char *fmt
, va_list ap
)
223 bool log
= getenv("QTEST_LOG") != NULL
;
224 char *str
= g_strdup_vprintf(fmt
, ap
);
227 fprintf(stderr
, "%s", str
);
229 socket_send(fd
, str
, strlen(str
));
233 void qmp_fd_send_raw(int fd
, const char *fmt
, ...)
238 qmp_fd_vsend_raw(fd
, fmt
, ap
);
242 bool qmp_rsp_is_err(QDict
*rsp
)
244 QDict
*error
= qdict_get_qdict(rsp
, "error");
249 void qmp_expect_error_and_unref(QDict
*rsp
, const char *class)
251 QDict
*error
= qdict_get_qdict(rsp
, "error");
253 g_assert_cmpstr(qdict_get_try_str(error
, "class"), ==, class);
254 g_assert_nonnull(qdict_get_try_str(error
, "desc"));
255 g_assert(!qdict_haskey(rsp
, "return"));