xref: /openbmc/qemu/migration/cpr-transfer.c (revision 9736ee382e95ead06a838fe0b0498e0cb3845270)
1*b3698869SSteve Sistare /*
2*b3698869SSteve Sistare  * Copyright (c) 2022, 2024 Oracle and/or its affiliates.
3*b3698869SSteve Sistare  *
4*b3698869SSteve Sistare  * This work is licensed under the terms of the GNU GPL, version 2 or later.
5*b3698869SSteve Sistare  * See the COPYING file in the top-level directory.
6*b3698869SSteve Sistare  */
7*b3698869SSteve Sistare 
8*b3698869SSteve Sistare #include "qemu/osdep.h"
9*b3698869SSteve Sistare #include "qapi/error.h"
10*b3698869SSteve Sistare #include "io/channel-file.h"
11*b3698869SSteve Sistare #include "io/channel-socket.h"
12*b3698869SSteve Sistare #include "io/net-listener.h"
13*b3698869SSteve Sistare #include "migration/cpr.h"
14*b3698869SSteve Sistare #include "migration/migration.h"
15*b3698869SSteve Sistare #include "migration/savevm.h"
16*b3698869SSteve Sistare #include "migration/qemu-file.h"
17*b3698869SSteve Sistare #include "migration/vmstate.h"
18*b3698869SSteve Sistare #include "trace.h"
19*b3698869SSteve Sistare 
cpr_transfer_output(MigrationChannel * channel,Error ** errp)20*b3698869SSteve Sistare QEMUFile *cpr_transfer_output(MigrationChannel *channel, Error **errp)
21*b3698869SSteve Sistare {
22*b3698869SSteve Sistare     MigrationAddress *addr = channel->addr;
23*b3698869SSteve Sistare 
24*b3698869SSteve Sistare     if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET &&
25*b3698869SSteve Sistare         addr->u.socket.type == SOCKET_ADDRESS_TYPE_UNIX) {
26*b3698869SSteve Sistare 
27*b3698869SSteve Sistare         g_autoptr(QIOChannelSocket) sioc = qio_channel_socket_new();
28*b3698869SSteve Sistare         QIOChannel *ioc = QIO_CHANNEL(sioc);
29*b3698869SSteve Sistare         SocketAddress *saddr = &addr->u.socket;
30*b3698869SSteve Sistare 
31*b3698869SSteve Sistare         if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) {
32*b3698869SSteve Sistare             return NULL;
33*b3698869SSteve Sistare         }
34*b3698869SSteve Sistare         trace_cpr_transfer_output(addr->u.socket.u.q_unix.path);
35*b3698869SSteve Sistare         qio_channel_set_name(ioc, "cpr-out");
36*b3698869SSteve Sistare         return qemu_file_new_output(ioc);
37*b3698869SSteve Sistare 
38*b3698869SSteve Sistare     } else {
39*b3698869SSteve Sistare         error_setg(errp, "bad cpr channel address; must be unix");
40*b3698869SSteve Sistare         return NULL;
41*b3698869SSteve Sistare     }
42*b3698869SSteve Sistare }
43*b3698869SSteve Sistare 
cpr_transfer_input(MigrationChannel * channel,Error ** errp)44*b3698869SSteve Sistare QEMUFile *cpr_transfer_input(MigrationChannel *channel, Error **errp)
45*b3698869SSteve Sistare {
46*b3698869SSteve Sistare     MigrationAddress *addr = channel->addr;
47*b3698869SSteve Sistare 
48*b3698869SSteve Sistare     if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET &&
49*b3698869SSteve Sistare         addr->u.socket.type == SOCKET_ADDRESS_TYPE_UNIX) {
50*b3698869SSteve Sistare 
51*b3698869SSteve Sistare         g_autoptr(QIOChannelSocket) sioc = NULL;
52*b3698869SSteve Sistare         SocketAddress *saddr = &addr->u.socket;
53*b3698869SSteve Sistare         g_autoptr(QIONetListener) listener = qio_net_listener_new();
54*b3698869SSteve Sistare         QIOChannel *ioc;
55*b3698869SSteve Sistare 
56*b3698869SSteve Sistare         qio_net_listener_set_name(listener, "cpr-socket-listener");
57*b3698869SSteve Sistare         if (qio_net_listener_open_sync(listener, saddr, 1, errp) < 0) {
58*b3698869SSteve Sistare             return NULL;
59*b3698869SSteve Sistare         }
60*b3698869SSteve Sistare 
61*b3698869SSteve Sistare         sioc = qio_net_listener_wait_client(listener);
62*b3698869SSteve Sistare         ioc = QIO_CHANNEL(sioc);
63*b3698869SSteve Sistare         trace_cpr_transfer_input(addr->u.socket.u.q_unix.path);
64*b3698869SSteve Sistare         qio_channel_set_name(ioc, "cpr-in");
65*b3698869SSteve Sistare         return qemu_file_new_input(ioc);
66*b3698869SSteve Sistare 
67*b3698869SSteve Sistare     } else {
68*b3698869SSteve Sistare         error_setg(errp, "bad cpr channel socket type; must be unix");
69*b3698869SSteve Sistare         return NULL;
70*b3698869SSteve Sistare     }
71*b3698869SSteve Sistare }
72