1 /* 2 * QEMU Guest Agent POSIX-specific command implementations 3 * 4 * Copyright IBM Corp. 2011 5 * 6 * Authors: 7 * Michael Roth <mdroth@linux.vnet.ibm.com> 8 * Michal Privoznik <mprivozn@redhat.com> 9 * 10 * This work is licensed under the terms of the GNU GPL, version 2 or later. 11 * See the COPYING file in the top-level directory. 12 */ 13 14 #include "qemu/osdep.h" 15 #include <sys/ioctl.h> 16 #include <sys/utsname.h> 17 #include <sys/wait.h> 18 #include <dirent.h> 19 #include "qga-qapi-commands.h" 20 #include "qapi/error.h" 21 #include "qapi/qmp/qerror.h" 22 #include "qemu/host-utils.h" 23 #include "qemu/sockets.h" 24 #include "qemu/base64.h" 25 #include "qemu/cutils.h" 26 #include "commands-common.h" 27 #include "block/nvme.h" 28 #include "cutils.h" 29 30 #ifdef HAVE_UTMPX 31 #include <utmpx.h> 32 #endif 33 34 #if defined(__linux__) 35 #include <mntent.h> 36 #include <sys/statvfs.h> 37 #include <linux/nvme_ioctl.h> 38 39 #ifdef CONFIG_LIBUDEV 40 #include <libudev.h> 41 #endif 42 #endif 43 44 #ifdef HAVE_GETIFADDRS 45 #include <arpa/inet.h> 46 #include <sys/socket.h> 47 #include <net/if.h> 48 #if defined(__NetBSD__) || defined(__OpenBSD__) 49 #include <net/if_arp.h> 50 #include <netinet/if_ether.h> 51 #else 52 #include <net/ethernet.h> 53 #endif 54 #include <sys/types.h> 55 #ifdef CONFIG_SOLARIS 56 #include <sys/sockio.h> 57 #endif 58 #endif 59 60 static void ga_wait_child(pid_t pid, int *status, Error **errp) 61 { 62 pid_t rpid; 63 64 *status = 0; 65 66 do { 67 rpid = waitpid(pid, status, 0); 68 } while (rpid == -1 && errno == EINTR); 69 70 if (rpid == -1) { 71 error_setg_errno(errp, errno, "failed to wait for child (pid: %d)", 72 pid); 73 return; 74 } 75 76 g_assert(rpid == pid); 77 } 78 79 void qmp_guest_shutdown(const char *mode, Error **errp) 80 { 81 const char *shutdown_flag; 82 Error *local_err = NULL; 83 pid_t pid; 84 int status; 85 86 #ifdef CONFIG_SOLARIS 87 const char *powerdown_flag = "-i5"; 88 const char *halt_flag = "-i0"; 89 const char *reboot_flag = "-i6"; 90 #elif defined(CONFIG_BSD) 91 const char *powerdown_flag = "-p"; 92 const char *halt_flag = "-h"; 93 const char *reboot_flag = "-r"; 94 #else 95 const char *powerdown_flag = "-P"; 96 const char *halt_flag = "-H"; 97 const char *reboot_flag = "-r"; 98 #endif 99 100 slog("guest-shutdown called, mode: %s", mode); 101 if (!mode || strcmp(mode, "powerdown") == 0) { 102 shutdown_flag = powerdown_flag; 103 } else if (strcmp(mode, "halt") == 0) { 104 shutdown_flag = halt_flag; 105 } else if (strcmp(mode, "reboot") == 0) { 106 shutdown_flag = reboot_flag; 107 } else { 108 error_setg(errp, 109 "mode is invalid (valid values are: halt|powerdown|reboot"); 110 return; 111 } 112 113 pid = fork(); 114 if (pid == 0) { 115 /* child, start the shutdown */ 116 setsid(); 117 reopen_fd_to_null(0); 118 reopen_fd_to_null(1); 119 reopen_fd_to_null(2); 120 121 #ifdef CONFIG_SOLARIS 122 execl("/sbin/shutdown", "shutdown", shutdown_flag, "-g0", "-y", 123 "hypervisor initiated shutdown", (char *)NULL); 124 #elif defined(CONFIG_BSD) 125 execl("/sbin/shutdown", "shutdown", shutdown_flag, "+0", 126 "hypervisor initiated shutdown", (char *)NULL); 127 #else 128 execl("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0", 129 "hypervisor initiated shutdown", (char *)NULL); 130 #endif 131 _exit(EXIT_FAILURE); 132 } else if (pid < 0) { 133 error_setg_errno(errp, errno, "failed to create child process"); 134 return; 135 } 136 137 ga_wait_child(pid, &status, &local_err); 138 if (local_err) { 139 error_propagate(errp, local_err); 140 return; 141 } 142 143 if (!WIFEXITED(status)) { 144 error_setg(errp, "child process has terminated abnormally"); 145 return; 146 } 147 148 if (WEXITSTATUS(status)) { 149 error_setg(errp, "child process has failed to shutdown"); 150 return; 151 } 152 153 /* succeeded */ 154 } 155 156 void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp) 157 { 158 int ret; 159 int status; 160 pid_t pid; 161 Error *local_err = NULL; 162 struct timeval tv; 163 static const char hwclock_path[] = "/sbin/hwclock"; 164 static int hwclock_available = -1; 165 166 if (hwclock_available < 0) { 167 hwclock_available = (access(hwclock_path, X_OK) == 0); 168 } 169 170 if (!hwclock_available) { 171 error_setg(errp, QERR_UNSUPPORTED); 172 return; 173 } 174 175 /* If user has passed a time, validate and set it. */ 176 if (has_time) { 177 GDate date = { 0, }; 178 179 /* year-2038 will overflow in case time_t is 32bit */ 180 if (time_ns / 1000000000 != (time_t)(time_ns / 1000000000)) { 181 error_setg(errp, "Time %" PRId64 " is too large", time_ns); 182 return; 183 } 184 185 tv.tv_sec = time_ns / 1000000000; 186 tv.tv_usec = (time_ns % 1000000000) / 1000; 187 g_date_set_time_t(&date, tv.tv_sec); 188 if (date.year < 1970 || date.year >= 2070) { 189 error_setg_errno(errp, errno, "Invalid time"); 190 return; 191 } 192 193 ret = settimeofday(&tv, NULL); 194 if (ret < 0) { 195 error_setg_errno(errp, errno, "Failed to set time to guest"); 196 return; 197 } 198 } 199 200 /* Now, if user has passed a time to set and the system time is set, we 201 * just need to synchronize the hardware clock. However, if no time was 202 * passed, user is requesting the opposite: set the system time from the 203 * hardware clock (RTC). */ 204 pid = fork(); 205 if (pid == 0) { 206 setsid(); 207 reopen_fd_to_null(0); 208 reopen_fd_to_null(1); 209 reopen_fd_to_null(2); 210 211 /* Use '/sbin/hwclock -w' to set RTC from the system time, 212 * or '/sbin/hwclock -s' to set the system time from RTC. */ 213 execl(hwclock_path, "hwclock", has_time ? "-w" : "-s", NULL); 214 _exit(EXIT_FAILURE); 215 } else if (pid < 0) { 216 error_setg_errno(errp, errno, "failed to create child process"); 217 return; 218 } 219 220 ga_wait_child(pid, &status, &local_err); 221 if (local_err) { 222 error_propagate(errp, local_err); 223 return; 224 } 225 226 if (!WIFEXITED(status)) { 227 error_setg(errp, "child process has terminated abnormally"); 228 return; 229 } 230 231 if (WEXITSTATUS(status)) { 232 error_setg(errp, "hwclock failed to set hardware clock to system time"); 233 return; 234 } 235 } 236 237 typedef enum { 238 RW_STATE_NEW, 239 RW_STATE_READING, 240 RW_STATE_WRITING, 241 } RwState; 242 243 struct GuestFileHandle { 244 uint64_t id; 245 FILE *fh; 246 RwState state; 247 QTAILQ_ENTRY(GuestFileHandle) next; 248 }; 249 250 static struct { 251 QTAILQ_HEAD(, GuestFileHandle) filehandles; 252 } guest_file_state = { 253 .filehandles = QTAILQ_HEAD_INITIALIZER(guest_file_state.filehandles), 254 }; 255 256 static int64_t guest_file_handle_add(FILE *fh, Error **errp) 257 { 258 GuestFileHandle *gfh; 259 int64_t handle; 260 261 handle = ga_get_fd_handle(ga_state, errp); 262 if (handle < 0) { 263 return -1; 264 } 265 266 gfh = g_new0(GuestFileHandle, 1); 267 gfh->id = handle; 268 gfh->fh = fh; 269 QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next); 270 271 return handle; 272 } 273 274 GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp) 275 { 276 GuestFileHandle *gfh; 277 278 QTAILQ_FOREACH(gfh, &guest_file_state.filehandles, next) 279 { 280 if (gfh->id == id) { 281 return gfh; 282 } 283 } 284 285 error_setg(errp, "handle '%" PRId64 "' has not been found", id); 286 return NULL; 287 } 288 289 typedef const char * const ccpc; 290 291 #ifndef O_BINARY 292 #define O_BINARY 0 293 #endif 294 295 /* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html */ 296 static const struct { 297 ccpc *forms; 298 int oflag_base; 299 } guest_file_open_modes[] = { 300 { (ccpc[]){ "r", NULL }, O_RDONLY }, 301 { (ccpc[]){ "rb", NULL }, O_RDONLY | O_BINARY }, 302 { (ccpc[]){ "w", NULL }, O_WRONLY | O_CREAT | O_TRUNC }, 303 { (ccpc[]){ "wb", NULL }, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY }, 304 { (ccpc[]){ "a", NULL }, O_WRONLY | O_CREAT | O_APPEND }, 305 { (ccpc[]){ "ab", NULL }, O_WRONLY | O_CREAT | O_APPEND | O_BINARY }, 306 { (ccpc[]){ "r+", NULL }, O_RDWR }, 307 { (ccpc[]){ "rb+", "r+b", NULL }, O_RDWR | O_BINARY }, 308 { (ccpc[]){ "w+", NULL }, O_RDWR | O_CREAT | O_TRUNC }, 309 { (ccpc[]){ "wb+", "w+b", NULL }, O_RDWR | O_CREAT | O_TRUNC | O_BINARY }, 310 { (ccpc[]){ "a+", NULL }, O_RDWR | O_CREAT | O_APPEND }, 311 { (ccpc[]){ "ab+", "a+b", NULL }, O_RDWR | O_CREAT | O_APPEND | O_BINARY } 312 }; 313 314 static int 315 find_open_flag(const char *mode_str, Error **errp) 316 { 317 unsigned mode; 318 319 for (mode = 0; mode < ARRAY_SIZE(guest_file_open_modes); ++mode) { 320 ccpc *form; 321 322 form = guest_file_open_modes[mode].forms; 323 while (*form != NULL && strcmp(*form, mode_str) != 0) { 324 ++form; 325 } 326 if (*form != NULL) { 327 break; 328 } 329 } 330 331 if (mode == ARRAY_SIZE(guest_file_open_modes)) { 332 error_setg(errp, "invalid file open mode '%s'", mode_str); 333 return -1; 334 } 335 return guest_file_open_modes[mode].oflag_base | O_NOCTTY | O_NONBLOCK; 336 } 337 338 #define DEFAULT_NEW_FILE_MODE (S_IRUSR | S_IWUSR | \ 339 S_IRGRP | S_IWGRP | \ 340 S_IROTH | S_IWOTH) 341 342 static FILE * 343 safe_open_or_create(const char *path, const char *mode, Error **errp) 344 { 345 int oflag; 346 int fd = -1; 347 FILE *f = NULL; 348 349 oflag = find_open_flag(mode, errp); 350 if (oflag < 0) { 351 goto end; 352 } 353 354 /* If the caller wants / allows creation of a new file, we implement it 355 * with a two step process: open() + (open() / fchmod()). 356 * 357 * First we insist on creating the file exclusively as a new file. If 358 * that succeeds, we're free to set any file-mode bits on it. (The 359 * motivation is that we want to set those file-mode bits independently 360 * of the current umask.) 361 * 362 * If the exclusive creation fails because the file already exists 363 * (EEXIST is not possible for any other reason), we just attempt to 364 * open the file, but in this case we won't be allowed to change the 365 * file-mode bits on the preexistent file. 366 * 367 * The pathname should never disappear between the two open()s in 368 * practice. If it happens, then someone very likely tried to race us. 369 * In this case just go ahead and report the ENOENT from the second 370 * open() to the caller. 371 * 372 * If the caller wants to open a preexistent file, then the first 373 * open() is decisive and its third argument is ignored, and the second 374 * open() and the fchmod() are never called. 375 */ 376 fd = qga_open_cloexec(path, oflag | ((oflag & O_CREAT) ? O_EXCL : 0), 0); 377 if (fd == -1 && errno == EEXIST) { 378 oflag &= ~(unsigned)O_CREAT; 379 fd = qga_open_cloexec(path, oflag, 0); 380 } 381 if (fd == -1) { 382 error_setg_errno(errp, errno, 383 "failed to open file '%s' (mode: '%s')", 384 path, mode); 385 goto end; 386 } 387 388 if ((oflag & O_CREAT) && fchmod(fd, DEFAULT_NEW_FILE_MODE) == -1) { 389 error_setg_errno(errp, errno, "failed to set permission " 390 "0%03o on new file '%s' (mode: '%s')", 391 (unsigned)DEFAULT_NEW_FILE_MODE, path, mode); 392 goto end; 393 } 394 395 f = fdopen(fd, mode); 396 if (f == NULL) { 397 error_setg_errno(errp, errno, "failed to associate stdio stream with " 398 "file descriptor %d, file '%s' (mode: '%s')", 399 fd, path, mode); 400 } 401 402 end: 403 if (f == NULL && fd != -1) { 404 close(fd); 405 if (oflag & O_CREAT) { 406 unlink(path); 407 } 408 } 409 return f; 410 } 411 412 int64_t qmp_guest_file_open(const char *path, const char *mode, 413 Error **errp) 414 { 415 FILE *fh; 416 Error *local_err = NULL; 417 int64_t handle; 418 419 if (!mode) { 420 mode = "r"; 421 } 422 slog("guest-file-open called, filepath: %s, mode: %s", path, mode); 423 fh = safe_open_or_create(path, mode, &local_err); 424 if (local_err != NULL) { 425 error_propagate(errp, local_err); 426 return -1; 427 } 428 429 /* set fd non-blocking to avoid common use cases (like reading from a 430 * named pipe) from hanging the agent 431 */ 432 if (!g_unix_set_fd_nonblocking(fileno(fh), true, NULL)) { 433 fclose(fh); 434 error_setg_errno(errp, errno, "Failed to set FD nonblocking"); 435 return -1; 436 } 437 438 handle = guest_file_handle_add(fh, errp); 439 if (handle < 0) { 440 fclose(fh); 441 return -1; 442 } 443 444 slog("guest-file-open, handle: %" PRId64, handle); 445 return handle; 446 } 447 448 void qmp_guest_file_close(int64_t handle, Error **errp) 449 { 450 GuestFileHandle *gfh = guest_file_handle_find(handle, errp); 451 int ret; 452 453 slog("guest-file-close called, handle: %" PRId64, handle); 454 if (!gfh) { 455 return; 456 } 457 458 ret = fclose(gfh->fh); 459 if (ret == EOF) { 460 error_setg_errno(errp, errno, "failed to close handle"); 461 return; 462 } 463 464 QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next); 465 g_free(gfh); 466 } 467 468 GuestFileRead *guest_file_read_unsafe(GuestFileHandle *gfh, 469 int64_t count, Error **errp) 470 { 471 GuestFileRead *read_data = NULL; 472 guchar *buf; 473 FILE *fh = gfh->fh; 474 size_t read_count; 475 476 /* explicitly flush when switching from writing to reading */ 477 if (gfh->state == RW_STATE_WRITING) { 478 int ret = fflush(fh); 479 if (ret == EOF) { 480 error_setg_errno(errp, errno, "failed to flush file"); 481 return NULL; 482 } 483 gfh->state = RW_STATE_NEW; 484 } 485 486 buf = g_malloc0(count + 1); 487 read_count = fread(buf, 1, count, fh); 488 if (ferror(fh)) { 489 error_setg_errno(errp, errno, "failed to read file"); 490 } else { 491 buf[read_count] = 0; 492 read_data = g_new0(GuestFileRead, 1); 493 read_data->count = read_count; 494 read_data->eof = feof(fh); 495 if (read_count) { 496 read_data->buf_b64 = g_base64_encode(buf, read_count); 497 } 498 gfh->state = RW_STATE_READING; 499 } 500 g_free(buf); 501 clearerr(fh); 502 503 return read_data; 504 } 505 506 GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64, 507 bool has_count, int64_t count, 508 Error **errp) 509 { 510 GuestFileWrite *write_data = NULL; 511 guchar *buf; 512 gsize buf_len; 513 int write_count; 514 GuestFileHandle *gfh = guest_file_handle_find(handle, errp); 515 FILE *fh; 516 517 if (!gfh) { 518 return NULL; 519 } 520 521 fh = gfh->fh; 522 523 if (gfh->state == RW_STATE_READING) { 524 int ret = fseek(fh, 0, SEEK_CUR); 525 if (ret == -1) { 526 error_setg_errno(errp, errno, "failed to seek file"); 527 return NULL; 528 } 529 gfh->state = RW_STATE_NEW; 530 } 531 532 buf = qbase64_decode(buf_b64, -1, &buf_len, errp); 533 if (!buf) { 534 return NULL; 535 } 536 537 if (!has_count) { 538 count = buf_len; 539 } else if (count < 0 || count > buf_len) { 540 error_setg(errp, "value '%" PRId64 "' is invalid for argument count", 541 count); 542 g_free(buf); 543 return NULL; 544 } 545 546 write_count = fwrite(buf, 1, count, fh); 547 if (ferror(fh)) { 548 error_setg_errno(errp, errno, "failed to write to file"); 549 slog("guest-file-write failed, handle: %" PRId64, handle); 550 } else { 551 write_data = g_new0(GuestFileWrite, 1); 552 write_data->count = write_count; 553 write_data->eof = feof(fh); 554 gfh->state = RW_STATE_WRITING; 555 } 556 g_free(buf); 557 clearerr(fh); 558 559 return write_data; 560 } 561 562 struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset, 563 GuestFileWhence *whence_code, 564 Error **errp) 565 { 566 GuestFileHandle *gfh = guest_file_handle_find(handle, errp); 567 GuestFileSeek *seek_data = NULL; 568 FILE *fh; 569 int ret; 570 int whence; 571 Error *err = NULL; 572 573 if (!gfh) { 574 return NULL; 575 } 576 577 /* We stupidly exposed 'whence':'int' in our qapi */ 578 whence = ga_parse_whence(whence_code, &err); 579 if (err) { 580 error_propagate(errp, err); 581 return NULL; 582 } 583 584 fh = gfh->fh; 585 ret = fseek(fh, offset, whence); 586 if (ret == -1) { 587 error_setg_errno(errp, errno, "failed to seek file"); 588 if (errno == ESPIPE) { 589 /* file is non-seekable, stdio shouldn't be buffering anyways */ 590 gfh->state = RW_STATE_NEW; 591 } 592 } else { 593 seek_data = g_new0(GuestFileSeek, 1); 594 seek_data->position = ftell(fh); 595 seek_data->eof = feof(fh); 596 gfh->state = RW_STATE_NEW; 597 } 598 clearerr(fh); 599 600 return seek_data; 601 } 602 603 void qmp_guest_file_flush(int64_t handle, Error **errp) 604 { 605 GuestFileHandle *gfh = guest_file_handle_find(handle, errp); 606 FILE *fh; 607 int ret; 608 609 if (!gfh) { 610 return; 611 } 612 613 fh = gfh->fh; 614 ret = fflush(fh); 615 if (ret == EOF) { 616 error_setg_errno(errp, errno, "failed to flush file"); 617 } else { 618 gfh->state = RW_STATE_NEW; 619 } 620 } 621 622 #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) 623 void free_fs_mount_list(FsMountList *mounts) 624 { 625 FsMount *mount, *temp; 626 627 if (!mounts) { 628 return; 629 } 630 631 QTAILQ_FOREACH_SAFE(mount, mounts, next, temp) { 632 QTAILQ_REMOVE(mounts, mount, next); 633 g_free(mount->dirname); 634 g_free(mount->devtype); 635 g_free(mount); 636 } 637 } 638 #endif 639 640 #if defined(CONFIG_FSFREEZE) 641 typedef enum { 642 FSFREEZE_HOOK_THAW = 0, 643 FSFREEZE_HOOK_FREEZE, 644 } FsfreezeHookArg; 645 646 static const char *fsfreeze_hook_arg_string[] = { 647 "thaw", 648 "freeze", 649 }; 650 651 static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp) 652 { 653 int status; 654 pid_t pid; 655 const char *hook; 656 const char *arg_str = fsfreeze_hook_arg_string[arg]; 657 Error *local_err = NULL; 658 659 hook = ga_fsfreeze_hook(ga_state); 660 if (!hook) { 661 return; 662 } 663 if (access(hook, X_OK) != 0) { 664 error_setg_errno(errp, errno, "can't access fsfreeze hook '%s'", hook); 665 return; 666 } 667 668 slog("executing fsfreeze hook with arg '%s'", arg_str); 669 pid = fork(); 670 if (pid == 0) { 671 setsid(); 672 reopen_fd_to_null(0); 673 reopen_fd_to_null(1); 674 reopen_fd_to_null(2); 675 676 execl(hook, hook, arg_str, NULL); 677 _exit(EXIT_FAILURE); 678 } else if (pid < 0) { 679 error_setg_errno(errp, errno, "failed to create child process"); 680 return; 681 } 682 683 ga_wait_child(pid, &status, &local_err); 684 if (local_err) { 685 error_propagate(errp, local_err); 686 return; 687 } 688 689 if (!WIFEXITED(status)) { 690 error_setg(errp, "fsfreeze hook has terminated abnormally"); 691 return; 692 } 693 694 status = WEXITSTATUS(status); 695 if (status) { 696 error_setg(errp, "fsfreeze hook has failed with status %d", status); 697 return; 698 } 699 } 700 701 /* 702 * Return status of freeze/thaw 703 */ 704 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp) 705 { 706 if (ga_is_frozen(ga_state)) { 707 return GUEST_FSFREEZE_STATUS_FROZEN; 708 } 709 710 return GUEST_FSFREEZE_STATUS_THAWED; 711 } 712 713 int64_t qmp_guest_fsfreeze_freeze(Error **errp) 714 { 715 return qmp_guest_fsfreeze_freeze_list(false, NULL, errp); 716 } 717 718 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, 719 strList *mountpoints, 720 Error **errp) 721 { 722 int ret; 723 FsMountList mounts; 724 Error *local_err = NULL; 725 726 slog("guest-fsfreeze called"); 727 728 execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err); 729 if (local_err) { 730 error_propagate(errp, local_err); 731 return -1; 732 } 733 734 QTAILQ_INIT(&mounts); 735 if (!build_fs_mount_list(&mounts, &local_err)) { 736 error_propagate(errp, local_err); 737 return -1; 738 } 739 740 /* cannot risk guest agent blocking itself on a write in this state */ 741 ga_set_frozen(ga_state); 742 743 ret = qmp_guest_fsfreeze_do_freeze_list(has_mountpoints, mountpoints, 744 mounts, errp); 745 746 free_fs_mount_list(&mounts); 747 /* We may not issue any FIFREEZE here. 748 * Just unset ga_state here and ready for the next call. 749 */ 750 if (ret == 0) { 751 ga_unset_frozen(ga_state); 752 } else if (ret < 0) { 753 qmp_guest_fsfreeze_thaw(NULL); 754 } 755 return ret; 756 } 757 758 int64_t qmp_guest_fsfreeze_thaw(Error **errp) 759 { 760 int ret; 761 762 ret = qmp_guest_fsfreeze_do_thaw(errp); 763 if (ret >= 0) { 764 ga_unset_frozen(ga_state); 765 execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp); 766 } else { 767 ret = 0; 768 } 769 770 return ret; 771 } 772 773 static void guest_fsfreeze_cleanup(void) 774 { 775 Error *err = NULL; 776 777 if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) { 778 qmp_guest_fsfreeze_thaw(&err); 779 if (err) { 780 slog("failed to clean up frozen filesystems: %s", 781 error_get_pretty(err)); 782 error_free(err); 783 } 784 } 785 } 786 #endif 787 788 /* linux-specific implementations. avoid this if at all possible. */ 789 #if defined(__linux__) 790 #if defined(CONFIG_FSFREEZE) 791 792 static char *get_pci_driver(char const *syspath, int pathlen, Error **errp) 793 { 794 char *path; 795 char *dpath; 796 char *driver = NULL; 797 char buf[PATH_MAX]; 798 ssize_t len; 799 800 path = g_strndup(syspath, pathlen); 801 dpath = g_strdup_printf("%s/driver", path); 802 len = readlink(dpath, buf, sizeof(buf) - 1); 803 if (len != -1) { 804 buf[len] = 0; 805 driver = g_path_get_basename(buf); 806 } 807 g_free(dpath); 808 g_free(path); 809 return driver; 810 } 811 812 static int compare_uint(const void *_a, const void *_b) 813 { 814 unsigned int a = *(unsigned int *)_a; 815 unsigned int b = *(unsigned int *)_b; 816 817 return a < b ? -1 : a > b ? 1 : 0; 818 } 819 820 /* Walk the specified sysfs and build a sorted list of host or ata numbers */ 821 static int build_hosts(char const *syspath, char const *host, bool ata, 822 unsigned int *hosts, int hosts_max, Error **errp) 823 { 824 char *path; 825 DIR *dir; 826 struct dirent *entry; 827 int i = 0; 828 829 path = g_strndup(syspath, host - syspath); 830 dir = opendir(path); 831 if (!dir) { 832 error_setg_errno(errp, errno, "opendir(\"%s\")", path); 833 g_free(path); 834 return -1; 835 } 836 837 while (i < hosts_max) { 838 entry = readdir(dir); 839 if (!entry) { 840 break; 841 } 842 if (ata && sscanf(entry->d_name, "ata%d", hosts + i) == 1) { 843 ++i; 844 } else if (!ata && sscanf(entry->d_name, "host%d", hosts + i) == 1) { 845 ++i; 846 } 847 } 848 849 qsort(hosts, i, sizeof(hosts[0]), compare_uint); 850 851 g_free(path); 852 closedir(dir); 853 return i; 854 } 855 856 /* 857 * Store disk device info for devices on the PCI bus. 858 * Returns true if information has been stored, or false for failure. 859 */ 860 static bool build_guest_fsinfo_for_pci_dev(char const *syspath, 861 GuestDiskAddress *disk, 862 Error **errp) 863 { 864 unsigned int pci[4], host, hosts[8], tgt[3]; 865 int i, nhosts = 0, pcilen; 866 GuestPCIAddress *pciaddr = disk->pci_controller; 867 bool has_ata = false, has_host = false, has_tgt = false; 868 char *p, *q, *driver = NULL; 869 bool ret = false; 870 871 p = strstr(syspath, "/devices/pci"); 872 if (!p || sscanf(p + 12, "%*x:%*x/%x:%x:%x.%x%n", 873 pci, pci + 1, pci + 2, pci + 3, &pcilen) < 4) { 874 g_debug("only pci device is supported: sysfs path '%s'", syspath); 875 return false; 876 } 877 878 p += 12 + pcilen; 879 while (true) { 880 driver = get_pci_driver(syspath, p - syspath, errp); 881 if (driver && (g_str_equal(driver, "ata_piix") || 882 g_str_equal(driver, "sym53c8xx") || 883 g_str_equal(driver, "virtio-pci") || 884 g_str_equal(driver, "ahci") || 885 g_str_equal(driver, "nvme"))) { 886 break; 887 } 888 889 g_free(driver); 890 if (sscanf(p, "/%x:%x:%x.%x%n", 891 pci, pci + 1, pci + 2, pci + 3, &pcilen) == 4) { 892 p += pcilen; 893 continue; 894 } 895 896 g_debug("unsupported driver or sysfs path '%s'", syspath); 897 return false; 898 } 899 900 p = strstr(syspath, "/target"); 901 if (p && sscanf(p + 7, "%*u:%*u:%*u/%*u:%u:%u:%u", 902 tgt, tgt + 1, tgt + 2) == 3) { 903 has_tgt = true; 904 } 905 906 p = strstr(syspath, "/ata"); 907 if (p) { 908 q = p + 4; 909 has_ata = true; 910 } else { 911 p = strstr(syspath, "/host"); 912 q = p + 5; 913 } 914 if (p && sscanf(q, "%u", &host) == 1) { 915 has_host = true; 916 nhosts = build_hosts(syspath, p, has_ata, hosts, 917 ARRAY_SIZE(hosts), errp); 918 if (nhosts < 0) { 919 goto cleanup; 920 } 921 } 922 923 pciaddr->domain = pci[0]; 924 pciaddr->bus = pci[1]; 925 pciaddr->slot = pci[2]; 926 pciaddr->function = pci[3]; 927 928 if (strcmp(driver, "ata_piix") == 0) { 929 /* a host per ide bus, target*:0:<unit>:0 */ 930 if (!has_host || !has_tgt) { 931 g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver); 932 goto cleanup; 933 } 934 for (i = 0; i < nhosts; i++) { 935 if (host == hosts[i]) { 936 disk->bus_type = GUEST_DISK_BUS_TYPE_IDE; 937 disk->bus = i; 938 disk->unit = tgt[1]; 939 break; 940 } 941 } 942 if (i >= nhosts) { 943 g_debug("no host for '%s' (driver '%s')", syspath, driver); 944 goto cleanup; 945 } 946 } else if (strcmp(driver, "sym53c8xx") == 0) { 947 /* scsi(LSI Logic): target*:0:<unit>:0 */ 948 if (!has_tgt) { 949 g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver); 950 goto cleanup; 951 } 952 disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI; 953 disk->unit = tgt[1]; 954 } else if (strcmp(driver, "virtio-pci") == 0) { 955 if (has_tgt) { 956 /* virtio-scsi: target*:0:0:<unit> */ 957 disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI; 958 disk->unit = tgt[2]; 959 } else { 960 /* virtio-blk: 1 disk per 1 device */ 961 disk->bus_type = GUEST_DISK_BUS_TYPE_VIRTIO; 962 } 963 } else if (strcmp(driver, "ahci") == 0) { 964 /* ahci: 1 host per 1 unit */ 965 if (!has_host || !has_tgt) { 966 g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver); 967 goto cleanup; 968 } 969 for (i = 0; i < nhosts; i++) { 970 if (host == hosts[i]) { 971 disk->unit = i; 972 disk->bus_type = GUEST_DISK_BUS_TYPE_SATA; 973 break; 974 } 975 } 976 if (i >= nhosts) { 977 g_debug("no host for '%s' (driver '%s')", syspath, driver); 978 goto cleanup; 979 } 980 } else if (strcmp(driver, "nvme") == 0) { 981 disk->bus_type = GUEST_DISK_BUS_TYPE_NVME; 982 } else { 983 g_debug("unknown driver '%s' (sysfs path '%s')", driver, syspath); 984 goto cleanup; 985 } 986 987 ret = true; 988 989 cleanup: 990 g_free(driver); 991 return ret; 992 } 993 994 /* 995 * Store disk device info for non-PCI virtio devices (for example s390x 996 * channel I/O devices). Returns true if information has been stored, or 997 * false for failure. 998 */ 999 static bool build_guest_fsinfo_for_nonpci_virtio(char const *syspath, 1000 GuestDiskAddress *disk, 1001 Error **errp) 1002 { 1003 unsigned int tgt[3]; 1004 char *p; 1005 1006 if (!strstr(syspath, "/virtio") || !strstr(syspath, "/block")) { 1007 g_debug("Unsupported virtio device '%s'", syspath); 1008 return false; 1009 } 1010 1011 p = strstr(syspath, "/target"); 1012 if (p && sscanf(p + 7, "%*u:%*u:%*u/%*u:%u:%u:%u", 1013 &tgt[0], &tgt[1], &tgt[2]) == 3) { 1014 /* virtio-scsi: target*:0:<target>:<unit> */ 1015 disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI; 1016 disk->bus = tgt[0]; 1017 disk->target = tgt[1]; 1018 disk->unit = tgt[2]; 1019 } else { 1020 /* virtio-blk: 1 disk per 1 device */ 1021 disk->bus_type = GUEST_DISK_BUS_TYPE_VIRTIO; 1022 } 1023 1024 return true; 1025 } 1026 1027 /* 1028 * Store disk device info for CCW devices (s390x channel I/O devices). 1029 * Returns true if information has been stored, or false for failure. 1030 */ 1031 static bool build_guest_fsinfo_for_ccw_dev(char const *syspath, 1032 GuestDiskAddress *disk, 1033 Error **errp) 1034 { 1035 unsigned int cssid, ssid, subchno, devno; 1036 char *p; 1037 1038 p = strstr(syspath, "/devices/css"); 1039 if (!p || sscanf(p + 12, "%*x/%x.%x.%x/%*x.%*x.%x/", 1040 &cssid, &ssid, &subchno, &devno) < 4) { 1041 g_debug("could not parse ccw device sysfs path: %s", syspath); 1042 return false; 1043 } 1044 1045 disk->ccw_address = g_new0(GuestCCWAddress, 1); 1046 disk->ccw_address->cssid = cssid; 1047 disk->ccw_address->ssid = ssid; 1048 disk->ccw_address->subchno = subchno; 1049 disk->ccw_address->devno = devno; 1050 1051 if (strstr(p, "/virtio")) { 1052 build_guest_fsinfo_for_nonpci_virtio(syspath, disk, errp); 1053 } 1054 1055 return true; 1056 } 1057 1058 /* Store disk device info specified by @sysfs into @fs */ 1059 static void build_guest_fsinfo_for_real_device(char const *syspath, 1060 GuestFilesystemInfo *fs, 1061 Error **errp) 1062 { 1063 GuestDiskAddress *disk; 1064 GuestPCIAddress *pciaddr; 1065 bool has_hwinf; 1066 #ifdef CONFIG_LIBUDEV 1067 struct udev *udev = NULL; 1068 struct udev_device *udevice = NULL; 1069 #endif 1070 1071 pciaddr = g_new0(GuestPCIAddress, 1); 1072 pciaddr->domain = -1; /* -1 means field is invalid */ 1073 pciaddr->bus = -1; 1074 pciaddr->slot = -1; 1075 pciaddr->function = -1; 1076 1077 disk = g_new0(GuestDiskAddress, 1); 1078 disk->pci_controller = pciaddr; 1079 disk->bus_type = GUEST_DISK_BUS_TYPE_UNKNOWN; 1080 1081 #ifdef CONFIG_LIBUDEV 1082 udev = udev_new(); 1083 udevice = udev_device_new_from_syspath(udev, syspath); 1084 if (udev == NULL || udevice == NULL) { 1085 g_debug("failed to query udev"); 1086 } else { 1087 const char *devnode, *serial; 1088 devnode = udev_device_get_devnode(udevice); 1089 if (devnode != NULL) { 1090 disk->dev = g_strdup(devnode); 1091 } 1092 serial = udev_device_get_property_value(udevice, "ID_SERIAL"); 1093 if (serial != NULL && *serial != 0) { 1094 disk->serial = g_strdup(serial); 1095 } 1096 } 1097 1098 udev_unref(udev); 1099 udev_device_unref(udevice); 1100 #endif 1101 1102 if (strstr(syspath, "/devices/pci")) { 1103 has_hwinf = build_guest_fsinfo_for_pci_dev(syspath, disk, errp); 1104 } else if (strstr(syspath, "/devices/css")) { 1105 has_hwinf = build_guest_fsinfo_for_ccw_dev(syspath, disk, errp); 1106 } else if (strstr(syspath, "/virtio")) { 1107 has_hwinf = build_guest_fsinfo_for_nonpci_virtio(syspath, disk, errp); 1108 } else { 1109 g_debug("Unsupported device type for '%s'", syspath); 1110 has_hwinf = false; 1111 } 1112 1113 if (has_hwinf || disk->dev || disk->serial) { 1114 QAPI_LIST_PREPEND(fs->disk, disk); 1115 } else { 1116 qapi_free_GuestDiskAddress(disk); 1117 } 1118 } 1119 1120 static void build_guest_fsinfo_for_device(char const *devpath, 1121 GuestFilesystemInfo *fs, 1122 Error **errp); 1123 1124 /* Store a list of slave devices of virtual volume specified by @syspath into 1125 * @fs */ 1126 static void build_guest_fsinfo_for_virtual_device(char const *syspath, 1127 GuestFilesystemInfo *fs, 1128 Error **errp) 1129 { 1130 Error *err = NULL; 1131 DIR *dir; 1132 char *dirpath; 1133 struct dirent *entry; 1134 1135 dirpath = g_strdup_printf("%s/slaves", syspath); 1136 dir = opendir(dirpath); 1137 if (!dir) { 1138 if (errno != ENOENT) { 1139 error_setg_errno(errp, errno, "opendir(\"%s\")", dirpath); 1140 } 1141 g_free(dirpath); 1142 return; 1143 } 1144 1145 for (;;) { 1146 errno = 0; 1147 entry = readdir(dir); 1148 if (entry == NULL) { 1149 if (errno) { 1150 error_setg_errno(errp, errno, "readdir(\"%s\")", dirpath); 1151 } 1152 break; 1153 } 1154 1155 if (entry->d_type == DT_LNK) { 1156 char *path; 1157 1158 g_debug(" slave device '%s'", entry->d_name); 1159 path = g_strdup_printf("%s/slaves/%s", syspath, entry->d_name); 1160 build_guest_fsinfo_for_device(path, fs, &err); 1161 g_free(path); 1162 1163 if (err) { 1164 error_propagate(errp, err); 1165 break; 1166 } 1167 } 1168 } 1169 1170 g_free(dirpath); 1171 closedir(dir); 1172 } 1173 1174 static bool is_disk_virtual(const char *devpath, Error **errp) 1175 { 1176 g_autofree char *syspath = realpath(devpath, NULL); 1177 1178 if (!syspath) { 1179 error_setg_errno(errp, errno, "realpath(\"%s\")", devpath); 1180 return false; 1181 } 1182 return strstr(syspath, "/devices/virtual/block/") != NULL; 1183 } 1184 1185 /* Dispatch to functions for virtual/real device */ 1186 static void build_guest_fsinfo_for_device(char const *devpath, 1187 GuestFilesystemInfo *fs, 1188 Error **errp) 1189 { 1190 ERRP_GUARD(); 1191 g_autofree char *syspath = NULL; 1192 bool is_virtual = false; 1193 1194 syspath = realpath(devpath, NULL); 1195 if (!syspath) { 1196 if (errno != ENOENT) { 1197 error_setg_errno(errp, errno, "realpath(\"%s\")", devpath); 1198 return; 1199 } 1200 1201 /* ENOENT: This devpath may not exist because of container config */ 1202 if (!fs->name) { 1203 fs->name = g_path_get_basename(devpath); 1204 } 1205 return; 1206 } 1207 1208 if (!fs->name) { 1209 fs->name = g_path_get_basename(syspath); 1210 } 1211 1212 g_debug(" parse sysfs path '%s'", syspath); 1213 is_virtual = is_disk_virtual(syspath, errp); 1214 if (*errp != NULL) { 1215 return; 1216 } 1217 if (is_virtual) { 1218 build_guest_fsinfo_for_virtual_device(syspath, fs, errp); 1219 } else { 1220 build_guest_fsinfo_for_real_device(syspath, fs, errp); 1221 } 1222 } 1223 1224 #ifdef CONFIG_LIBUDEV 1225 1226 /* 1227 * Wrapper around build_guest_fsinfo_for_device() for getting just 1228 * the disk address. 1229 */ 1230 static GuestDiskAddress *get_disk_address(const char *syspath, Error **errp) 1231 { 1232 g_autoptr(GuestFilesystemInfo) fs = NULL; 1233 1234 fs = g_new0(GuestFilesystemInfo, 1); 1235 build_guest_fsinfo_for_device(syspath, fs, errp); 1236 if (fs->disk != NULL) { 1237 return g_steal_pointer(&fs->disk->value); 1238 } 1239 return NULL; 1240 } 1241 1242 static char *get_alias_for_syspath(const char *syspath) 1243 { 1244 struct udev *udev = NULL; 1245 struct udev_device *udevice = NULL; 1246 char *ret = NULL; 1247 1248 udev = udev_new(); 1249 if (udev == NULL) { 1250 g_debug("failed to query udev"); 1251 goto out; 1252 } 1253 udevice = udev_device_new_from_syspath(udev, syspath); 1254 if (udevice == NULL) { 1255 g_debug("failed to query udev for path: %s", syspath); 1256 goto out; 1257 } else { 1258 const char *alias = udev_device_get_property_value( 1259 udevice, "DM_NAME"); 1260 /* 1261 * NULL means there was an error and empty string means there is no 1262 * alias. In case of no alias we return NULL instead of empty string. 1263 */ 1264 if (alias == NULL) { 1265 g_debug("failed to query udev for device alias for: %s", 1266 syspath); 1267 } else if (*alias != 0) { 1268 ret = g_strdup(alias); 1269 } 1270 } 1271 1272 out: 1273 udev_unref(udev); 1274 udev_device_unref(udevice); 1275 return ret; 1276 } 1277 1278 static char *get_device_for_syspath(const char *syspath) 1279 { 1280 struct udev *udev = NULL; 1281 struct udev_device *udevice = NULL; 1282 char *ret = NULL; 1283 1284 udev = udev_new(); 1285 if (udev == NULL) { 1286 g_debug("failed to query udev"); 1287 goto out; 1288 } 1289 udevice = udev_device_new_from_syspath(udev, syspath); 1290 if (udevice == NULL) { 1291 g_debug("failed to query udev for path: %s", syspath); 1292 goto out; 1293 } else { 1294 ret = g_strdup(udev_device_get_devnode(udevice)); 1295 } 1296 1297 out: 1298 udev_unref(udev); 1299 udev_device_unref(udevice); 1300 return ret; 1301 } 1302 1303 static void get_disk_deps(const char *disk_dir, GuestDiskInfo *disk) 1304 { 1305 g_autofree char *deps_dir = NULL; 1306 const gchar *dep; 1307 GDir *dp_deps = NULL; 1308 1309 /* List dependent disks */ 1310 deps_dir = g_strdup_printf("%s/slaves", disk_dir); 1311 g_debug(" listing entries in: %s", deps_dir); 1312 dp_deps = g_dir_open(deps_dir, 0, NULL); 1313 if (dp_deps == NULL) { 1314 g_debug("failed to list entries in %s", deps_dir); 1315 return; 1316 } 1317 disk->has_dependencies = true; 1318 while ((dep = g_dir_read_name(dp_deps)) != NULL) { 1319 g_autofree char *dep_dir = NULL; 1320 char *dev_name; 1321 1322 /* Add dependent disks */ 1323 dep_dir = g_strdup_printf("%s/%s", deps_dir, dep); 1324 dev_name = get_device_for_syspath(dep_dir); 1325 if (dev_name != NULL) { 1326 g_debug(" adding dependent device: %s", dev_name); 1327 QAPI_LIST_PREPEND(disk->dependencies, dev_name); 1328 } 1329 } 1330 g_dir_close(dp_deps); 1331 } 1332 1333 /* 1334 * Detect partitions subdirectory, name is "<disk_name><number>" or 1335 * "<disk_name>p<number>" 1336 * 1337 * @disk_name -- last component of /sys path (e.g. sda) 1338 * @disk_dir -- sys path of the disk (e.g. /sys/block/sda) 1339 * @disk_dev -- device node of the disk (e.g. /dev/sda) 1340 */ 1341 static GuestDiskInfoList *get_disk_partitions( 1342 GuestDiskInfoList *list, 1343 const char *disk_name, const char *disk_dir, 1344 const char *disk_dev) 1345 { 1346 GuestDiskInfoList *ret = list; 1347 struct dirent *de_disk; 1348 DIR *dp_disk = NULL; 1349 size_t len = strlen(disk_name); 1350 1351 dp_disk = opendir(disk_dir); 1352 while ((de_disk = readdir(dp_disk)) != NULL) { 1353 g_autofree char *partition_dir = NULL; 1354 char *dev_name; 1355 GuestDiskInfo *partition; 1356 1357 if (!(de_disk->d_type & DT_DIR)) { 1358 continue; 1359 } 1360 1361 if (!(strncmp(disk_name, de_disk->d_name, len) == 0 && 1362 ((*(de_disk->d_name + len) == 'p' && 1363 isdigit(*(de_disk->d_name + len + 1))) || 1364 isdigit(*(de_disk->d_name + len))))) { 1365 continue; 1366 } 1367 1368 partition_dir = g_strdup_printf("%s/%s", 1369 disk_dir, de_disk->d_name); 1370 dev_name = get_device_for_syspath(partition_dir); 1371 if (dev_name == NULL) { 1372 g_debug("Failed to get device name for syspath: %s", 1373 disk_dir); 1374 continue; 1375 } 1376 partition = g_new0(GuestDiskInfo, 1); 1377 partition->name = dev_name; 1378 partition->partition = true; 1379 partition->has_dependencies = true; 1380 /* Add parent disk as dependent for easier tracking of hierarchy */ 1381 QAPI_LIST_PREPEND(partition->dependencies, g_strdup(disk_dev)); 1382 1383 QAPI_LIST_PREPEND(ret, partition); 1384 } 1385 closedir(dp_disk); 1386 1387 return ret; 1388 } 1389 1390 static void get_nvme_smart(GuestDiskInfo *disk) 1391 { 1392 int fd; 1393 GuestNVMeSmart *smart; 1394 NvmeSmartLog log = {0}; 1395 struct nvme_admin_cmd cmd = { 1396 .opcode = NVME_ADM_CMD_GET_LOG_PAGE, 1397 .nsid = NVME_NSID_BROADCAST, 1398 .addr = (uintptr_t)&log, 1399 .data_len = sizeof(log), 1400 .cdw10 = NVME_LOG_SMART_INFO | (1 << 15) /* RAE bit */ 1401 | (((sizeof(log) >> 2) - 1) << 16) 1402 }; 1403 1404 fd = qga_open_cloexec(disk->name, O_RDONLY, 0); 1405 if (fd == -1) { 1406 g_debug("Failed to open device: %s: %s", disk->name, g_strerror(errno)); 1407 return; 1408 } 1409 1410 if (ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd)) { 1411 g_debug("Failed to get smart: %s: %s", disk->name, g_strerror(errno)); 1412 close(fd); 1413 return; 1414 } 1415 1416 disk->smart = g_new0(GuestDiskSmart, 1); 1417 disk->smart->type = GUEST_DISK_BUS_TYPE_NVME; 1418 1419 smart = &disk->smart->u.nvme; 1420 smart->critical_warning = log.critical_warning; 1421 smart->temperature = lduw_le_p(&log.temperature); /* unaligned field */ 1422 smart->available_spare = log.available_spare; 1423 smart->available_spare_threshold = log.available_spare_threshold; 1424 smart->percentage_used = log.percentage_used; 1425 smart->data_units_read_lo = le64_to_cpu(log.data_units_read[0]); 1426 smart->data_units_read_hi = le64_to_cpu(log.data_units_read[1]); 1427 smart->data_units_written_lo = le64_to_cpu(log.data_units_written[0]); 1428 smart->data_units_written_hi = le64_to_cpu(log.data_units_written[1]); 1429 smart->host_read_commands_lo = le64_to_cpu(log.host_read_commands[0]); 1430 smart->host_read_commands_hi = le64_to_cpu(log.host_read_commands[1]); 1431 smart->host_write_commands_lo = le64_to_cpu(log.host_write_commands[0]); 1432 smart->host_write_commands_hi = le64_to_cpu(log.host_write_commands[1]); 1433 smart->controller_busy_time_lo = le64_to_cpu(log.controller_busy_time[0]); 1434 smart->controller_busy_time_hi = le64_to_cpu(log.controller_busy_time[1]); 1435 smart->power_cycles_lo = le64_to_cpu(log.power_cycles[0]); 1436 smart->power_cycles_hi = le64_to_cpu(log.power_cycles[1]); 1437 smart->power_on_hours_lo = le64_to_cpu(log.power_on_hours[0]); 1438 smart->power_on_hours_hi = le64_to_cpu(log.power_on_hours[1]); 1439 smart->unsafe_shutdowns_lo = le64_to_cpu(log.unsafe_shutdowns[0]); 1440 smart->unsafe_shutdowns_hi = le64_to_cpu(log.unsafe_shutdowns[1]); 1441 smart->media_errors_lo = le64_to_cpu(log.media_errors[0]); 1442 smart->media_errors_hi = le64_to_cpu(log.media_errors[1]); 1443 smart->number_of_error_log_entries_lo = 1444 le64_to_cpu(log.number_of_error_log_entries[0]); 1445 smart->number_of_error_log_entries_hi = 1446 le64_to_cpu(log.number_of_error_log_entries[1]); 1447 1448 close(fd); 1449 } 1450 1451 static void get_disk_smart(GuestDiskInfo *disk) 1452 { 1453 if (disk->address 1454 && (disk->address->bus_type == GUEST_DISK_BUS_TYPE_NVME)) { 1455 get_nvme_smart(disk); 1456 } 1457 } 1458 1459 GuestDiskInfoList *qmp_guest_get_disks(Error **errp) 1460 { 1461 GuestDiskInfoList *ret = NULL; 1462 GuestDiskInfo *disk; 1463 DIR *dp = NULL; 1464 struct dirent *de = NULL; 1465 1466 g_debug("listing /sys/block directory"); 1467 dp = opendir("/sys/block"); 1468 if (dp == NULL) { 1469 error_setg_errno(errp, errno, "Can't open directory \"/sys/block\""); 1470 return NULL; 1471 } 1472 while ((de = readdir(dp)) != NULL) { 1473 g_autofree char *disk_dir = NULL, *line = NULL, 1474 *size_path = NULL; 1475 char *dev_name; 1476 Error *local_err = NULL; 1477 if (de->d_type != DT_LNK) { 1478 g_debug(" skipping entry: %s", de->d_name); 1479 continue; 1480 } 1481 1482 /* Check size and skip zero-sized disks */ 1483 g_debug(" checking disk size"); 1484 size_path = g_strdup_printf("/sys/block/%s/size", de->d_name); 1485 if (!g_file_get_contents(size_path, &line, NULL, NULL)) { 1486 g_debug(" failed to read disk size"); 1487 continue; 1488 } 1489 if (g_strcmp0(line, "0\n") == 0) { 1490 g_debug(" skipping zero-sized disk"); 1491 continue; 1492 } 1493 1494 g_debug(" adding %s", de->d_name); 1495 disk_dir = g_strdup_printf("/sys/block/%s", de->d_name); 1496 dev_name = get_device_for_syspath(disk_dir); 1497 if (dev_name == NULL) { 1498 g_debug("Failed to get device name for syspath: %s", 1499 disk_dir); 1500 continue; 1501 } 1502 disk = g_new0(GuestDiskInfo, 1); 1503 disk->name = dev_name; 1504 disk->partition = false; 1505 disk->alias = get_alias_for_syspath(disk_dir); 1506 QAPI_LIST_PREPEND(ret, disk); 1507 1508 /* Get address for non-virtual devices */ 1509 bool is_virtual = is_disk_virtual(disk_dir, &local_err); 1510 if (local_err != NULL) { 1511 g_debug(" failed to check disk path, ignoring error: %s", 1512 error_get_pretty(local_err)); 1513 error_free(local_err); 1514 local_err = NULL; 1515 /* Don't try to get the address */ 1516 is_virtual = true; 1517 } 1518 if (!is_virtual) { 1519 disk->address = get_disk_address(disk_dir, &local_err); 1520 if (local_err != NULL) { 1521 g_debug(" failed to get device info, ignoring error: %s", 1522 error_get_pretty(local_err)); 1523 error_free(local_err); 1524 local_err = NULL; 1525 } 1526 } 1527 1528 get_disk_deps(disk_dir, disk); 1529 get_disk_smart(disk); 1530 ret = get_disk_partitions(ret, de->d_name, disk_dir, dev_name); 1531 } 1532 1533 closedir(dp); 1534 1535 return ret; 1536 } 1537 1538 #else 1539 1540 GuestDiskInfoList *qmp_guest_get_disks(Error **errp) 1541 { 1542 error_setg(errp, QERR_UNSUPPORTED); 1543 return NULL; 1544 } 1545 1546 #endif 1547 1548 /* Return a list of the disk device(s)' info which @mount lies on */ 1549 static GuestFilesystemInfo *build_guest_fsinfo(struct FsMount *mount, 1550 Error **errp) 1551 { 1552 GuestFilesystemInfo *fs = g_malloc0(sizeof(*fs)); 1553 struct statvfs buf; 1554 unsigned long used, nonroot_total, fr_size; 1555 char *devpath = g_strdup_printf("/sys/dev/block/%u:%u", 1556 mount->devmajor, mount->devminor); 1557 1558 fs->mountpoint = g_strdup(mount->dirname); 1559 fs->type = g_strdup(mount->devtype); 1560 build_guest_fsinfo_for_device(devpath, fs, errp); 1561 1562 if (statvfs(fs->mountpoint, &buf) == 0) { 1563 fr_size = buf.f_frsize; 1564 used = buf.f_blocks - buf.f_bfree; 1565 nonroot_total = used + buf.f_bavail; 1566 fs->used_bytes = used * fr_size; 1567 fs->total_bytes = nonroot_total * fr_size; 1568 1569 fs->has_total_bytes = true; 1570 fs->has_used_bytes = true; 1571 } 1572 1573 g_free(devpath); 1574 1575 return fs; 1576 } 1577 1578 GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) 1579 { 1580 FsMountList mounts; 1581 struct FsMount *mount; 1582 GuestFilesystemInfoList *ret = NULL; 1583 Error *local_err = NULL; 1584 1585 QTAILQ_INIT(&mounts); 1586 if (!build_fs_mount_list(&mounts, &local_err)) { 1587 error_propagate(errp, local_err); 1588 return NULL; 1589 } 1590 1591 QTAILQ_FOREACH(mount, &mounts, next) { 1592 g_debug("Building guest fsinfo for '%s'", mount->dirname); 1593 1594 QAPI_LIST_PREPEND(ret, build_guest_fsinfo(mount, &local_err)); 1595 if (local_err) { 1596 error_propagate(errp, local_err); 1597 qapi_free_GuestFilesystemInfoList(ret); 1598 ret = NULL; 1599 break; 1600 } 1601 } 1602 1603 free_fs_mount_list(&mounts); 1604 return ret; 1605 } 1606 #endif /* CONFIG_FSFREEZE */ 1607 1608 #if defined(CONFIG_FSTRIM) 1609 /* 1610 * Walk list of mounted file systems in the guest, and trim them. 1611 */ 1612 GuestFilesystemTrimResponse * 1613 qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp) 1614 { 1615 GuestFilesystemTrimResponse *response; 1616 GuestFilesystemTrimResult *result; 1617 int ret = 0; 1618 FsMountList mounts; 1619 struct FsMount *mount; 1620 int fd; 1621 struct fstrim_range r; 1622 1623 slog("guest-fstrim called"); 1624 1625 QTAILQ_INIT(&mounts); 1626 if (!build_fs_mount_list(&mounts, errp)) { 1627 return NULL; 1628 } 1629 1630 response = g_malloc0(sizeof(*response)); 1631 1632 QTAILQ_FOREACH(mount, &mounts, next) { 1633 result = g_malloc0(sizeof(*result)); 1634 result->path = g_strdup(mount->dirname); 1635 1636 QAPI_LIST_PREPEND(response->paths, result); 1637 1638 fd = qga_open_cloexec(mount->dirname, O_RDONLY, 0); 1639 if (fd == -1) { 1640 result->error = g_strdup_printf("failed to open: %s", 1641 strerror(errno)); 1642 continue; 1643 } 1644 1645 /* We try to cull filesystems we know won't work in advance, but other 1646 * filesystems may not implement fstrim for less obvious reasons. 1647 * These will report EOPNOTSUPP; while in some other cases ENOTTY 1648 * will be reported (e.g. CD-ROMs). 1649 * Any other error means an unexpected error. 1650 */ 1651 r.start = 0; 1652 r.len = -1; 1653 r.minlen = has_minimum ? minimum : 0; 1654 ret = ioctl(fd, FITRIM, &r); 1655 if (ret == -1) { 1656 if (errno == ENOTTY || errno == EOPNOTSUPP) { 1657 result->error = g_strdup("trim not supported"); 1658 } else { 1659 result->error = g_strdup_printf("failed to trim: %s", 1660 strerror(errno)); 1661 } 1662 close(fd); 1663 continue; 1664 } 1665 1666 result->has_minimum = true; 1667 result->minimum = r.minlen; 1668 result->has_trimmed = true; 1669 result->trimmed = r.len; 1670 close(fd); 1671 } 1672 1673 free_fs_mount_list(&mounts); 1674 return response; 1675 } 1676 #endif /* CONFIG_FSTRIM */ 1677 1678 1679 #define LINUX_SYS_STATE_FILE "/sys/power/state" 1680 #define SUSPEND_SUPPORTED 0 1681 #define SUSPEND_NOT_SUPPORTED 1 1682 1683 typedef enum { 1684 SUSPEND_MODE_DISK = 0, 1685 SUSPEND_MODE_RAM = 1, 1686 SUSPEND_MODE_HYBRID = 2, 1687 } SuspendMode; 1688 1689 /* 1690 * Executes a command in a child process using g_spawn_sync, 1691 * returning an int >= 0 representing the exit status of the 1692 * process. 1693 * 1694 * If the program wasn't found in path, returns -1. 1695 * 1696 * If a problem happened when creating the child process, 1697 * returns -1 and errp is set. 1698 */ 1699 static int run_process_child(const char *command[], Error **errp) 1700 { 1701 int exit_status, spawn_flag; 1702 GError *g_err = NULL; 1703 bool success; 1704 1705 spawn_flag = G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | 1706 G_SPAWN_STDERR_TO_DEV_NULL; 1707 1708 success = g_spawn_sync(NULL, (char **)command, NULL, spawn_flag, 1709 NULL, NULL, NULL, NULL, 1710 &exit_status, &g_err); 1711 1712 if (success) { 1713 return WEXITSTATUS(exit_status); 1714 } 1715 1716 if (g_err && (g_err->code != G_SPAWN_ERROR_NOENT)) { 1717 error_setg(errp, "failed to create child process, error '%s'", 1718 g_err->message); 1719 } 1720 1721 g_error_free(g_err); 1722 return -1; 1723 } 1724 1725 static bool systemd_supports_mode(SuspendMode mode, Error **errp) 1726 { 1727 const char *systemctl_args[3] = {"systemd-hibernate", "systemd-suspend", 1728 "systemd-hybrid-sleep"}; 1729 const char *cmd[4] = {"systemctl", "status", systemctl_args[mode], NULL}; 1730 int status; 1731 1732 status = run_process_child(cmd, errp); 1733 1734 /* 1735 * systemctl status uses LSB return codes so we can expect 1736 * status > 0 and be ok. To assert if the guest has support 1737 * for the selected suspend mode, status should be < 4. 4 is 1738 * the code for unknown service status, the return value when 1739 * the service does not exist. A common value is status = 3 1740 * (program is not running). 1741 */ 1742 if (status > 0 && status < 4) { 1743 return true; 1744 } 1745 1746 return false; 1747 } 1748 1749 static void systemd_suspend(SuspendMode mode, Error **errp) 1750 { 1751 Error *local_err = NULL; 1752 const char *systemctl_args[3] = {"hibernate", "suspend", "hybrid-sleep"}; 1753 const char *cmd[3] = {"systemctl", systemctl_args[mode], NULL}; 1754 int status; 1755 1756 status = run_process_child(cmd, &local_err); 1757 1758 if (status == 0) { 1759 return; 1760 } 1761 1762 if ((status == -1) && !local_err) { 1763 error_setg(errp, "the helper program 'systemctl %s' was not found", 1764 systemctl_args[mode]); 1765 return; 1766 } 1767 1768 if (local_err) { 1769 error_propagate(errp, local_err); 1770 } else { 1771 error_setg(errp, "the helper program 'systemctl %s' returned an " 1772 "unexpected exit status code (%d)", 1773 systemctl_args[mode], status); 1774 } 1775 } 1776 1777 static bool pmutils_supports_mode(SuspendMode mode, Error **errp) 1778 { 1779 Error *local_err = NULL; 1780 const char *pmutils_args[3] = {"--hibernate", "--suspend", 1781 "--suspend-hybrid"}; 1782 const char *cmd[3] = {"pm-is-supported", pmutils_args[mode], NULL}; 1783 int status; 1784 1785 status = run_process_child(cmd, &local_err); 1786 1787 if (status == SUSPEND_SUPPORTED) { 1788 return true; 1789 } 1790 1791 if ((status == -1) && !local_err) { 1792 return false; 1793 } 1794 1795 if (local_err) { 1796 error_propagate(errp, local_err); 1797 } else { 1798 error_setg(errp, 1799 "the helper program '%s' returned an unexpected exit" 1800 " status code (%d)", "pm-is-supported", status); 1801 } 1802 1803 return false; 1804 } 1805 1806 static void pmutils_suspend(SuspendMode mode, Error **errp) 1807 { 1808 Error *local_err = NULL; 1809 const char *pmutils_binaries[3] = {"pm-hibernate", "pm-suspend", 1810 "pm-suspend-hybrid"}; 1811 const char *cmd[2] = {pmutils_binaries[mode], NULL}; 1812 int status; 1813 1814 status = run_process_child(cmd, &local_err); 1815 1816 if (status == 0) { 1817 return; 1818 } 1819 1820 if ((status == -1) && !local_err) { 1821 error_setg(errp, "the helper program '%s' was not found", 1822 pmutils_binaries[mode]); 1823 return; 1824 } 1825 1826 if (local_err) { 1827 error_propagate(errp, local_err); 1828 } else { 1829 error_setg(errp, 1830 "the helper program '%s' returned an unexpected exit" 1831 " status code (%d)", pmutils_binaries[mode], status); 1832 } 1833 } 1834 1835 static bool linux_sys_state_supports_mode(SuspendMode mode, Error **errp) 1836 { 1837 const char *sysfile_strs[3] = {"disk", "mem", NULL}; 1838 const char *sysfile_str = sysfile_strs[mode]; 1839 char buf[32]; /* hopefully big enough */ 1840 int fd; 1841 ssize_t ret; 1842 1843 if (!sysfile_str) { 1844 error_setg(errp, "unknown guest suspend mode"); 1845 return false; 1846 } 1847 1848 fd = open(LINUX_SYS_STATE_FILE, O_RDONLY); 1849 if (fd < 0) { 1850 return false; 1851 } 1852 1853 ret = read(fd, buf, sizeof(buf) - 1); 1854 close(fd); 1855 if (ret <= 0) { 1856 return false; 1857 } 1858 buf[ret] = '\0'; 1859 1860 if (strstr(buf, sysfile_str)) { 1861 return true; 1862 } 1863 return false; 1864 } 1865 1866 static void linux_sys_state_suspend(SuspendMode mode, Error **errp) 1867 { 1868 Error *local_err = NULL; 1869 const char *sysfile_strs[3] = {"disk", "mem", NULL}; 1870 const char *sysfile_str = sysfile_strs[mode]; 1871 pid_t pid; 1872 int status; 1873 1874 if (!sysfile_str) { 1875 error_setg(errp, "unknown guest suspend mode"); 1876 return; 1877 } 1878 1879 pid = fork(); 1880 if (!pid) { 1881 /* child */ 1882 int fd; 1883 1884 setsid(); 1885 reopen_fd_to_null(0); 1886 reopen_fd_to_null(1); 1887 reopen_fd_to_null(2); 1888 1889 fd = open(LINUX_SYS_STATE_FILE, O_WRONLY); 1890 if (fd < 0) { 1891 _exit(EXIT_FAILURE); 1892 } 1893 1894 if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) { 1895 _exit(EXIT_FAILURE); 1896 } 1897 1898 _exit(EXIT_SUCCESS); 1899 } else if (pid < 0) { 1900 error_setg_errno(errp, errno, "failed to create child process"); 1901 return; 1902 } 1903 1904 ga_wait_child(pid, &status, &local_err); 1905 if (local_err) { 1906 error_propagate(errp, local_err); 1907 return; 1908 } 1909 1910 if (WEXITSTATUS(status)) { 1911 error_setg(errp, "child process has failed to suspend"); 1912 } 1913 1914 } 1915 1916 static void guest_suspend(SuspendMode mode, Error **errp) 1917 { 1918 Error *local_err = NULL; 1919 bool mode_supported = false; 1920 1921 if (systemd_supports_mode(mode, &local_err)) { 1922 mode_supported = true; 1923 systemd_suspend(mode, &local_err); 1924 } 1925 1926 if (!local_err) { 1927 return; 1928 } 1929 1930 error_free(local_err); 1931 local_err = NULL; 1932 1933 if (pmutils_supports_mode(mode, &local_err)) { 1934 mode_supported = true; 1935 pmutils_suspend(mode, &local_err); 1936 } 1937 1938 if (!local_err) { 1939 return; 1940 } 1941 1942 error_free(local_err); 1943 local_err = NULL; 1944 1945 if (linux_sys_state_supports_mode(mode, &local_err)) { 1946 mode_supported = true; 1947 linux_sys_state_suspend(mode, &local_err); 1948 } 1949 1950 if (!mode_supported) { 1951 error_free(local_err); 1952 error_setg(errp, 1953 "the requested suspend mode is not supported by the guest"); 1954 } else { 1955 error_propagate(errp, local_err); 1956 } 1957 } 1958 1959 void qmp_guest_suspend_disk(Error **errp) 1960 { 1961 guest_suspend(SUSPEND_MODE_DISK, errp); 1962 } 1963 1964 void qmp_guest_suspend_ram(Error **errp) 1965 { 1966 guest_suspend(SUSPEND_MODE_RAM, errp); 1967 } 1968 1969 void qmp_guest_suspend_hybrid(Error **errp) 1970 { 1971 guest_suspend(SUSPEND_MODE_HYBRID, errp); 1972 } 1973 1974 /* Transfer online/offline status between @vcpu and the guest system. 1975 * 1976 * On input either @errp or *@errp must be NULL. 1977 * 1978 * In system-to-@vcpu direction, the following @vcpu fields are accessed: 1979 * - R: vcpu->logical_id 1980 * - W: vcpu->online 1981 * - W: vcpu->can_offline 1982 * 1983 * In @vcpu-to-system direction, the following @vcpu fields are accessed: 1984 * - R: vcpu->logical_id 1985 * - R: vcpu->online 1986 * 1987 * Written members remain unmodified on error. 1988 */ 1989 static void transfer_vcpu(GuestLogicalProcessor *vcpu, bool sys2vcpu, 1990 char *dirpath, Error **errp) 1991 { 1992 int fd; 1993 int res; 1994 int dirfd; 1995 static const char fn[] = "online"; 1996 1997 dirfd = open(dirpath, O_RDONLY | O_DIRECTORY); 1998 if (dirfd == -1) { 1999 error_setg_errno(errp, errno, "open(\"%s\")", dirpath); 2000 return; 2001 } 2002 2003 fd = openat(dirfd, fn, sys2vcpu ? O_RDONLY : O_RDWR); 2004 if (fd == -1) { 2005 if (errno != ENOENT) { 2006 error_setg_errno(errp, errno, "open(\"%s/%s\")", dirpath, fn); 2007 } else if (sys2vcpu) { 2008 vcpu->online = true; 2009 vcpu->can_offline = false; 2010 } else if (!vcpu->online) { 2011 error_setg(errp, "logical processor #%" PRId64 " can't be " 2012 "offlined", vcpu->logical_id); 2013 } /* otherwise pretend successful re-onlining */ 2014 } else { 2015 unsigned char status; 2016 2017 res = pread(fd, &status, 1, 0); 2018 if (res == -1) { 2019 error_setg_errno(errp, errno, "pread(\"%s/%s\")", dirpath, fn); 2020 } else if (res == 0) { 2021 error_setg(errp, "pread(\"%s/%s\"): unexpected EOF", dirpath, 2022 fn); 2023 } else if (sys2vcpu) { 2024 vcpu->online = (status != '0'); 2025 vcpu->can_offline = true; 2026 } else if (vcpu->online != (status != '0')) { 2027 status = '0' + vcpu->online; 2028 if (pwrite(fd, &status, 1, 0) == -1) { 2029 error_setg_errno(errp, errno, "pwrite(\"%s/%s\")", dirpath, 2030 fn); 2031 } 2032 } /* otherwise pretend successful re-(on|off)-lining */ 2033 2034 res = close(fd); 2035 g_assert(res == 0); 2036 } 2037 2038 res = close(dirfd); 2039 g_assert(res == 0); 2040 } 2041 2042 GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) 2043 { 2044 GuestLogicalProcessorList *head, **tail; 2045 const char *cpu_dir = "/sys/devices/system/cpu"; 2046 const gchar *line; 2047 g_autoptr(GDir) cpu_gdir = NULL; 2048 Error *local_err = NULL; 2049 2050 head = NULL; 2051 tail = &head; 2052 cpu_gdir = g_dir_open(cpu_dir, 0, NULL); 2053 2054 if (cpu_gdir == NULL) { 2055 error_setg_errno(errp, errno, "failed to list entries: %s", cpu_dir); 2056 return NULL; 2057 } 2058 2059 while (local_err == NULL && (line = g_dir_read_name(cpu_gdir)) != NULL) { 2060 GuestLogicalProcessor *vcpu; 2061 int64_t id; 2062 if (sscanf(line, "cpu%" PRId64, &id)) { 2063 g_autofree char *path = g_strdup_printf("/sys/devices/system/cpu/" 2064 "cpu%" PRId64 "/", id); 2065 vcpu = g_malloc0(sizeof *vcpu); 2066 vcpu->logical_id = id; 2067 vcpu->has_can_offline = true; /* lolspeak ftw */ 2068 transfer_vcpu(vcpu, true, path, &local_err); 2069 QAPI_LIST_APPEND(tail, vcpu); 2070 } 2071 } 2072 2073 if (local_err == NULL) { 2074 /* there's no guest with zero VCPUs */ 2075 g_assert(head != NULL); 2076 return head; 2077 } 2078 2079 qapi_free_GuestLogicalProcessorList(head); 2080 error_propagate(errp, local_err); 2081 return NULL; 2082 } 2083 2084 int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) 2085 { 2086 int64_t processed; 2087 Error *local_err = NULL; 2088 2089 processed = 0; 2090 while (vcpus != NULL) { 2091 char *path = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/", 2092 vcpus->value->logical_id); 2093 2094 transfer_vcpu(vcpus->value, false, path, &local_err); 2095 g_free(path); 2096 if (local_err != NULL) { 2097 break; 2098 } 2099 ++processed; 2100 vcpus = vcpus->next; 2101 } 2102 2103 if (local_err != NULL) { 2104 if (processed == 0) { 2105 error_propagate(errp, local_err); 2106 } else { 2107 error_free(local_err); 2108 } 2109 } 2110 2111 return processed; 2112 } 2113 #endif /* __linux__ */ 2114 2115 #if defined(__linux__) || defined(__FreeBSD__) 2116 void qmp_guest_set_user_password(const char *username, 2117 const char *password, 2118 bool crypted, 2119 Error **errp) 2120 { 2121 Error *local_err = NULL; 2122 char *passwd_path = NULL; 2123 pid_t pid; 2124 int status; 2125 int datafd[2] = { -1, -1 }; 2126 char *rawpasswddata = NULL; 2127 size_t rawpasswdlen; 2128 char *chpasswddata = NULL; 2129 size_t chpasswdlen; 2130 2131 rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, errp); 2132 if (!rawpasswddata) { 2133 return; 2134 } 2135 rawpasswddata = g_renew(char, rawpasswddata, rawpasswdlen + 1); 2136 rawpasswddata[rawpasswdlen] = '\0'; 2137 2138 if (strchr(rawpasswddata, '\n')) { 2139 error_setg(errp, "forbidden characters in raw password"); 2140 goto out; 2141 } 2142 2143 if (strchr(username, '\n') || 2144 strchr(username, ':')) { 2145 error_setg(errp, "forbidden characters in username"); 2146 goto out; 2147 } 2148 2149 #ifdef __FreeBSD__ 2150 chpasswddata = g_strdup(rawpasswddata); 2151 passwd_path = g_find_program_in_path("pw"); 2152 #else 2153 chpasswddata = g_strdup_printf("%s:%s\n", username, rawpasswddata); 2154 passwd_path = g_find_program_in_path("chpasswd"); 2155 #endif 2156 2157 chpasswdlen = strlen(chpasswddata); 2158 2159 if (!passwd_path) { 2160 error_setg(errp, "cannot find 'passwd' program in PATH"); 2161 goto out; 2162 } 2163 2164 if (!g_unix_open_pipe(datafd, FD_CLOEXEC, NULL)) { 2165 error_setg(errp, "cannot create pipe FDs"); 2166 goto out; 2167 } 2168 2169 pid = fork(); 2170 if (pid == 0) { 2171 close(datafd[1]); 2172 /* child */ 2173 setsid(); 2174 dup2(datafd[0], 0); 2175 reopen_fd_to_null(1); 2176 reopen_fd_to_null(2); 2177 2178 #ifdef __FreeBSD__ 2179 const char *h_arg; 2180 h_arg = (crypted) ? "-H" : "-h"; 2181 execl(passwd_path, "pw", "usermod", "-n", username, h_arg, "0", NULL); 2182 #else 2183 if (crypted) { 2184 execl(passwd_path, "chpasswd", "-e", NULL); 2185 } else { 2186 execl(passwd_path, "chpasswd", NULL); 2187 } 2188 #endif 2189 _exit(EXIT_FAILURE); 2190 } else if (pid < 0) { 2191 error_setg_errno(errp, errno, "failed to create child process"); 2192 goto out; 2193 } 2194 close(datafd[0]); 2195 datafd[0] = -1; 2196 2197 if (qemu_write_full(datafd[1], chpasswddata, chpasswdlen) != chpasswdlen) { 2198 error_setg_errno(errp, errno, "cannot write new account password"); 2199 goto out; 2200 } 2201 close(datafd[1]); 2202 datafd[1] = -1; 2203 2204 ga_wait_child(pid, &status, &local_err); 2205 if (local_err) { 2206 error_propagate(errp, local_err); 2207 goto out; 2208 } 2209 2210 if (!WIFEXITED(status)) { 2211 error_setg(errp, "child process has terminated abnormally"); 2212 goto out; 2213 } 2214 2215 if (WEXITSTATUS(status)) { 2216 error_setg(errp, "child process has failed to set user password"); 2217 goto out; 2218 } 2219 2220 out: 2221 g_free(chpasswddata); 2222 g_free(rawpasswddata); 2223 g_free(passwd_path); 2224 if (datafd[0] != -1) { 2225 close(datafd[0]); 2226 } 2227 if (datafd[1] != -1) { 2228 close(datafd[1]); 2229 } 2230 } 2231 #else /* __linux__ || __FreeBSD__ */ 2232 void qmp_guest_set_user_password(const char *username, 2233 const char *password, 2234 bool crypted, 2235 Error **errp) 2236 { 2237 error_setg(errp, QERR_UNSUPPORTED); 2238 } 2239 #endif /* __linux__ || __FreeBSD__ */ 2240 2241 #ifdef __linux__ 2242 static void ga_read_sysfs_file(int dirfd, const char *pathname, char *buf, 2243 int size, Error **errp) 2244 { 2245 int fd; 2246 int res; 2247 2248 errno = 0; 2249 fd = openat(dirfd, pathname, O_RDONLY); 2250 if (fd == -1) { 2251 error_setg_errno(errp, errno, "open sysfs file \"%s\"", pathname); 2252 return; 2253 } 2254 2255 res = pread(fd, buf, size, 0); 2256 if (res == -1) { 2257 error_setg_errno(errp, errno, "pread sysfs file \"%s\"", pathname); 2258 } else if (res == 0) { 2259 error_setg(errp, "pread sysfs file \"%s\": unexpected EOF", pathname); 2260 } 2261 close(fd); 2262 } 2263 2264 static void ga_write_sysfs_file(int dirfd, const char *pathname, 2265 const char *buf, int size, Error **errp) 2266 { 2267 int fd; 2268 2269 errno = 0; 2270 fd = openat(dirfd, pathname, O_WRONLY); 2271 if (fd == -1) { 2272 error_setg_errno(errp, errno, "open sysfs file \"%s\"", pathname); 2273 return; 2274 } 2275 2276 if (pwrite(fd, buf, size, 0) == -1) { 2277 error_setg_errno(errp, errno, "pwrite sysfs file \"%s\"", pathname); 2278 } 2279 2280 close(fd); 2281 } 2282 2283 /* Transfer online/offline status between @mem_blk and the guest system. 2284 * 2285 * On input either @errp or *@errp must be NULL. 2286 * 2287 * In system-to-@mem_blk direction, the following @mem_blk fields are accessed: 2288 * - R: mem_blk->phys_index 2289 * - W: mem_blk->online 2290 * - W: mem_blk->can_offline 2291 * 2292 * In @mem_blk-to-system direction, the following @mem_blk fields are accessed: 2293 * - R: mem_blk->phys_index 2294 * - R: mem_blk->online 2295 *- R: mem_blk->can_offline 2296 * Written members remain unmodified on error. 2297 */ 2298 static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk, 2299 GuestMemoryBlockResponse *result, 2300 Error **errp) 2301 { 2302 char *dirpath; 2303 int dirfd; 2304 char *status; 2305 Error *local_err = NULL; 2306 2307 if (!sys2memblk) { 2308 DIR *dp; 2309 2310 if (!result) { 2311 error_setg(errp, "Internal error, 'result' should not be NULL"); 2312 return; 2313 } 2314 errno = 0; 2315 dp = opendir("/sys/devices/system/memory/"); 2316 /* if there is no 'memory' directory in sysfs, 2317 * we think this VM does not support online/offline memory block, 2318 * any other solution? 2319 */ 2320 if (!dp) { 2321 if (errno == ENOENT) { 2322 result->response = 2323 GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED; 2324 } 2325 goto out1; 2326 } 2327 closedir(dp); 2328 } 2329 2330 dirpath = g_strdup_printf("/sys/devices/system/memory/memory%" PRId64 "/", 2331 mem_blk->phys_index); 2332 dirfd = open(dirpath, O_RDONLY | O_DIRECTORY); 2333 if (dirfd == -1) { 2334 if (sys2memblk) { 2335 error_setg_errno(errp, errno, "open(\"%s\")", dirpath); 2336 } else { 2337 if (errno == ENOENT) { 2338 result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_NOT_FOUND; 2339 } else { 2340 result->response = 2341 GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED; 2342 } 2343 } 2344 g_free(dirpath); 2345 goto out1; 2346 } 2347 g_free(dirpath); 2348 2349 status = g_malloc0(10); 2350 ga_read_sysfs_file(dirfd, "state", status, 10, &local_err); 2351 if (local_err) { 2352 /* treat with sysfs file that not exist in old kernel */ 2353 if (errno == ENOENT) { 2354 error_free(local_err); 2355 if (sys2memblk) { 2356 mem_blk->online = true; 2357 mem_blk->can_offline = false; 2358 } else if (!mem_blk->online) { 2359 result->response = 2360 GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED; 2361 } 2362 } else { 2363 if (sys2memblk) { 2364 error_propagate(errp, local_err); 2365 } else { 2366 error_free(local_err); 2367 result->response = 2368 GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED; 2369 } 2370 } 2371 goto out2; 2372 } 2373 2374 if (sys2memblk) { 2375 char removable = '0'; 2376 2377 mem_blk->online = (strncmp(status, "online", 6) == 0); 2378 2379 ga_read_sysfs_file(dirfd, "removable", &removable, 1, &local_err); 2380 if (local_err) { 2381 /* if no 'removable' file, it doesn't support offline mem blk */ 2382 if (errno == ENOENT) { 2383 error_free(local_err); 2384 mem_blk->can_offline = false; 2385 } else { 2386 error_propagate(errp, local_err); 2387 } 2388 } else { 2389 mem_blk->can_offline = (removable != '0'); 2390 } 2391 } else { 2392 if (mem_blk->online != (strncmp(status, "online", 6) == 0)) { 2393 const char *new_state = mem_blk->online ? "online" : "offline"; 2394 2395 ga_write_sysfs_file(dirfd, "state", new_state, strlen(new_state), 2396 &local_err); 2397 if (local_err) { 2398 error_free(local_err); 2399 result->response = 2400 GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED; 2401 goto out2; 2402 } 2403 2404 result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_SUCCESS; 2405 result->has_error_code = false; 2406 } /* otherwise pretend successful re-(on|off)-lining */ 2407 } 2408 g_free(status); 2409 close(dirfd); 2410 return; 2411 2412 out2: 2413 g_free(status); 2414 close(dirfd); 2415 out1: 2416 if (!sys2memblk) { 2417 result->has_error_code = true; 2418 result->error_code = errno; 2419 } 2420 } 2421 2422 GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp) 2423 { 2424 GuestMemoryBlockList *head, **tail; 2425 Error *local_err = NULL; 2426 struct dirent *de; 2427 DIR *dp; 2428 2429 head = NULL; 2430 tail = &head; 2431 2432 dp = opendir("/sys/devices/system/memory/"); 2433 if (!dp) { 2434 /* it's ok if this happens to be a system that doesn't expose 2435 * memory blocks via sysfs, but otherwise we should report 2436 * an error 2437 */ 2438 if (errno != ENOENT) { 2439 error_setg_errno(errp, errno, "Can't open directory" 2440 "\"/sys/devices/system/memory/\""); 2441 } 2442 return NULL; 2443 } 2444 2445 /* Note: the phys_index of memory block may be discontinuous, 2446 * this is because a memblk is the unit of the Sparse Memory design, which 2447 * allows discontinuous memory ranges (ex. NUMA), so here we should 2448 * traverse the memory block directory. 2449 */ 2450 while ((de = readdir(dp)) != NULL) { 2451 GuestMemoryBlock *mem_blk; 2452 2453 if ((strncmp(de->d_name, "memory", 6) != 0) || 2454 !(de->d_type & DT_DIR)) { 2455 continue; 2456 } 2457 2458 mem_blk = g_malloc0(sizeof *mem_blk); 2459 /* The d_name is "memoryXXX", phys_index is block id, same as XXX */ 2460 mem_blk->phys_index = strtoul(&de->d_name[6], NULL, 10); 2461 mem_blk->has_can_offline = true; /* lolspeak ftw */ 2462 transfer_memory_block(mem_blk, true, NULL, &local_err); 2463 if (local_err) { 2464 break; 2465 } 2466 2467 QAPI_LIST_APPEND(tail, mem_blk); 2468 } 2469 2470 closedir(dp); 2471 if (local_err == NULL) { 2472 /* there's no guest with zero memory blocks */ 2473 if (head == NULL) { 2474 error_setg(errp, "guest reported zero memory blocks!"); 2475 } 2476 return head; 2477 } 2478 2479 qapi_free_GuestMemoryBlockList(head); 2480 error_propagate(errp, local_err); 2481 return NULL; 2482 } 2483 2484 GuestMemoryBlockResponseList * 2485 qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp) 2486 { 2487 GuestMemoryBlockResponseList *head, **tail; 2488 Error *local_err = NULL; 2489 2490 head = NULL; 2491 tail = &head; 2492 2493 while (mem_blks != NULL) { 2494 GuestMemoryBlockResponse *result; 2495 GuestMemoryBlock *current_mem_blk = mem_blks->value; 2496 2497 result = g_malloc0(sizeof(*result)); 2498 result->phys_index = current_mem_blk->phys_index; 2499 transfer_memory_block(current_mem_blk, false, result, &local_err); 2500 if (local_err) { /* should never happen */ 2501 goto err; 2502 } 2503 2504 QAPI_LIST_APPEND(tail, result); 2505 mem_blks = mem_blks->next; 2506 } 2507 2508 return head; 2509 err: 2510 qapi_free_GuestMemoryBlockResponseList(head); 2511 error_propagate(errp, local_err); 2512 return NULL; 2513 } 2514 2515 GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp) 2516 { 2517 Error *local_err = NULL; 2518 char *dirpath; 2519 int dirfd; 2520 char *buf; 2521 GuestMemoryBlockInfo *info; 2522 2523 dirpath = g_strdup_printf("/sys/devices/system/memory/"); 2524 dirfd = open(dirpath, O_RDONLY | O_DIRECTORY); 2525 if (dirfd == -1) { 2526 error_setg_errno(errp, errno, "open(\"%s\")", dirpath); 2527 g_free(dirpath); 2528 return NULL; 2529 } 2530 g_free(dirpath); 2531 2532 buf = g_malloc0(20); 2533 ga_read_sysfs_file(dirfd, "block_size_bytes", buf, 20, &local_err); 2534 close(dirfd); 2535 if (local_err) { 2536 g_free(buf); 2537 error_propagate(errp, local_err); 2538 return NULL; 2539 } 2540 2541 info = g_new0(GuestMemoryBlockInfo, 1); 2542 info->size = strtol(buf, NULL, 16); /* the unit is bytes */ 2543 2544 g_free(buf); 2545 2546 return info; 2547 } 2548 2549 #define MAX_NAME_LEN 128 2550 static GuestDiskStatsInfoList *guest_get_diskstats(Error **errp) 2551 { 2552 #ifdef CONFIG_LINUX 2553 GuestDiskStatsInfoList *head = NULL, **tail = &head; 2554 const char *diskstats = "/proc/diskstats"; 2555 FILE *fp; 2556 size_t n; 2557 char *line = NULL; 2558 2559 fp = fopen(diskstats, "r"); 2560 if (fp == NULL) { 2561 error_setg_errno(errp, errno, "open(\"%s\")", diskstats); 2562 return NULL; 2563 } 2564 2565 while (getline(&line, &n, fp) != -1) { 2566 g_autofree GuestDiskStatsInfo *diskstatinfo = NULL; 2567 g_autofree GuestDiskStats *diskstat = NULL; 2568 char dev_name[MAX_NAME_LEN]; 2569 unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks, dc_ticks, fl_ticks; 2570 unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios; 2571 unsigned long wr_merges, rd_sec_or_wr_ios, wr_sec; 2572 unsigned long dc_ios, dc_merges, dc_sec, fl_ios; 2573 unsigned int major, minor; 2574 int i; 2575 2576 i = sscanf(line, "%u %u %s %lu %lu %lu" 2577 "%lu %lu %lu %lu %u %u %u %u" 2578 "%lu %lu %lu %u %lu %u", 2579 &major, &minor, dev_name, 2580 &rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios, 2581 &rd_ticks_or_wr_sec, &wr_ios, &wr_merges, &wr_sec, 2582 &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks, 2583 &dc_ios, &dc_merges, &dc_sec, &dc_ticks, 2584 &fl_ios, &fl_ticks); 2585 2586 if (i < 7) { 2587 continue; 2588 } 2589 2590 diskstatinfo = g_new0(GuestDiskStatsInfo, 1); 2591 diskstatinfo->name = g_strdup(dev_name); 2592 diskstatinfo->major = major; 2593 diskstatinfo->minor = minor; 2594 2595 diskstat = g_new0(GuestDiskStats, 1); 2596 if (i == 7) { 2597 diskstat->has_read_ios = true; 2598 diskstat->read_ios = rd_ios; 2599 diskstat->has_read_sectors = true; 2600 diskstat->read_sectors = rd_merges_or_rd_sec; 2601 diskstat->has_write_ios = true; 2602 diskstat->write_ios = rd_sec_or_wr_ios; 2603 diskstat->has_write_sectors = true; 2604 diskstat->write_sectors = rd_ticks_or_wr_sec; 2605 } 2606 if (i >= 14) { 2607 diskstat->has_read_ios = true; 2608 diskstat->read_ios = rd_ios; 2609 diskstat->has_read_sectors = true; 2610 diskstat->read_sectors = rd_sec_or_wr_ios; 2611 diskstat->has_read_merges = true; 2612 diskstat->read_merges = rd_merges_or_rd_sec; 2613 diskstat->has_read_ticks = true; 2614 diskstat->read_ticks = rd_ticks_or_wr_sec; 2615 diskstat->has_write_ios = true; 2616 diskstat->write_ios = wr_ios; 2617 diskstat->has_write_sectors = true; 2618 diskstat->write_sectors = wr_sec; 2619 diskstat->has_write_merges = true; 2620 diskstat->write_merges = wr_merges; 2621 diskstat->has_write_ticks = true; 2622 diskstat->write_ticks = wr_ticks; 2623 diskstat->has_ios_pgr = true; 2624 diskstat->ios_pgr = ios_pgr; 2625 diskstat->has_total_ticks = true; 2626 diskstat->total_ticks = tot_ticks; 2627 diskstat->has_weight_ticks = true; 2628 diskstat->weight_ticks = rq_ticks; 2629 } 2630 if (i >= 18) { 2631 diskstat->has_discard_ios = true; 2632 diskstat->discard_ios = dc_ios; 2633 diskstat->has_discard_merges = true; 2634 diskstat->discard_merges = dc_merges; 2635 diskstat->has_discard_sectors = true; 2636 diskstat->discard_sectors = dc_sec; 2637 diskstat->has_discard_ticks = true; 2638 diskstat->discard_ticks = dc_ticks; 2639 } 2640 if (i >= 20) { 2641 diskstat->has_flush_ios = true; 2642 diskstat->flush_ios = fl_ios; 2643 diskstat->has_flush_ticks = true; 2644 diskstat->flush_ticks = fl_ticks; 2645 } 2646 2647 diskstatinfo->stats = g_steal_pointer(&diskstat); 2648 QAPI_LIST_APPEND(tail, diskstatinfo); 2649 diskstatinfo = NULL; 2650 } 2651 free(line); 2652 fclose(fp); 2653 return head; 2654 #else 2655 g_debug("disk stats reporting available only for Linux"); 2656 return NULL; 2657 #endif 2658 } 2659 2660 GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp) 2661 { 2662 return guest_get_diskstats(errp); 2663 } 2664 2665 GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp) 2666 { 2667 GuestCpuStatsList *head = NULL, **tail = &head; 2668 const char *cpustats = "/proc/stat"; 2669 int clk_tck = sysconf(_SC_CLK_TCK); 2670 FILE *fp; 2671 size_t n; 2672 char *line = NULL; 2673 2674 fp = fopen(cpustats, "r"); 2675 if (fp == NULL) { 2676 error_setg_errno(errp, errno, "open(\"%s\")", cpustats); 2677 return NULL; 2678 } 2679 2680 while (getline(&line, &n, fp) != -1) { 2681 GuestCpuStats *cpustat = NULL; 2682 GuestLinuxCpuStats *linuxcpustat; 2683 int i; 2684 unsigned long user, system, idle, iowait, irq, softirq, steal, guest; 2685 unsigned long nice, guest_nice; 2686 char name[64]; 2687 2688 i = sscanf(line, "%s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", 2689 name, &user, &nice, &system, &idle, &iowait, &irq, &softirq, 2690 &steal, &guest, &guest_nice); 2691 2692 /* drop "cpu 1 2 3 ...", get "cpuX 1 2 3 ..." only */ 2693 if ((i == EOF) || strncmp(name, "cpu", 3) || (name[3] == '\0')) { 2694 continue; 2695 } 2696 2697 if (i < 5) { 2698 slog("Parsing cpu stat from %s failed, see \"man proc\"", cpustats); 2699 break; 2700 } 2701 2702 cpustat = g_new0(GuestCpuStats, 1); 2703 cpustat->type = GUEST_CPU_STATS_TYPE_LINUX; 2704 2705 linuxcpustat = &cpustat->u.q_linux; 2706 linuxcpustat->cpu = atoi(&name[3]); 2707 linuxcpustat->user = user * 1000 / clk_tck; 2708 linuxcpustat->nice = nice * 1000 / clk_tck; 2709 linuxcpustat->system = system * 1000 / clk_tck; 2710 linuxcpustat->idle = idle * 1000 / clk_tck; 2711 2712 if (i > 5) { 2713 linuxcpustat->has_iowait = true; 2714 linuxcpustat->iowait = iowait * 1000 / clk_tck; 2715 } 2716 2717 if (i > 6) { 2718 linuxcpustat->has_irq = true; 2719 linuxcpustat->irq = irq * 1000 / clk_tck; 2720 linuxcpustat->has_softirq = true; 2721 linuxcpustat->softirq = softirq * 1000 / clk_tck; 2722 } 2723 2724 if (i > 8) { 2725 linuxcpustat->has_steal = true; 2726 linuxcpustat->steal = steal * 1000 / clk_tck; 2727 } 2728 2729 if (i > 9) { 2730 linuxcpustat->has_guest = true; 2731 linuxcpustat->guest = guest * 1000 / clk_tck; 2732 } 2733 2734 if (i > 10) { 2735 linuxcpustat->has_guest = true; 2736 linuxcpustat->guest = guest * 1000 / clk_tck; 2737 linuxcpustat->has_guestnice = true; 2738 linuxcpustat->guestnice = guest_nice * 1000 / clk_tck; 2739 } 2740 2741 QAPI_LIST_APPEND(tail, cpustat); 2742 } 2743 2744 free(line); 2745 fclose(fp); 2746 return head; 2747 } 2748 2749 #else /* defined(__linux__) */ 2750 2751 void qmp_guest_suspend_disk(Error **errp) 2752 { 2753 error_setg(errp, QERR_UNSUPPORTED); 2754 } 2755 2756 void qmp_guest_suspend_ram(Error **errp) 2757 { 2758 error_setg(errp, QERR_UNSUPPORTED); 2759 } 2760 2761 void qmp_guest_suspend_hybrid(Error **errp) 2762 { 2763 error_setg(errp, QERR_UNSUPPORTED); 2764 } 2765 2766 GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) 2767 { 2768 error_setg(errp, QERR_UNSUPPORTED); 2769 return NULL; 2770 } 2771 2772 int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) 2773 { 2774 error_setg(errp, QERR_UNSUPPORTED); 2775 return -1; 2776 } 2777 2778 GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp) 2779 { 2780 error_setg(errp, QERR_UNSUPPORTED); 2781 return NULL; 2782 } 2783 2784 GuestMemoryBlockResponseList * 2785 qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp) 2786 { 2787 error_setg(errp, QERR_UNSUPPORTED); 2788 return NULL; 2789 } 2790 2791 GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp) 2792 { 2793 error_setg(errp, QERR_UNSUPPORTED); 2794 return NULL; 2795 } 2796 2797 #endif 2798 2799 #ifdef HAVE_GETIFADDRS 2800 static GuestNetworkInterface * 2801 guest_find_interface(GuestNetworkInterfaceList *head, 2802 const char *name) 2803 { 2804 for (; head; head = head->next) { 2805 if (strcmp(head->value->name, name) == 0) { 2806 return head->value; 2807 } 2808 } 2809 2810 return NULL; 2811 } 2812 2813 static int guest_get_network_stats(const char *name, 2814 GuestNetworkInterfaceStat *stats) 2815 { 2816 #ifdef CONFIG_LINUX 2817 int name_len; 2818 char const *devinfo = "/proc/net/dev"; 2819 FILE *fp; 2820 char *line = NULL, *colon; 2821 size_t n = 0; 2822 fp = fopen(devinfo, "r"); 2823 if (!fp) { 2824 g_debug("failed to open network stats %s: %s", devinfo, 2825 g_strerror(errno)); 2826 return -1; 2827 } 2828 name_len = strlen(name); 2829 while (getline(&line, &n, fp) != -1) { 2830 long long dummy; 2831 long long rx_bytes; 2832 long long rx_packets; 2833 long long rx_errs; 2834 long long rx_dropped; 2835 long long tx_bytes; 2836 long long tx_packets; 2837 long long tx_errs; 2838 long long tx_dropped; 2839 char *trim_line; 2840 trim_line = g_strchug(line); 2841 if (trim_line[0] == '\0') { 2842 continue; 2843 } 2844 colon = strchr(trim_line, ':'); 2845 if (!colon) { 2846 continue; 2847 } 2848 if (colon - name_len == trim_line && 2849 strncmp(trim_line, name, name_len) == 0) { 2850 if (sscanf(colon + 1, 2851 "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld", 2852 &rx_bytes, &rx_packets, &rx_errs, &rx_dropped, 2853 &dummy, &dummy, &dummy, &dummy, 2854 &tx_bytes, &tx_packets, &tx_errs, &tx_dropped, 2855 &dummy, &dummy, &dummy, &dummy) != 16) { 2856 continue; 2857 } 2858 stats->rx_bytes = rx_bytes; 2859 stats->rx_packets = rx_packets; 2860 stats->rx_errs = rx_errs; 2861 stats->rx_dropped = rx_dropped; 2862 stats->tx_bytes = tx_bytes; 2863 stats->tx_packets = tx_packets; 2864 stats->tx_errs = tx_errs; 2865 stats->tx_dropped = tx_dropped; 2866 fclose(fp); 2867 g_free(line); 2868 return 0; 2869 } 2870 } 2871 fclose(fp); 2872 g_free(line); 2873 g_debug("/proc/net/dev: Interface '%s' not found", name); 2874 #else /* !CONFIG_LINUX */ 2875 g_debug("Network stats reporting available only for Linux"); 2876 #endif /* !CONFIG_LINUX */ 2877 return -1; 2878 } 2879 2880 #ifndef CONFIG_BSD 2881 /* 2882 * Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a 2883 * buffer with ETHER_ADDR_LEN length at least. 2884 * 2885 * Returns false in case of an error, otherwise true. "obtained" argument 2886 * is true if a MAC address was obtained successful, otherwise false. 2887 */ 2888 bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf, 2889 bool *obtained, Error **errp) 2890 { 2891 struct ifreq ifr; 2892 int sock; 2893 2894 *obtained = false; 2895 2896 /* we haven't obtained HW address yet */ 2897 sock = socket(PF_INET, SOCK_STREAM, 0); 2898 if (sock == -1) { 2899 error_setg_errno(errp, errno, "failed to create socket"); 2900 return false; 2901 } 2902 2903 memset(&ifr, 0, sizeof(ifr)); 2904 pstrcpy(ifr.ifr_name, IF_NAMESIZE, ifa->ifa_name); 2905 if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { 2906 /* 2907 * We can't get the hw addr of this interface, but that's not a 2908 * fatal error. 2909 */ 2910 if (errno == EADDRNOTAVAIL) { 2911 /* The interface doesn't have a hw addr (e.g. loopback). */ 2912 g_debug("failed to get MAC address of %s: %s", 2913 ifa->ifa_name, strerror(errno)); 2914 } else{ 2915 g_warning("failed to get MAC address of %s: %s", 2916 ifa->ifa_name, strerror(errno)); 2917 } 2918 } else { 2919 #ifdef CONFIG_SOLARIS 2920 memcpy(buf, &ifr.ifr_addr.sa_data, ETHER_ADDR_LEN); 2921 #else 2922 memcpy(buf, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); 2923 #endif 2924 *obtained = true; 2925 } 2926 close(sock); 2927 return true; 2928 } 2929 #endif /* CONFIG_BSD */ 2930 2931 /* 2932 * Build information about guest interfaces 2933 */ 2934 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) 2935 { 2936 GuestNetworkInterfaceList *head = NULL, **tail = &head; 2937 struct ifaddrs *ifap, *ifa; 2938 2939 if (getifaddrs(&ifap) < 0) { 2940 error_setg_errno(errp, errno, "getifaddrs failed"); 2941 goto error; 2942 } 2943 2944 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 2945 GuestNetworkInterface *info; 2946 GuestIpAddressList **address_tail; 2947 GuestIpAddress *address_item = NULL; 2948 GuestNetworkInterfaceStat *interface_stat = NULL; 2949 char addr4[INET_ADDRSTRLEN]; 2950 char addr6[INET6_ADDRSTRLEN]; 2951 unsigned char mac_addr[ETHER_ADDR_LEN]; 2952 bool obtained; 2953 void *p; 2954 2955 g_debug("Processing %s interface", ifa->ifa_name); 2956 2957 info = guest_find_interface(head, ifa->ifa_name); 2958 2959 if (!info) { 2960 info = g_malloc0(sizeof(*info)); 2961 info->name = g_strdup(ifa->ifa_name); 2962 2963 QAPI_LIST_APPEND(tail, info); 2964 } 2965 2966 if (!info->hardware_address) { 2967 if (!guest_get_hw_addr(ifa, mac_addr, &obtained, errp)) { 2968 goto error; 2969 } 2970 if (obtained) { 2971 info->hardware_address = 2972 g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", 2973 (int) mac_addr[0], (int) mac_addr[1], 2974 (int) mac_addr[2], (int) mac_addr[3], 2975 (int) mac_addr[4], (int) mac_addr[5]); 2976 } 2977 } 2978 2979 if (ifa->ifa_addr && 2980 ifa->ifa_addr->sa_family == AF_INET) { 2981 /* interface with IPv4 address */ 2982 p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; 2983 if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) { 2984 error_setg_errno(errp, errno, "inet_ntop failed"); 2985 goto error; 2986 } 2987 2988 address_item = g_malloc0(sizeof(*address_item)); 2989 address_item->ip_address = g_strdup(addr4); 2990 address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4; 2991 2992 if (ifa->ifa_netmask) { 2993 /* Count the number of set bits in netmask. 2994 * This is safe as '1' and '0' cannot be shuffled in netmask. */ 2995 p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr; 2996 address_item->prefix = ctpop32(((uint32_t *) p)[0]); 2997 } 2998 } else if (ifa->ifa_addr && 2999 ifa->ifa_addr->sa_family == AF_INET6) { 3000 /* interface with IPv6 address */ 3001 p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; 3002 if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) { 3003 error_setg_errno(errp, errno, "inet_ntop failed"); 3004 goto error; 3005 } 3006 3007 address_item = g_malloc0(sizeof(*address_item)); 3008 address_item->ip_address = g_strdup(addr6); 3009 address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6; 3010 3011 if (ifa->ifa_netmask) { 3012 /* Count the number of set bits in netmask. 3013 * This is safe as '1' and '0' cannot be shuffled in netmask. */ 3014 p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr; 3015 address_item->prefix = 3016 ctpop32(((uint32_t *) p)[0]) + 3017 ctpop32(((uint32_t *) p)[1]) + 3018 ctpop32(((uint32_t *) p)[2]) + 3019 ctpop32(((uint32_t *) p)[3]); 3020 } 3021 } 3022 3023 if (!address_item) { 3024 continue; 3025 } 3026 3027 address_tail = &info->ip_addresses; 3028 while (*address_tail) { 3029 address_tail = &(*address_tail)->next; 3030 } 3031 QAPI_LIST_APPEND(address_tail, address_item); 3032 3033 info->has_ip_addresses = true; 3034 3035 if (!info->statistics) { 3036 interface_stat = g_malloc0(sizeof(*interface_stat)); 3037 if (guest_get_network_stats(info->name, interface_stat) == -1) { 3038 g_free(interface_stat); 3039 } else { 3040 info->statistics = interface_stat; 3041 } 3042 } 3043 } 3044 3045 freeifaddrs(ifap); 3046 return head; 3047 3048 error: 3049 freeifaddrs(ifap); 3050 qapi_free_GuestNetworkInterfaceList(head); 3051 return NULL; 3052 } 3053 3054 #else 3055 3056 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) 3057 { 3058 error_setg(errp, QERR_UNSUPPORTED); 3059 return NULL; 3060 } 3061 3062 #endif /* HAVE_GETIFADDRS */ 3063 3064 #if !defined(CONFIG_FSFREEZE) 3065 3066 GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) 3067 { 3068 error_setg(errp, QERR_UNSUPPORTED); 3069 return NULL; 3070 } 3071 3072 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp) 3073 { 3074 error_setg(errp, QERR_UNSUPPORTED); 3075 3076 return 0; 3077 } 3078 3079 int64_t qmp_guest_fsfreeze_freeze(Error **errp) 3080 { 3081 error_setg(errp, QERR_UNSUPPORTED); 3082 3083 return 0; 3084 } 3085 3086 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, 3087 strList *mountpoints, 3088 Error **errp) 3089 { 3090 error_setg(errp, QERR_UNSUPPORTED); 3091 3092 return 0; 3093 } 3094 3095 int64_t qmp_guest_fsfreeze_thaw(Error **errp) 3096 { 3097 error_setg(errp, QERR_UNSUPPORTED); 3098 3099 return 0; 3100 } 3101 3102 GuestDiskInfoList *qmp_guest_get_disks(Error **errp) 3103 { 3104 error_setg(errp, QERR_UNSUPPORTED); 3105 return NULL; 3106 } 3107 3108 GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp) 3109 { 3110 error_setg(errp, QERR_UNSUPPORTED); 3111 return NULL; 3112 } 3113 3114 GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp) 3115 { 3116 error_setg(errp, QERR_UNSUPPORTED); 3117 return NULL; 3118 } 3119 3120 #endif /* CONFIG_FSFREEZE */ 3121 3122 #if !defined(CONFIG_FSTRIM) 3123 GuestFilesystemTrimResponse * 3124 qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp) 3125 { 3126 error_setg(errp, QERR_UNSUPPORTED); 3127 return NULL; 3128 } 3129 #endif 3130 3131 /* add unsupported commands to the list of blocked RPCs */ 3132 GList *ga_command_init_blockedrpcs(GList *blockedrpcs) 3133 { 3134 #if !defined(__linux__) 3135 { 3136 const char *list[] = { 3137 "guest-suspend-disk", "guest-suspend-ram", 3138 "guest-suspend-hybrid", "guest-get-vcpus", "guest-set-vcpus", 3139 "guest-get-memory-blocks", "guest-set-memory-blocks", 3140 "guest-get-memory-block-size", "guest-get-memory-block-info", 3141 NULL}; 3142 char **p = (char **)list; 3143 3144 while (*p) { 3145 blockedrpcs = g_list_append(blockedrpcs, g_strdup(*p++)); 3146 } 3147 } 3148 #endif 3149 3150 #if !defined(HAVE_GETIFADDRS) 3151 blockedrpcs = g_list_append(blockedrpcs, 3152 g_strdup("guest-network-get-interfaces")); 3153 #endif 3154 3155 #if !defined(CONFIG_FSFREEZE) 3156 { 3157 const char *list[] = { 3158 "guest-get-fsinfo", "guest-fsfreeze-status", 3159 "guest-fsfreeze-freeze", "guest-fsfreeze-freeze-list", 3160 "guest-fsfreeze-thaw", "guest-get-fsinfo", 3161 "guest-get-disks", NULL}; 3162 char **p = (char **)list; 3163 3164 while (*p) { 3165 blockedrpcs = g_list_append(blockedrpcs, g_strdup(*p++)); 3166 } 3167 } 3168 #endif 3169 3170 #if !defined(CONFIG_FSTRIM) 3171 blockedrpcs = g_list_append(blockedrpcs, g_strdup("guest-fstrim")); 3172 #endif 3173 3174 blockedrpcs = g_list_append(blockedrpcs, g_strdup("guest-get-devices")); 3175 3176 return blockedrpcs; 3177 } 3178 3179 /* register init/cleanup routines for stateful command groups */ 3180 void ga_command_state_init(GAState *s, GACommandState *cs) 3181 { 3182 #if defined(CONFIG_FSFREEZE) 3183 ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup); 3184 #endif 3185 } 3186 3187 #ifdef HAVE_UTMPX 3188 3189 #define QGA_MICRO_SECOND_TO_SECOND 1000000 3190 3191 static double ga_get_login_time(struct utmpx *user_info) 3192 { 3193 double seconds = (double)user_info->ut_tv.tv_sec; 3194 double useconds = (double)user_info->ut_tv.tv_usec; 3195 useconds /= QGA_MICRO_SECOND_TO_SECOND; 3196 return seconds + useconds; 3197 } 3198 3199 GuestUserList *qmp_guest_get_users(Error **errp) 3200 { 3201 GHashTable *cache = NULL; 3202 GuestUserList *head = NULL, **tail = &head; 3203 struct utmpx *user_info = NULL; 3204 gpointer value = NULL; 3205 GuestUser *user = NULL; 3206 double login_time = 0; 3207 3208 cache = g_hash_table_new(g_str_hash, g_str_equal); 3209 setutxent(); 3210 3211 for (;;) { 3212 user_info = getutxent(); 3213 if (user_info == NULL) { 3214 break; 3215 } else if (user_info->ut_type != USER_PROCESS) { 3216 continue; 3217 } else if (g_hash_table_contains(cache, user_info->ut_user)) { 3218 value = g_hash_table_lookup(cache, user_info->ut_user); 3219 user = (GuestUser *)value; 3220 login_time = ga_get_login_time(user_info); 3221 /* We're ensuring the earliest login time to be sent */ 3222 if (login_time < user->login_time) { 3223 user->login_time = login_time; 3224 } 3225 continue; 3226 } 3227 3228 user = g_new0(GuestUser, 1); 3229 user->user = g_strdup(user_info->ut_user); 3230 user->login_time = ga_get_login_time(user_info); 3231 3232 g_hash_table_insert(cache, user->user, user); 3233 3234 QAPI_LIST_APPEND(tail, user); 3235 } 3236 endutxent(); 3237 g_hash_table_destroy(cache); 3238 return head; 3239 } 3240 3241 #else 3242 3243 GuestUserList *qmp_guest_get_users(Error **errp) 3244 { 3245 error_setg(errp, QERR_UNSUPPORTED); 3246 return NULL; 3247 } 3248 3249 #endif 3250 3251 /* Replace escaped special characters with theire real values. The replacement 3252 * is done in place -- returned value is in the original string. 3253 */ 3254 static void ga_osrelease_replace_special(gchar *value) 3255 { 3256 gchar *p, *p2, quote; 3257 3258 /* Trim the string at first space or semicolon if it is not enclosed in 3259 * single or double quotes. */ 3260 if ((value[0] != '"') || (value[0] == '\'')) { 3261 p = strchr(value, ' '); 3262 if (p != NULL) { 3263 *p = 0; 3264 } 3265 p = strchr(value, ';'); 3266 if (p != NULL) { 3267 *p = 0; 3268 } 3269 return; 3270 } 3271 3272 quote = value[0]; 3273 p2 = value; 3274 p = value + 1; 3275 while (*p != 0) { 3276 if (*p == '\\') { 3277 p++; 3278 switch (*p) { 3279 case '$': 3280 case '\'': 3281 case '"': 3282 case '\\': 3283 case '`': 3284 break; 3285 default: 3286 /* Keep literal backslash followed by whatever is there */ 3287 p--; 3288 break; 3289 } 3290 } else if (*p == quote) { 3291 *p2 = 0; 3292 break; 3293 } 3294 *(p2++) = *(p++); 3295 } 3296 } 3297 3298 static GKeyFile *ga_parse_osrelease(const char *fname) 3299 { 3300 gchar *content = NULL; 3301 gchar *content2 = NULL; 3302 GError *err = NULL; 3303 GKeyFile *keys = g_key_file_new(); 3304 const char *group = "[os-release]\n"; 3305 3306 if (!g_file_get_contents(fname, &content, NULL, &err)) { 3307 slog("failed to read '%s', error: %s", fname, err->message); 3308 goto fail; 3309 } 3310 3311 if (!g_utf8_validate(content, -1, NULL)) { 3312 slog("file is not utf-8 encoded: %s", fname); 3313 goto fail; 3314 } 3315 content2 = g_strdup_printf("%s%s", group, content); 3316 3317 if (!g_key_file_load_from_data(keys, content2, -1, G_KEY_FILE_NONE, 3318 &err)) { 3319 slog("failed to parse file '%s', error: %s", fname, err->message); 3320 goto fail; 3321 } 3322 3323 g_free(content); 3324 g_free(content2); 3325 return keys; 3326 3327 fail: 3328 g_error_free(err); 3329 g_free(content); 3330 g_free(content2); 3331 g_key_file_free(keys); 3332 return NULL; 3333 } 3334 3335 GuestOSInfo *qmp_guest_get_osinfo(Error **errp) 3336 { 3337 GuestOSInfo *info = NULL; 3338 struct utsname kinfo; 3339 GKeyFile *osrelease = NULL; 3340 const char *qga_os_release = g_getenv("QGA_OS_RELEASE"); 3341 3342 info = g_new0(GuestOSInfo, 1); 3343 3344 if (uname(&kinfo) != 0) { 3345 error_setg_errno(errp, errno, "uname failed"); 3346 } else { 3347 info->kernel_version = g_strdup(kinfo.version); 3348 info->kernel_release = g_strdup(kinfo.release); 3349 info->machine = g_strdup(kinfo.machine); 3350 } 3351 3352 if (qga_os_release != NULL) { 3353 osrelease = ga_parse_osrelease(qga_os_release); 3354 } else { 3355 osrelease = ga_parse_osrelease("/etc/os-release"); 3356 if (osrelease == NULL) { 3357 osrelease = ga_parse_osrelease("/usr/lib/os-release"); 3358 } 3359 } 3360 3361 if (osrelease != NULL) { 3362 char *value; 3363 3364 #define GET_FIELD(field, osfield) do { \ 3365 value = g_key_file_get_value(osrelease, "os-release", osfield, NULL); \ 3366 if (value != NULL) { \ 3367 ga_osrelease_replace_special(value); \ 3368 info->field = value; \ 3369 } \ 3370 } while (0) 3371 GET_FIELD(id, "ID"); 3372 GET_FIELD(name, "NAME"); 3373 GET_FIELD(pretty_name, "PRETTY_NAME"); 3374 GET_FIELD(version, "VERSION"); 3375 GET_FIELD(version_id, "VERSION_ID"); 3376 GET_FIELD(variant, "VARIANT"); 3377 GET_FIELD(variant_id, "VARIANT_ID"); 3378 #undef GET_FIELD 3379 3380 g_key_file_free(osrelease); 3381 } 3382 3383 return info; 3384 } 3385 3386 GuestDeviceInfoList *qmp_guest_get_devices(Error **errp) 3387 { 3388 error_setg(errp, QERR_UNSUPPORTED); 3389 3390 return NULL; 3391 } 3392 3393 #ifndef HOST_NAME_MAX 3394 # ifdef _POSIX_HOST_NAME_MAX 3395 # define HOST_NAME_MAX _POSIX_HOST_NAME_MAX 3396 # else 3397 # define HOST_NAME_MAX 255 3398 # endif 3399 #endif 3400 3401 char *qga_get_host_name(Error **errp) 3402 { 3403 long len = -1; 3404 g_autofree char *hostname = NULL; 3405 3406 #ifdef _SC_HOST_NAME_MAX 3407 len = sysconf(_SC_HOST_NAME_MAX); 3408 #endif /* _SC_HOST_NAME_MAX */ 3409 3410 if (len < 0) { 3411 len = HOST_NAME_MAX; 3412 } 3413 3414 /* Unfortunately, gethostname() below does not guarantee a 3415 * NULL terminated string. Therefore, allocate one byte more 3416 * to be sure. */ 3417 hostname = g_new0(char, len + 1); 3418 3419 if (gethostname(hostname, len) < 0) { 3420 error_setg_errno(errp, errno, 3421 "cannot get hostname"); 3422 return NULL; 3423 } 3424 3425 return g_steal_pointer(&hostname); 3426 } 3427