2 * Copyright (c) 2021-2023 Oracle and/or its affiliates.
4 * This work is licensed under the terms of the GNU GPL, version 2 or later.
5 * See the COPYING file in the top-level directory.
8 #include "qemu/osdep.h"
9 #include "qemu/cutils.h"
10 #include "qapi/error.h"
13 #include "migration.h"
14 #include "io/channel-file.h"
15 #include "io/channel-util.h"
18 #define OFFSET_OPTION ",offset="
20 /* Remove the offset option from @filespec and return it in @offsetp. */
22 static int file_parse_offset(char *filespec
, uint64_t *offsetp
, Error
**errp
)
24 char *option
= strstr(filespec
, OFFSET_OPTION
);
29 option
+= sizeof(OFFSET_OPTION
) - 1;
30 ret
= qemu_strtosz(option
, NULL
, offsetp
);
32 error_setg_errno(errp
, -ret
, "file URI has bad offset %s", option
);
39 void file_start_outgoing_migration(MigrationState
*s
, const char *filespec
,
42 g_autofree
char *filename
= g_strdup(filespec
);
43 g_autoptr(QIOChannelFile
) fioc
= NULL
;
47 trace_migration_file_outgoing(filename
);
49 if (file_parse_offset(filename
, &offset
, errp
)) {
53 fioc
= qio_channel_file_new_path(filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
59 ioc
= QIO_CHANNEL(fioc
);
60 if (offset
&& qio_channel_io_seek(ioc
, offset
, SEEK_SET
, errp
) < 0) {
63 qio_channel_set_name(ioc
, "migration-file-outgoing");
64 migration_channel_connect(s
, ioc
, NULL
, NULL
);
67 static gboolean
file_accept_incoming_migration(QIOChannel
*ioc
,
68 GIOCondition condition
,
71 migration_channel_process_incoming(ioc
);
72 object_unref(OBJECT(ioc
));
73 return G_SOURCE_REMOVE
;
76 void file_start_incoming_migration(const char *filespec
, Error
**errp
)
78 g_autofree
char *filename
= g_strdup(filespec
);
79 QIOChannelFile
*fioc
= NULL
;
83 trace_migration_file_incoming(filename
);
85 if (file_parse_offset(filename
, &offset
, errp
)) {
89 fioc
= qio_channel_file_new_path(filename
, O_RDONLY
, 0, errp
);
94 ioc
= QIO_CHANNEL(fioc
);
95 if (offset
&& qio_channel_io_seek(ioc
, offset
, SEEK_SET
, errp
) < 0) {
98 qio_channel_set_name(QIO_CHANNEL(ioc
), "migration-file-incoming");
99 qio_channel_add_watch_full(ioc
, G_IO_IN
,
100 file_accept_incoming_migration
,
102 g_main_context_get_thread_default());