Lines Matching refs:ev
79 # define LOG_QMP(f, ...) LOGD(DEBUG, ev->domid, f, ##__VA_ARGS__)
292 static int qmp_ev_qemu_compare_version(libxl__ev_qmp *ev, int major, in qmp_ev_qemu_compare_version() argument
296 if (ev->qemu_version.level > (level)) return +1; \ in qmp_ev_qemu_compare_version()
297 if (ev->qemu_version.level < (level)) return -1; \ in qmp_ev_qemu_compare_version()
961 static void dm_stopped(libxl__egc *egc, libxl__ev_qmp *ev,
963 static void dm_state_fd_ready(libxl__egc *egc, libxl__ev_qmp *ev,
965 static void dm_state_save_to_fdset(libxl__egc *egc, libxl__ev_qmp *ev, int fdset);
966 static void dm_state_saved(libxl__egc *egc, libxl__ev_qmp *ev,
975 libxl__ev_qmp *ev = &dsps->qmp; in libxl__qmp_suspend_save() local
977 ev->ao = dsps->ao; in libxl__qmp_suspend_save()
978 ev->domid = dsps->domid; in libxl__qmp_suspend_save()
979 ev->callback = dm_stopped; in libxl__qmp_suspend_save()
980 ev->payload_fd = -1; in libxl__qmp_suspend_save()
982 rc = libxl__ev_qmp_send(egc, ev, "stop", NULL); in libxl__qmp_suspend_save()
992 static void dm_stopped(libxl__egc *egc, libxl__ev_qmp *ev, in dm_stopped() argument
996 libxl__domain_suspend_state *dsps = CONTAINER_OF(ev, *dsps, qmp); in dm_stopped()
1005 dm_state_save_to_fdset(egc, ev, 1); in dm_stopped()
1009 ev->payload_fd = open(filename, O_WRONLY | O_CREAT, 0600); in dm_stopped()
1010 if (ev->payload_fd < 0) { in dm_stopped()
1011 LOGED(ERROR, ev->domid, in dm_stopped()
1017 ev->callback = dm_state_fd_ready; in dm_stopped()
1018 rc = libxl__ev_qmp_send(egc, ev, "add-fd", NULL); in dm_stopped()
1025 if (ev->payload_fd >= 0) { in dm_stopped()
1026 close(ev->payload_fd); in dm_stopped()
1028 ev->payload_fd = -1; in dm_stopped()
1033 static void dm_state_fd_ready(libxl__egc *egc, libxl__ev_qmp *ev, in dm_state_fd_ready() argument
1039 libxl__domain_suspend_state *dsps = CONTAINER_OF(ev, *dsps, qmp); in dm_state_fd_ready()
1041 close(ev->payload_fd); in dm_state_fd_ready()
1042 ev->payload_fd = -1; in dm_state_fd_ready()
1053 dm_state_save_to_fdset(egc, ev, fdset); in dm_state_fd_ready()
1062 static void dm_state_save_to_fdset(libxl__egc *egc, libxl__ev_qmp *ev, int fdset) in dm_state_save_to_fdset() argument
1067 libxl__domain_suspend_state *dsps = CONTAINER_OF(ev, *dsps, qmp); in dm_state_save_to_fdset()
1069 ev->callback = dm_state_saved; in dm_state_save_to_fdset()
1074 if (qmp_ev_qemu_compare_version(ev, 2, 11, 0) >= 0) in dm_state_save_to_fdset()
1077 rc = libxl__ev_qmp_send(egc, ev, "xen-save-devices-state", args); in dm_state_save_to_fdset()
1090 static void dm_state_saved(libxl__egc *egc, libxl__ev_qmp *ev, in dm_state_saved() argument
1094 libxl__domain_suspend_state *dsps = CONTAINER_OF(ev, *dsps, qmp); in dm_state_saved()
1164 libxl__ev_qmp *ev, int fd);
1166 libxl__ev_qmp *ev, int fd);
1167 static int qmp_ev_get_next_msg(libxl__egc *egc, libxl__ev_qmp *ev,
1170 libxl__ev_qmp *ev,
1175 static void qmp_ev_ensure_reading_writing(libxl__gc *gc, libxl__ev_qmp *ev) in qmp_ev_ensure_reading_writing() argument
1181 if (ev->state == qmp_state_waiting_lock) in qmp_ev_ensure_reading_writing()
1185 if (ev->tx_buf) in qmp_ev_ensure_reading_writing()
1187 else if ((ev->state == qmp_state_waiting_reply) && ev->msg) in qmp_ev_ensure_reading_writing()
1190 libxl__ev_fd_modify(gc, &ev->efd, events); in qmp_ev_ensure_reading_writing()
1193 static void qmp_ev_set_state(libxl__gc *gc, libxl__ev_qmp *ev, in qmp_ev_set_state() argument
1201 assert(ev->state == qmp_state_disconnected); in qmp_ev_set_state()
1204 assert(ev->state == qmp_state_waiting_lock); in qmp_ev_set_state()
1207 assert(ev->state == qmp_state_connecting); in qmp_ev_set_state()
1210 assert(ev->state == qmp_state_capability_negotiation || in qmp_ev_set_state()
1211 ev->state == qmp_state_connected); in qmp_ev_set_state()
1214 assert(ev->state == qmp_state_waiting_reply); in qmp_ev_set_state()
1218 ev->state = new_state; in qmp_ev_set_state()
1220 qmp_ev_ensure_reading_writing(gc, ev); in qmp_ev_set_state()
1223 static void qmp_ev_tx_buf_clear(libxl__ev_qmp *ev) in qmp_ev_tx_buf_clear() argument
1225 ev->tx_buf = NULL; in qmp_ev_tx_buf_clear()
1226 ev->tx_buf_len = 0; in qmp_ev_tx_buf_clear()
1227 ev->tx_buf_off = 0; in qmp_ev_tx_buf_clear()
1270 static int qmp_ev_connect(libxl__egc *egc, libxl__ev_qmp *ev) in qmp_ev_connect() argument
1279 libxl__ev_slowlock *lock = &ev->lock; in qmp_ev_connect()
1281 assert(ev->state == qmp_state_disconnected); in qmp_ev_connect()
1285 ev->cfd = libxl__carefd_opened(CTX, fd); in qmp_ev_connect()
1286 if (!ev->cfd) { in qmp_ev_connect()
1287 LOGED(ERROR, ev->domid, "socket() failed"); in qmp_ev_connect()
1291 rc = libxl_fd_set_nonblock(CTX, libxl__carefd_fd(ev->cfd), 1); in qmp_ev_connect()
1295 qmp_ev_set_state(gc, ev, qmp_state_waiting_lock); in qmp_ev_connect()
1297 lock->ao = ev->ao; in qmp_ev_connect()
1298 lock->domid = ev->domid; in qmp_ev_connect()
1300 libxl__ev_slowlock_lock(egc, &ev->lock); in qmp_ev_connect()
1313 libxl__ev_qmp *ev = CONTAINER_OF(lock, *ev, lock); in qmp_ev_lock_aquired() local
1321 qmp_socket_path = libxl__qemu_qmp_path(gc, ev->domid); in qmp_ev_lock_aquired()
1323 LOGD(DEBUG, ev->domid, "Connecting to %s", qmp_socket_path); in qmp_ev_lock_aquired()
1330 r = connect(libxl__carefd_fd(ev->cfd), in qmp_ev_lock_aquired()
1333 LOGED(ERROR, ev->domid, "Failed to connect to QMP socket %s", in qmp_ev_lock_aquired()
1339 rc = libxl__ev_fd_register(gc, &ev->efd, qmp_ev_fd_callback, in qmp_ev_lock_aquired()
1340 libxl__carefd_fd(ev->cfd), POLLIN); in qmp_ev_lock_aquired()
1344 qmp_ev_set_state(gc, ev, qmp_state_connecting); in qmp_ev_lock_aquired()
1355 ev->rc = rc; in qmp_ev_lock_aquired()
1356 ev->ei.callback = lock_error_callback; in qmp_ev_lock_aquired()
1357 libxl__ev_immediate_register(egc, &ev->ei); in qmp_ev_lock_aquired()
1364 libxl__ev_qmp *ev = CONTAINER_OF(ei, *ev, ei); in lock_error_callback() local
1366 int rc = ev->rc; in lock_error_callback()
1369 libxl__ev_qmp_dispose(gc, ev); in lock_error_callback()
1372 ev->callback(egc, ev, NULL, rc); /* must be last */ in lock_error_callback()
1384 libxl__ev_qmp *ev = CONTAINER_OF(ev_fd, *ev, efd); in qmp_ev_fd_callback() local
1385 STATE_AO_GC(ev->ao); in qmp_ev_fd_callback()
1395 LOGED(ERROR, ev->domid, "getsockopt failed"); in qmp_ev_fd_callback()
1398 LOGED(ERROR, ev->domid, "error on QMP socket"); in qmp_ev_fd_callback()
1400 LOGD(ERROR, ev->domid, in qmp_ev_fd_callback()
1408 LOGD(ERROR, ev->domid, in qmp_ev_fd_callback()
1417 rc = qmp_ev_callback_writable(gc, ev, fd); in qmp_ev_fd_callback()
1423 rc = qmp_ev_callback_readable(egc, ev, fd); in qmp_ev_fd_callback()
1437 LOGD(ERROR, ev->domid, in qmp_ev_fd_callback()
1441 libxl__ev_qmp_dispose(gc, ev); in qmp_ev_fd_callback()
1444 ev->callback(egc, ev, NULL, rc); /* must be last */ in qmp_ev_fd_callback()
1448 libxl__ev_qmp *ev, int fd) in qmp_ev_callback_writable() argument
1458 if (ev->state == qmp_state_waiting_reply) { in qmp_ev_callback_writable()
1459 if (ev->msg) { in qmp_ev_callback_writable()
1460 assert(!ev->tx_buf); in qmp_ev_callback_writable()
1461 ev->tx_buf = ev->msg; in qmp_ev_callback_writable()
1462 ev->tx_buf_len = strlen(ev->msg); in qmp_ev_callback_writable()
1463 ev->tx_buf_off = 0; in qmp_ev_callback_writable()
1464 ev->id = ev->msg_id; in qmp_ev_callback_writable()
1465 ev->msg = NULL; in qmp_ev_callback_writable()
1466 ev->msg_id = 0; in qmp_ev_callback_writable()
1470 assert(ev->tx_buf); in qmp_ev_callback_writable()
1472 LOG_QMP("sending: '%.*s'", (int)ev->tx_buf_len, ev->tx_buf); in qmp_ev_callback_writable()
1478 if (ev->state == qmp_state_waiting_reply && in qmp_ev_callback_writable()
1479 ev->payload_fd >= 0 && in qmp_ev_callback_writable()
1480 ev->tx_buf_off == 0) { in qmp_ev_callback_writable()
1482 rc = libxl__sendmsg_fds(gc, fd, ev->tx_buf[ev->tx_buf_off], in qmp_ev_callback_writable()
1483 1, &ev->payload_fd, "QMP socket"); in qmp_ev_callback_writable()
1489 ev->tx_buf_off++; in qmp_ev_callback_writable()
1492 while (ev->tx_buf_off < ev->tx_buf_len) { in qmp_ev_callback_writable()
1493 ssize_t max_write = ev->tx_buf_len - ev->tx_buf_off; in qmp_ev_callback_writable()
1494 r = write(fd, ev->tx_buf + ev->tx_buf_off, max_write); in qmp_ev_callback_writable()
1500 LOGED(ERROR, ev->domid, "failed to write to QMP socket"); in qmp_ev_callback_writable()
1504 ev->tx_buf_off += r; in qmp_ev_callback_writable()
1507 if (ev->tx_buf_off == ev->tx_buf_len) in qmp_ev_callback_writable()
1508 qmp_ev_tx_buf_clear(ev); in qmp_ev_callback_writable()
1510 qmp_ev_ensure_reading_writing(gc, ev); in qmp_ev_callback_writable()
1516 libxl__ev_qmp *ev, int fd) in qmp_ev_callback_readable() argument
1532 STATE_AO_GC(ev->ao); in qmp_ev_callback_readable()
1541 rc = qmp_ev_get_next_msg(egc, ev, &o); in qmp_ev_callback_readable()
1548 rc = qmp_ev_handle_message(egc, ev, o); in qmp_ev_callback_readable()
1555 if (ev->rx_buf_size - ev->rx_buf_used < QMP_RECEIVE_BUFFER_SIZE) { in qmp_ev_callback_readable()
1556 size_t newsize = ev->rx_buf_size * 2 + QMP_RECEIVE_BUFFER_SIZE; in qmp_ev_callback_readable()
1559 LOGD(ERROR, ev->domid, in qmp_ev_callback_readable()
1564 ev->rx_buf_size = newsize; in qmp_ev_callback_readable()
1565 ev->rx_buf = libxl__realloc(gc, ev->rx_buf, ev->rx_buf_size); in qmp_ev_callback_readable()
1568 r = read(fd, ev->rx_buf + ev->rx_buf_used, in qmp_ev_callback_readable()
1569 ev->rx_buf_size - ev->rx_buf_used); in qmp_ev_callback_readable()
1575 LOGED(ERROR, ev->domid, "error reading QMP socket"); in qmp_ev_callback_readable()
1580 LOGD(ERROR, ev->domid, "Unexpected EOF on QMP socket"); in qmp_ev_callback_readable()
1585 (int)r, ev->rx_buf + ev->rx_buf_used); in qmp_ev_callback_readable()
1587 ev->rx_buf_used += r; in qmp_ev_callback_readable()
1588 assert(ev->rx_buf_used <= ev->rx_buf_size); in qmp_ev_callback_readable()
1596 static int qmp_ev_get_next_msg(libxl__egc *egc, libxl__ev_qmp *ev, in qmp_ev_get_next_msg() argument
1604 STATE_AO_GC(ev->ao); in qmp_ev_get_next_msg()
1611 if (!ev->rx_buf_used) in qmp_ev_get_next_msg()
1615 end = memmem(ev->rx_buf, ev->rx_buf_used, eom, eoml); in qmp_ev_get_next_msg()
1618 len = (end - ev->rx_buf) + eoml; in qmp_ev_get_next_msg()
1620 LOG_QMP("parsing %luB: '%.*s'", len, (int)len, ev->rx_buf); in qmp_ev_get_next_msg()
1623 ev->rx_buf[len - eoml] = '\0'; in qmp_ev_get_next_msg()
1624 o = libxl__json_parse(gc, ev->rx_buf); in qmp_ev_get_next_msg()
1627 LOGD(ERROR, ev->domid, "Parse error"); in qmp_ev_get_next_msg()
1631 ev->rx_buf_used -= len; in qmp_ev_get_next_msg()
1632 memmove(ev->rx_buf, ev->rx_buf + len, ev->rx_buf_used); in qmp_ev_get_next_msg()
1642 libxl__ev_qmp *ev,
1646 libxl__ev_qmp *ev, in qmp_ev_handle_message() argument
1664 STATE_AO_GC(ev->ao); in qmp_ev_handle_message()
1676 if (ev->state != qmp_state_connecting) { in qmp_ev_handle_message()
1677 LOGD(ERROR, ev->domid, in qmp_ev_handle_message()
1691 ev->qemu_version.level = libxl__json_object_get_integer( \ in qmp_ev_handle_message()
1698 LOGD(DEBUG, ev->domid, "QEMU version: %d.%d.%d", in qmp_ev_handle_message()
1699 ev->qemu_version.major, in qmp_ev_handle_message()
1700 ev->qemu_version.minor, in qmp_ev_handle_message()
1701 ev->qemu_version.micro); in qmp_ev_handle_message()
1704 assert(!ev->tx_buf); in qmp_ev_handle_message()
1705 ev->id = ev->next_id++; in qmp_ev_handle_message()
1706 buf = qmp_prepare_cmd(gc, "qmp_capabilities", NULL, ev->id); in qmp_ev_handle_message()
1708 LOGD(ERROR, ev->domid, in qmp_ev_handle_message()
1712 ev->tx_buf = buf; in qmp_ev_handle_message()
1713 ev->tx_buf_len = strlen(buf); in qmp_ev_handle_message()
1714 ev->tx_buf_off = 0; in qmp_ev_handle_message()
1715 qmp_ev_set_state(gc, ev, qmp_state_capability_negotiation); in qmp_ev_handle_message()
1742 qmp_ev_parse_error_messages(egc, ev, resp); in qmp_ev_handle_message()
1748 if (id != ev->id) { in qmp_ev_handle_message()
1749 LOGD(ERROR, ev->domid, in qmp_ev_handle_message()
1755 switch (ev->state) { in qmp_ev_handle_message()
1758 LOGD(ERROR, ev->domid, in qmp_ev_handle_message()
1763 qmp_ev_set_state(gc, ev, qmp_state_waiting_reply); in qmp_ev_handle_message()
1772 rc = qmp_ev_parse_error_messages(egc, ev, resp); in qmp_ev_handle_message()
1774 qmp_ev_set_state(gc, ev, qmp_state_connected); in qmp_ev_handle_message()
1775 ev->callback(egc, ev, response, rc); /* must be last */ in qmp_ev_handle_message()
1778 LOGD(ERROR, ev->domid, "Unexpected message: %s", JSON(resp)); in qmp_ev_handle_message()
1788 LOGD(ERROR, ev->domid, "Unexpected message received: %s", in qmp_ev_handle_message()
1800 libxl__ev_qmp *ev, in qmp_ev_parse_error_messages() argument
1804 STATE_AO_GC(ev->ao); in qmp_ev_parse_error_messages()
1818 LOGD(ERROR, ev->domid, in qmp_ev_parse_error_messages()
1830 LOGD(ERROR, ev->domid, in qmp_ev_parse_error_messages()
1836 LOGD(ERROR, ev->domid, "%s", s); in qmp_ev_parse_error_messages()
1838 LOGD(ERROR, ev->domid, "Received unexpected error: %s", in qmp_ev_parse_error_messages()
1847 void libxl__ev_qmp_init(libxl__ev_qmp *ev) in libxl__ev_qmp_init() argument
1852 ev->next_id = 0x786c7100; in libxl__ev_qmp_init()
1854 ev->cfd = NULL; in libxl__ev_qmp_init()
1855 libxl__ev_fd_init(&ev->efd); in libxl__ev_qmp_init()
1856 ev->state = qmp_state_disconnected; in libxl__ev_qmp_init()
1857 ev->id = 0; in libxl__ev_qmp_init()
1859 ev->rx_buf = NULL; in libxl__ev_qmp_init()
1860 ev->rx_buf_size = ev->rx_buf_used = 0; in libxl__ev_qmp_init()
1861 qmp_ev_tx_buf_clear(ev); in libxl__ev_qmp_init()
1863 ev->msg = NULL; in libxl__ev_qmp_init()
1864 ev->msg_id = 0; in libxl__ev_qmp_init()
1866 ev->qemu_version.major = -1; in libxl__ev_qmp_init()
1867 ev->qemu_version.minor = -1; in libxl__ev_qmp_init()
1868 ev->qemu_version.micro = -1; in libxl__ev_qmp_init()
1870 libxl__ev_qmplock_init(&ev->lock); in libxl__ev_qmp_init()
1871 ev->rc = 0; in libxl__ev_qmp_init()
1874 int libxl__ev_qmp_send(libxl__egc *egc, libxl__ev_qmp *ev, in libxl__ev_qmp_send() argument
1880 STATE_AO_GC(ev->ao); in libxl__ev_qmp_send()
1883 LOGD(DEBUG, ev->domid, " ev %p, cmd '%s'", ev, cmd); in libxl__ev_qmp_send()
1885 assert(ev->state == qmp_state_disconnected || in libxl__ev_qmp_send()
1886 ev->state == qmp_state_connected); in libxl__ev_qmp_send()
1890 if (ev->state == qmp_state_disconnected) { in libxl__ev_qmp_send()
1891 rc = qmp_ev_connect(egc, ev); in libxl__ev_qmp_send()
1897 ev->msg_id = ev->next_id++; in libxl__ev_qmp_send()
1898 ev->msg = qmp_prepare_cmd(gc, cmd, args, ev->msg_id); in libxl__ev_qmp_send()
1899 if (!ev->msg) { in libxl__ev_qmp_send()
1900 LOGD(ERROR, ev->domid, "Failed to generate caller's command %s", in libxl__ev_qmp_send()
1905 if (ev->state == qmp_state_connected) { in libxl__ev_qmp_send()
1906 qmp_ev_set_state(gc, ev, qmp_state_waiting_reply); in libxl__ev_qmp_send()
1912 libxl__ev_qmp_dispose(gc, ev); in libxl__ev_qmp_send()
1916 void libxl__ev_qmp_dispose(libxl__gc *gc, libxl__ev_qmp *ev) in libxl__ev_qmp_dispose() argument
1919 LOGD(DEBUG, ev->domid, " ev %p", ev); in libxl__ev_qmp_dispose()
1921 libxl__ev_fd_deregister(gc, &ev->efd); in libxl__ev_qmp_dispose()
1922 libxl__carefd_close(ev->cfd); in libxl__ev_qmp_dispose()
1923 libxl__ev_slowlock_dispose(gc, &ev->lock); in libxl__ev_qmp_dispose()
1925 libxl__ev_qmp_init(ev); in libxl__ev_qmp_dispose()