xref: /qemu/migration/fd.c (revision 1af7cba50c58efc207c368cbc8b61166889873b2)
15ac1fad3SPaolo Bonzini /*
25ac1fad3SPaolo Bonzini  * QEMU live migration via generic fd
35ac1fad3SPaolo Bonzini  *
464802ee5SDaniel P. Berrange  * Copyright Red Hat, Inc. 2009-2016
55ac1fad3SPaolo Bonzini  *
65ac1fad3SPaolo Bonzini  * Authors:
75ac1fad3SPaolo Bonzini  *  Chris Lalancette <clalance@redhat.com>
864802ee5SDaniel P. Berrange  *  Daniel P. Berrange <berrange@redhat.com>
95ac1fad3SPaolo Bonzini  *
105ac1fad3SPaolo Bonzini  * This work is licensed under the terms of the GNU GPL, version 2.  See
115ac1fad3SPaolo Bonzini  * the COPYING file in the top-level directory.
125ac1fad3SPaolo Bonzini  *
136b620ca3SPaolo Bonzini  * Contributions after 2012-01-13 are licensed under the terms of the
146b620ca3SPaolo Bonzini  * GNU GPL, version 2 or (at your option) any later version.
155ac1fad3SPaolo Bonzini  */
165ac1fad3SPaolo Bonzini 
171393a485SPeter Maydell #include "qemu/osdep.h"
18dd4339c5SJuan Quintela #include "channel.h"
197fcac4a2SJuan Quintela #include "fd.h"
2074228c59SFabiano Rosas #include "file.h"
210efc9142SJuan Quintela #include "migration.h"
2283c9089eSPaolo Bonzini #include "monitor/monitor.h"
23c55deb86SFabiano Rosas #include "qemu/error-report.h"
24c55deb86SFabiano Rosas #include "qemu/sockets.h"
2564802ee5SDaniel P. Berrange #include "io/channel-util.h"
2664802ee5SDaniel P. Berrange #include "trace.h"
275ac1fad3SPaolo Bonzini 
fd_is_pipe(int fd)28*87ae45e6SPeter Xu static bool fd_is_pipe(int fd)
29*87ae45e6SPeter Xu {
30*87ae45e6SPeter Xu     struct stat statbuf;
31*87ae45e6SPeter Xu 
32*87ae45e6SPeter Xu     if (fstat(fd, &statbuf) == -1) {
33*87ae45e6SPeter Xu         return false;
34*87ae45e6SPeter Xu     }
35*87ae45e6SPeter Xu 
36*87ae45e6SPeter Xu     return S_ISFIFO(statbuf.st_mode);
37*87ae45e6SPeter Xu }
38*87ae45e6SPeter Xu 
migration_fd_valid(int fd)39*87ae45e6SPeter Xu static bool migration_fd_valid(int fd)
40*87ae45e6SPeter Xu {
41*87ae45e6SPeter Xu     if (fd_is_socket(fd)) {
42*87ae45e6SPeter Xu         return true;
43*87ae45e6SPeter Xu     }
44*87ae45e6SPeter Xu 
45*87ae45e6SPeter Xu     if (fd_is_pipe(fd)) {
46*87ae45e6SPeter Xu         return true;
47*87ae45e6SPeter Xu     }
48*87ae45e6SPeter Xu 
49*87ae45e6SPeter Xu     return false;
50*87ae45e6SPeter Xu }
51131fe9b8SCristian Klein 
fd_start_outgoing_migration(MigrationState * s,const char * fdname,Error ** errp)52f37afb5aSPaolo Bonzini void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
535ac1fad3SPaolo Bonzini {
5464802ee5SDaniel P. Berrange     QIOChannel *ioc;
55947e4744SKevin Wolf     int fd = monitor_get_fd(monitor_cur(), fdname, errp);
56f8bbc128SPaolo Bonzini     if (fd == -1) {
57f37afb5aSPaolo Bonzini         return;
585ac1fad3SPaolo Bonzini     }
59131fe9b8SCristian Klein 
60*87ae45e6SPeter Xu     if (!migration_fd_valid(fd)) {
61c55deb86SFabiano Rosas         warn_report("fd: migration to a file is deprecated."
62c55deb86SFabiano Rosas                     " Use file: instead.");
63c55deb86SFabiano Rosas     }
64c55deb86SFabiano Rosas 
6564802ee5SDaniel P. Berrange     trace_migration_fd_outgoing(fd);
6664802ee5SDaniel P. Berrange     ioc = qio_channel_new_fd(fd, errp);
6764802ee5SDaniel P. Berrange     if (!ioc) {
6864802ee5SDaniel P. Berrange         close(fd);
6964802ee5SDaniel P. Berrange         return;
70131fe9b8SCristian Klein     }
715ac1fad3SPaolo Bonzini 
727d5b0d68SPhilippe Mathieu-Daudé     qio_channel_set_name(ioc, "migration-fd-outgoing");
73688a3dcbSDr. David Alan Gilbert     migration_channel_connect(s, ioc, NULL, NULL);
7464802ee5SDaniel P. Berrange     object_unref(OBJECT(ioc));
755ac1fad3SPaolo Bonzini }
765ac1fad3SPaolo Bonzini 
fd_accept_incoming_migration(QIOChannel * ioc,GIOCondition condition,gpointer opaque)7764802ee5SDaniel P. Berrange static gboolean fd_accept_incoming_migration(QIOChannel *ioc,
7864802ee5SDaniel P. Berrange                                              GIOCondition condition,
7964802ee5SDaniel P. Berrange                                              gpointer opaque)
805ac1fad3SPaolo Bonzini {
8154314711SJuan Quintela     migration_channel_process_incoming(ioc);
8264802ee5SDaniel P. Berrange     object_unref(OBJECT(ioc));
832a543bfdSJuan Quintela     return G_SOURCE_REMOVE;
845ac1fad3SPaolo Bonzini }
855ac1fad3SPaolo Bonzini 
fd_start_incoming_migration(const char * fdname,Error ** errp)8661053d48SYury Kotov void fd_start_incoming_migration(const char *fdname, Error **errp)
875ac1fad3SPaolo Bonzini {
8864802ee5SDaniel P. Berrange     QIOChannel *ioc;
89947e4744SKevin Wolf     int fd = monitor_fd_param(monitor_cur(), fdname, errp);
9061053d48SYury Kotov     if (fd == -1) {
9161053d48SYury Kotov         return;
9261053d48SYury Kotov     }
935ac1fad3SPaolo Bonzini 
94*87ae45e6SPeter Xu     if (!migration_fd_valid(fd)) {
95c55deb86SFabiano Rosas         warn_report("fd: migration to a file is deprecated."
96c55deb86SFabiano Rosas                     " Use file: instead.");
97c55deb86SFabiano Rosas     }
98c55deb86SFabiano Rosas 
9964802ee5SDaniel P. Berrange     trace_migration_fd_incoming(fd);
10064802ee5SDaniel P. Berrange 
10164802ee5SDaniel P. Berrange     ioc = qio_channel_new_fd(fd, errp);
10264802ee5SDaniel P. Berrange     if (!ioc) {
10364802ee5SDaniel P. Berrange         close(fd);
10443eaae28SPaolo Bonzini         return;
1055ac1fad3SPaolo Bonzini     }
1065ac1fad3SPaolo Bonzini 
1077d5b0d68SPhilippe Mathieu-Daudé     qio_channel_set_name(ioc, "migration-fd-incoming");
108e89f5ff2SPeter Xu     qio_channel_add_watch_full(ioc, G_IO_IN,
10964802ee5SDaniel P. Berrange                                fd_accept_incoming_migration,
110e89f5ff2SPeter Xu                                NULL, NULL,
111e89f5ff2SPeter Xu                                g_main_context_get_thread_default());
112decdc767SFabiano Rosas }
113