mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
tests/qtest/migration: Rename migration-helpers.c
Rename migration-helpers.c to migration-util.c to make its purpose more explicit and avoid the "helper" terminology. Move the file to the qtest/migration/ directory along with the rest of the migration files. Signed-off-by: Fabiano Rosas <farosas@suse.de>
This commit is contained in:
parent
e6c5704043
commit
b7d7f723a9
7 changed files with 12 additions and 10 deletions
|
@ -1,285 +0,0 @@
|
|||
/*
|
||||
* QTest migration helpers
|
||||
*
|
||||
* Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
|
||||
* based on the vhost-user-test.c that is:
|
||||
* Copyright (c) 2014 Virtual Open Systems Sarl.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/ctype.h"
|
||||
#include "qapi/qapi-visit-sockets.h"
|
||||
#include "qapi/qobject-input-visitor.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qlist.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/memalign.h"
|
||||
|
||||
#include "migration-helpers.h"
|
||||
#include "migration/bootfile.h"
|
||||
|
||||
static char *SocketAddress_to_str(SocketAddress *addr)
|
||||
{
|
||||
switch (addr->type) {
|
||||
case SOCKET_ADDRESS_TYPE_INET:
|
||||
return g_strdup_printf("tcp:%s:%s",
|
||||
addr->u.inet.host,
|
||||
addr->u.inet.port);
|
||||
case SOCKET_ADDRESS_TYPE_UNIX:
|
||||
return g_strdup_printf("unix:%s",
|
||||
addr->u.q_unix.path);
|
||||
case SOCKET_ADDRESS_TYPE_FD:
|
||||
return g_strdup_printf("fd:%s", addr->u.fd.str);
|
||||
case SOCKET_ADDRESS_TYPE_VSOCK:
|
||||
return g_strdup_printf("vsock:%s:%s",
|
||||
addr->u.vsock.cid,
|
||||
addr->u.vsock.port);
|
||||
default:
|
||||
return g_strdup("unknown address type");
|
||||
}
|
||||
}
|
||||
|
||||
static QDict *SocketAddress_to_qdict(SocketAddress *addr)
|
||||
{
|
||||
QDict *dict = qdict_new();
|
||||
|
||||
switch (addr->type) {
|
||||
case SOCKET_ADDRESS_TYPE_INET:
|
||||
qdict_put_str(dict, "type", "inet");
|
||||
qdict_put_str(dict, "host", addr->u.inet.host);
|
||||
qdict_put_str(dict, "port", addr->u.inet.port);
|
||||
break;
|
||||
case SOCKET_ADDRESS_TYPE_UNIX:
|
||||
qdict_put_str(dict, "type", "unix");
|
||||
qdict_put_str(dict, "path", addr->u.q_unix.path);
|
||||
break;
|
||||
case SOCKET_ADDRESS_TYPE_FD:
|
||||
qdict_put_str(dict, "type", "fd");
|
||||
qdict_put_str(dict, "str", addr->u.fd.str);
|
||||
break;
|
||||
case SOCKET_ADDRESS_TYPE_VSOCK:
|
||||
qdict_put_str(dict, "type", "vsock");
|
||||
qdict_put_str(dict, "cid", addr->u.vsock.cid);
|
||||
qdict_put_str(dict, "port", addr->u.vsock.port);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
static SocketAddressList *migrate_get_socket_address(QTestState *who)
|
||||
{
|
||||
QDict *rsp;
|
||||
SocketAddressList *addrs;
|
||||
Visitor *iv = NULL;
|
||||
QObject *object;
|
||||
|
||||
rsp = migrate_query(who);
|
||||
object = qdict_get(rsp, "socket-address");
|
||||
|
||||
iv = qobject_input_visitor_new(object);
|
||||
visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort);
|
||||
visit_free(iv);
|
||||
|
||||
qobject_unref(rsp);
|
||||
return addrs;
|
||||
}
|
||||
|
||||
char *migrate_get_connect_uri(QTestState *who)
|
||||
{
|
||||
SocketAddressList *addrs;
|
||||
char *connect_uri;
|
||||
|
||||
addrs = migrate_get_socket_address(who);
|
||||
connect_uri = SocketAddress_to_str(addrs->value);
|
||||
|
||||
qapi_free_SocketAddressList(addrs);
|
||||
return connect_uri;
|
||||
}
|
||||
|
||||
static QDict *
|
||||
migrate_get_connect_qdict(QTestState *who)
|
||||
{
|
||||
SocketAddressList *addrs;
|
||||
QDict *connect_qdict;
|
||||
|
||||
addrs = migrate_get_socket_address(who);
|
||||
connect_qdict = SocketAddress_to_qdict(addrs->value);
|
||||
|
||||
qapi_free_SocketAddressList(addrs);
|
||||
return connect_qdict;
|
||||
}
|
||||
|
||||
void migrate_set_ports(QTestState *to, QList *channel_list)
|
||||
{
|
||||
QDict *addr;
|
||||
QListEntry *entry;
|
||||
const char *addr_port = NULL;
|
||||
|
||||
addr = migrate_get_connect_qdict(to);
|
||||
|
||||
QLIST_FOREACH_ENTRY(channel_list, entry) {
|
||||
QDict *channel = qobject_to(QDict, qlist_entry_obj(entry));
|
||||
QDict *addrdict = qdict_get_qdict(channel, "addr");
|
||||
|
||||
if (qdict_haskey(addrdict, "port") &&
|
||||
qdict_haskey(addr, "port") &&
|
||||
(strcmp(qdict_get_str(addrdict, "port"), "0") == 0)) {
|
||||
addr_port = qdict_get_str(addr, "port");
|
||||
qdict_put_str(addrdict, "port", addr_port);
|
||||
}
|
||||
}
|
||||
|
||||
qobject_unref(addr);
|
||||
}
|
||||
|
||||
bool migrate_watch_for_events(QTestState *who, const char *name,
|
||||
QDict *event, void *opaque)
|
||||
{
|
||||
QTestMigrationState *state = opaque;
|
||||
|
||||
if (g_str_equal(name, "STOP")) {
|
||||
state->stop_seen = true;
|
||||
return true;
|
||||
} else if (g_str_equal(name, "SUSPEND")) {
|
||||
state->suspend_seen = true;
|
||||
return true;
|
||||
} else if (g_str_equal(name, "RESUME")) {
|
||||
state->resume_seen = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char *find_common_machine_version(const char *mtype, const char *var1,
|
||||
const char *var2)
|
||||
{
|
||||
g_autofree char *type1 = qtest_resolve_machine_alias(var1, mtype);
|
||||
g_autofree char *type2 = qtest_resolve_machine_alias(var2, mtype);
|
||||
|
||||
g_assert(type1 && type2);
|
||||
|
||||
if (g_str_equal(type1, type2)) {
|
||||
/* either can be used */
|
||||
return g_strdup(type1);
|
||||
}
|
||||
|
||||
if (qtest_has_machine_with_env(var2, type1)) {
|
||||
return g_strdup(type1);
|
||||
}
|
||||
|
||||
if (qtest_has_machine_with_env(var1, type2)) {
|
||||
return g_strdup(type2);
|
||||
}
|
||||
|
||||
g_test_message("No common machine version for machine type '%s' between "
|
||||
"binaries %s and %s", mtype, getenv(var1), getenv(var2));
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
char *resolve_machine_version(const char *alias, const char *var1,
|
||||
const char *var2)
|
||||
{
|
||||
const char *mname = g_getenv("QTEST_QEMU_MACHINE_TYPE");
|
||||
g_autofree char *machine_name = NULL;
|
||||
|
||||
if (mname) {
|
||||
const char *dash = strrchr(mname, '-');
|
||||
const char *dot = strrchr(mname, '.');
|
||||
|
||||
machine_name = g_strdup(mname);
|
||||
|
||||
if (dash && dot) {
|
||||
assert(qtest_has_machine(machine_name));
|
||||
return g_steal_pointer(&machine_name);
|
||||
}
|
||||
/* else: probably an alias, let it be resolved below */
|
||||
} else {
|
||||
/* use the hardcoded alias */
|
||||
machine_name = g_strdup(alias);
|
||||
}
|
||||
|
||||
return find_common_machine_version(machine_name, var1, var2);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
void (*func)(void);
|
||||
} MigrationTest;
|
||||
|
||||
static void migration_test_destroy(gpointer data)
|
||||
{
|
||||
MigrationTest *test = (MigrationTest *)data;
|
||||
|
||||
g_free(test->name);
|
||||
g_free(test);
|
||||
}
|
||||
|
||||
static void migration_test_wrapper(const void *data)
|
||||
{
|
||||
MigrationTest *test = (MigrationTest *)data;
|
||||
|
||||
g_test_message("Running /%s%s", qtest_get_arch(), test->name);
|
||||
test->func();
|
||||
}
|
||||
|
||||
void migration_test_add(const char *path, void (*fn)(void))
|
||||
{
|
||||
MigrationTest *test = g_new0(MigrationTest, 1);
|
||||
|
||||
test->func = fn;
|
||||
test->name = g_strdup(path);
|
||||
|
||||
qtest_add_data_func_full(path, test, migration_test_wrapper,
|
||||
migration_test_destroy);
|
||||
}
|
||||
|
||||
#ifdef O_DIRECT
|
||||
/*
|
||||
* Probe for O_DIRECT support on the filesystem. Since this is used
|
||||
* for tests, be conservative, if anything fails, assume it's
|
||||
* unsupported.
|
||||
*/
|
||||
bool probe_o_direct_support(const char *tmpfs)
|
||||
{
|
||||
g_autofree char *filename = g_strdup_printf("%s/probe-o-direct", tmpfs);
|
||||
int fd, flags = O_CREAT | O_RDWR | O_TRUNC | O_DIRECT;
|
||||
void *buf;
|
||||
ssize_t ret, len;
|
||||
uint64_t offset;
|
||||
|
||||
fd = open(filename, flags, 0660);
|
||||
if (fd < 0) {
|
||||
unlink(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using 1MB alignment as conservative choice to satisfy any
|
||||
* plausible architecture default page size, and/or filesystem
|
||||
* alignment restrictions.
|
||||
*/
|
||||
len = 0x100000;
|
||||
offset = 0x100000;
|
||||
|
||||
buf = qemu_try_memalign(len, len);
|
||||
g_assert(buf);
|
||||
|
||||
ret = pwrite(fd, buf, len, offset);
|
||||
unlink(filename);
|
||||
g_free(buf);
|
||||
|
||||
if (ret < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue