From: Mark Kanda <mark.ka...@oracle.com> Iterate through the character devices and save/restore the socket fds.
Signed-off-by: Mark Kanda <mark.ka...@oracle.com> Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- chardev/char-socket.c | 35 +++++++++++++++++++++++++++++++++++ chardev/char.c | 14 ++++++++++++++ include/chardev/char.h | 5 +++++ include/sysemu/sysemu.h | 1 + migration/savevm.c | 8 ++++++++ 5 files changed, 63 insertions(+) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index ef62dbf..e08e7e1 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -36,6 +36,8 @@ #include "qapi/qapi-visit-sockets.h" #include "chardev/char-io.h" +#include "sysemu/sysemu.h" +#include "qemu/cutils.h" /***********************************************************/ /* TCP Net console */ @@ -400,6 +402,7 @@ static void tcp_chr_free_connection(Chardev *chr) SocketChardev *s = SOCKET_CHARDEV(chr); int i; + unsetenv_fd(chr->label); if (s->read_msgfds_num) { for (i = 0; i < s->read_msgfds_num; i++) { close(s->read_msgfds[i]); @@ -1375,6 +1378,9 @@ static void qmp_chardev_open_socket(Chardev *chr, return; } } + + load_char_socket_fd(chr); + } static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, @@ -1517,3 +1523,32 @@ static void register_types(void) } type_init(register_types); + +void save_char_socket_fd(Chardev *chr) +{ + SocketChardev *sockchar = SOCKET_CHARDEV(chr); + + if (sockchar->sioc) { + setenv_fd(chr->label, sockchar->sioc->fd); + } +} + +void load_char_socket_fd(Chardev *chr) +{ + SocketChardev *sockchar; + QIOChannelSocket *sioc; + + int fd = getenv_fd(chr->label); + + if (fd != -1) { + unsetenv_fd(chr->label); + sockchar = SOCKET_CHARDEV(chr); + sioc = qio_channel_socket_accept(*sockchar->listener->sioc, fd, NULL); + if (sioc) { + tcp_chr_accept(sockchar->listener, sioc, chr); + } else { + error_printf("error: could not restore socket for %s\n", + chr->label); + } + } +} diff --git a/chardev/char.c b/chardev/char.c index 77e7ec8..8fd54cc 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -34,6 +34,7 @@ #include "qapi/qapi-commands-char.h" #include "qapi/qmp/qerror.h" #include "sysemu/replay.h" +#include "sysemu/sysemu.h" #include "qemu/help_option.h" #include "qemu/module.h" #include "qemu/option.h" @@ -1174,3 +1175,16 @@ static void register_types(void) } type_init(register_types); + +static int chardev_is_socket(Object *child, void *opaque) +{ + if (CHARDEV_IS_SOCKET(child)) { + save_char_socket_fd((Chardev *) child); + } + return 0; +} + +void save_chardev_fds(void) +{ + object_child_foreach(get_chardevs_root(), chardev_is_socket, NULL); +} diff --git a/include/chardev/char.h b/include/chardev/char.h index 00589a6..80a9cf8 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -250,6 +250,8 @@ int qemu_chr_wait_connected(Chardev *chr, Error **errp); object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_RINGBUF) #define CHARDEV_IS_PTY(chr) \ object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_PTY) +#define CHARDEV_IS_SOCKET(chr) \ + object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_SOCKET) typedef struct ChardevClass { ObjectClass parent_class; @@ -290,4 +292,7 @@ GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms, /* console.c */ void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp); +void save_char_socket_fd(Chardev *); +void load_char_socket_fd(Chardev *); + #endif diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 4dfc4ca..fa1a5c3 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -27,6 +27,7 @@ void qemu_remove_machine_init_done_notifier(Notifier *notify); void save_cpr_snapshot(const char *file, const char *mode, Error **errp); void load_cpr_snapshot(const char *file, Error **errp); +void save_chardev_fds(void); extern int autostart; diff --git a/migration/savevm.c b/migration/savevm.c index 2902006..81f38c4 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2700,6 +2700,12 @@ static QEMUFile *qf_file_open(const char *filename, int flags, int mode, return qemu_fopen_channel_input(ioc); } +static int preserve_fd(const char *name, const char *val, void *handle) +{ + qemu_clr_cloexec(atoi(val)); + return 0; +} + void save_cpr_snapshot(const char *file, const char *mode, Error **errp) { int ret = 0; @@ -2761,6 +2767,8 @@ void save_cpr_snapshot(const char *file, const char *mode, Error **errp) if (qemu_preserve_ram(errp)) { return; } + save_chardev_fds(); + walkenv(FD_PREFIX, preserve_fd, 0); qemu_system_exec_request(); putenv((char *)"QEMU_START_FREEZE="); } -- 1.8.3.1