1 /* 2 * QTest migration utilities 3 * 4 * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates 5 * based on the vhost-user-test.c that is: 6 * Copyright (c) 2014 Virtual Open Systems Sarl. 7 * 8 * This work is licensed under the terms of the GNU GPL, version 2 or later. 9 * See the COPYING file in the top-level directory. 10 * 11 */ 12 13 #include "qemu/osdep.h" 14 #include "qemu/ctype.h" 15 #include "qapi/qapi-visit-sockets.h" 16 #include "qapi/qobject-input-visitor.h" 17 #include "qapi/error.h" 18 #include "qobject/qlist.h" 19 #include "qemu/cutils.h" 20 #include "qemu/memalign.h" 21 22 #include "migration/bootfile.h" 23 #include "migration/migration-util.h" 24 25 #if defined(__linux__) 26 #include <sys/ioctl.h> 27 #include <sys/syscall.h> 28 #endif 29 30 /* for uffd_version_check() */ 31 #if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD) 32 #include <sys/eventfd.h> 33 #include "qemu/userfaultfd.h" 34 #endif 35 36 /* For dirty ring test; so far only x86_64 is supported */ 37 #if defined(__linux__) && defined(HOST_X86_64) 38 #include "linux/kvm.h" 39 #endif 40 41 42 static char *SocketAddress_to_str(SocketAddress *addr) 43 { 44 switch (addr->type) { 45 case SOCKET_ADDRESS_TYPE_INET: 46 return g_strdup_printf("tcp:%s:%s", 47 addr->u.inet.host, 48 addr->u.inet.port); 49 case SOCKET_ADDRESS_TYPE_UNIX: 50 return g_strdup_printf("unix:%s", 51 addr->u.q_unix.path); 52 case SOCKET_ADDRESS_TYPE_FD: 53 return g_strdup_printf("fd:%s", addr->u.fd.str); 54 case SOCKET_ADDRESS_TYPE_VSOCK: 55 return g_strdup_printf("vsock:%s:%s", 56 addr->u.vsock.cid, 57 addr->u.vsock.port); 58 default: 59 return g_strdup("unknown address type"); 60 } 61 } 62 63 static QDict *SocketAddress_to_qdict(SocketAddress *addr) 64 { 65 QDict *dict = qdict_new(); 66 67 switch (addr->type) { 68 case SOCKET_ADDRESS_TYPE_INET: 69 qdict_put_str(dict, "type", "inet"); 70 qdict_put_str(dict, "host", addr->u.inet.host); 71 qdict_put_str(dict, "port", addr->u.inet.port); 72 break; 73 case SOCKET_ADDRESS_TYPE_UNIX: 74 qdict_put_str(dict, "type", "unix"); 75 qdict_put_str(dict, "path", addr->u.q_unix.path); 76 break; 77 case SOCKET_ADDRESS_TYPE_FD: 78 qdict_put_str(dict, "type", "fd"); 79 qdict_put_str(dict, "str", addr->u.fd.str); 80 break; 81 case SOCKET_ADDRESS_TYPE_VSOCK: 82 qdict_put_str(dict, "type", "vsock"); 83 qdict_put_str(dict, "cid", addr->u.vsock.cid); 84 qdict_put_str(dict, "port", addr->u.vsock.port); 85 break; 86 default: 87 g_assert_not_reached(); 88 } 89 90 return dict; 91 } 92 93 static SocketAddressList *migrate_get_socket_address(QTestState *who) 94 { 95 QDict *rsp; 96 SocketAddressList *addrs; 97 Visitor *iv = NULL; 98 QObject *object; 99 100 rsp = migrate_query(who); 101 object = qdict_get(rsp, "socket-address"); 102 103 iv = qobject_input_visitor_new(object); 104 visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort); 105 visit_free(iv); 106 107 qobject_unref(rsp); 108 return addrs; 109 } 110 111 char *migrate_get_connect_uri(QTestState *who) 112 { 113 SocketAddressList *addrs; 114 char *connect_uri; 115 116 addrs = migrate_get_socket_address(who); 117 connect_uri = SocketAddress_to_str(addrs->value); 118 119 qapi_free_SocketAddressList(addrs); 120 return connect_uri; 121 } 122 123 static QDict * 124 migrate_get_connect_qdict(QTestState *who) 125 { 126 SocketAddressList *addrs; 127 QDict *connect_qdict; 128 129 addrs = migrate_get_socket_address(who); 130 connect_qdict = SocketAddress_to_qdict(addrs->value); 131 132 qapi_free_SocketAddressList(addrs); 133 return connect_qdict; 134 } 135 136 void migrate_set_ports(QTestState *to, QList *channel_list) 137 { 138 g_autoptr(QDict) addr = NULL; 139 QListEntry *entry; 140 const char *addr_port = NULL; 141 142 QLIST_FOREACH_ENTRY(channel_list, entry) { 143 QDict *channel = qobject_to(QDict, qlist_entry_obj(entry)); 144 QDict *addrdict = qdict_get_qdict(channel, "addr"); 145 146 if (!qdict_haskey(addrdict, "port") || 147 strcmp(qdict_get_str(addrdict, "port"), "0")) { 148 continue; 149 } 150 151 /* 152 * Fetch addr only if needed, so tests that are not yet connected to 153 * the monitor do not query it. Such tests cannot use port=0. 154 */ 155 if (!addr) { 156 addr = migrate_get_connect_qdict(to); 157 } 158 159 if (qdict_haskey(addr, "port")) { 160 addr_port = qdict_get_str(addr, "port"); 161 qdict_put_str(addrdict, "port", addr_port); 162 } 163 } 164 } 165 166 bool migrate_watch_for_events(QTestState *who, const char *name, 167 QDict *event, void *opaque) 168 { 169 QTestMigrationState *state = opaque; 170 171 if (g_str_equal(name, "STOP")) { 172 state->stop_seen = true; 173 return true; 174 } else if (g_str_equal(name, "SUSPEND")) { 175 state->suspend_seen = true; 176 return true; 177 } else if (g_str_equal(name, "RESUME")) { 178 state->resume_seen = true; 179 return true; 180 } 181 182 return false; 183 } 184 185 char *find_common_machine_version(const char *mtype, const char *var1, 186 const char *var2) 187 { 188 g_autofree char *type1 = qtest_resolve_machine_alias(var1, mtype); 189 g_autofree char *type2 = qtest_resolve_machine_alias(var2, mtype); 190 191 g_assert(type1 && type2); 192 193 if (g_str_equal(type1, type2)) { 194 /* either can be used */ 195 return g_strdup(type1); 196 } 197 198 if (qtest_has_machine_with_env(var2, type1)) { 199 return g_strdup(type1); 200 } 201 202 if (qtest_has_machine_with_env(var1, type2)) { 203 return g_strdup(type2); 204 } 205 206 g_test_message("No common machine version for machine type '%s' between " 207 "binaries %s and %s", mtype, getenv(var1), getenv(var2)); 208 g_assert_not_reached(); 209 } 210 211 char *resolve_machine_version(const char *alias, const char *var1, 212 const char *var2) 213 { 214 const char *mname = g_getenv("QTEST_QEMU_MACHINE_TYPE"); 215 g_autofree char *machine_name = NULL; 216 217 if (mname) { 218 const char *dash = strrchr(mname, '-'); 219 const char *dot = strrchr(mname, '.'); 220 221 machine_name = g_strdup(mname); 222 223 if (dash && dot) { 224 assert(qtest_has_machine(machine_name)); 225 return g_steal_pointer(&machine_name); 226 } 227 /* else: probably an alias, let it be resolved below */ 228 } else { 229 /* use the hardcoded alias */ 230 machine_name = g_strdup(alias); 231 } 232 233 return find_common_machine_version(machine_name, var1, var2); 234 } 235 236 typedef struct { 237 char *name; 238 void (*func)(void); 239 void (*func_full)(void *); 240 } MigrationTest; 241 242 static void migration_test_destroy(gpointer data) 243 { 244 MigrationTest *test = (MigrationTest *)data; 245 246 g_free(test->name); 247 g_free(test); 248 } 249 250 static void migration_test_wrapper(const void *data) 251 { 252 MigrationTest *test = (MigrationTest *)data; 253 254 g_test_message("Running /%s%s", qtest_get_arch(), test->name); 255 test->func(); 256 } 257 258 void migration_test_add(const char *path, void (*fn)(void)) 259 { 260 MigrationTest *test = g_new0(MigrationTest, 1); 261 262 test->func = fn; 263 test->name = g_strdup(path); 264 265 qtest_add_data_func_full(path, test, migration_test_wrapper, 266 migration_test_destroy); 267 } 268 269 static void migration_test_wrapper_full(const void *data) 270 { 271 MigrationTest *test = (MigrationTest *)data; 272 273 g_test_message("Running /%s%s", qtest_get_arch(), test->name); 274 test->func_full(test->name); 275 } 276 277 void migration_test_add_suffix(const char *path, const char *suffix, 278 void (*fn)(void *)) 279 { 280 MigrationTest *test = g_new0(MigrationTest, 1); 281 282 g_assert(g_str_has_suffix(path, "/")); 283 g_assert(!g_str_has_prefix(suffix, "/")); 284 285 test->func_full = fn; 286 test->name = g_strconcat(path, suffix, NULL); 287 288 qtest_add_data_func_full(test->name, test, migration_test_wrapper_full, 289 migration_test_destroy); 290 } 291 292 #ifdef O_DIRECT 293 /* 294 * Probe for O_DIRECT support on the filesystem. Since this is used 295 * for tests, be conservative, if anything fails, assume it's 296 * unsupported. 297 */ 298 bool probe_o_direct_support(const char *tmpfs) 299 { 300 g_autofree char *filename = g_strdup_printf("%s/probe-o-direct", tmpfs); 301 int fd, flags = O_CREAT | O_RDWR | O_TRUNC | O_DIRECT; 302 void *buf; 303 ssize_t ret, len; 304 uint64_t offset; 305 306 fd = open(filename, flags, 0660); 307 if (fd < 0) { 308 unlink(filename); 309 return false; 310 } 311 312 /* 313 * Using 1MB alignment as conservative choice to satisfy any 314 * plausible architecture default page size, and/or filesystem 315 * alignment restrictions. 316 */ 317 len = 0x100000; 318 offset = 0x100000; 319 320 buf = qemu_try_memalign(len, len); 321 g_assert(buf); 322 memset(buf, 0, len); 323 324 ret = pwrite(fd, buf, len, offset); 325 unlink(filename); 326 g_free(buf); 327 328 if (ret < 0) { 329 return false; 330 } 331 332 return true; 333 } 334 #endif 335 336 #if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD) 337 bool ufd_version_check(bool *uffd_feature_thread_id) 338 { 339 struct uffdio_api api_struct; 340 uint64_t ioctl_mask; 341 342 int ufd = uffd_open(O_CLOEXEC); 343 344 if (ufd == -1) { 345 g_test_message("Skipping test: userfaultfd not available"); 346 return false; 347 } 348 349 api_struct.api = UFFD_API; 350 api_struct.features = 0; 351 if (ioctl(ufd, UFFDIO_API, &api_struct)) { 352 g_test_message("Skipping test: UFFDIO_API failed"); 353 return false; 354 } 355 356 if (uffd_feature_thread_id) { 357 *uffd_feature_thread_id = api_struct.features & UFFD_FEATURE_THREAD_ID; 358 } 359 360 ioctl_mask = (1ULL << _UFFDIO_REGISTER | 361 1ULL << _UFFDIO_UNREGISTER); 362 if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) { 363 g_test_message("Skipping test: Missing userfault feature"); 364 return false; 365 } 366 367 return true; 368 } 369 #else 370 bool ufd_version_check(bool *uffd_feature_thread_id) 371 { 372 g_test_message("Skipping test: Userfault not available (builtdtime)"); 373 return false; 374 } 375 #endif 376 377 bool kvm_dirty_ring_supported(void) 378 { 379 #if defined(__linux__) && defined(HOST_X86_64) 380 int ret, kvm_fd = open("/dev/kvm", O_RDONLY); 381 382 if (kvm_fd < 0) { 383 return false; 384 } 385 386 ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, KVM_CAP_DIRTY_LOG_RING); 387 close(kvm_fd); 388 389 /* We test with 4096 slots */ 390 if (ret < 4096) { 391 return false; 392 } 393 394 return true; 395 #else 396 return false; 397 #endif 398 } 399