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 <glib.h> 15 #include <sys/types.h> 16 #include <sys/ioctl.h> 17 #include <sys/wait.h> 18 #include <unistd.h> 19 #include <errno.h> 20 #include <fcntl.h> 21 #include <inttypes.h> 22 #include "qga/guest-agent-core.h" 23 #include "qga-qmp-commands.h" 24 #include "qapi/qmp/qerror.h" 25 #include "qemu/queue.h" 26 #include "qemu/host-utils.h" 27 28 #ifndef CONFIG_HAS_ENVIRON 29 #ifdef __APPLE__ 30 #include <crt_externs.h> 31 #define environ (*_NSGetEnviron()) 32 #else 33 extern char **environ; 34 #endif 35 #endif 36 37 #if defined(__linux__) 38 #include <mntent.h> 39 #include <linux/fs.h> 40 #include <ifaddrs.h> 41 #include <arpa/inet.h> 42 #include <sys/socket.h> 43 #include <net/if.h> 44 45 #ifdef FIFREEZE 46 #define CONFIG_FSFREEZE 47 #endif 48 #ifdef FITRIM 49 #define CONFIG_FSTRIM 50 #endif 51 #endif 52 53 static void ga_wait_child(pid_t pid, int *status, Error **err) 54 { 55 pid_t rpid; 56 57 *status = 0; 58 59 do { 60 rpid = waitpid(pid, status, 0); 61 } while (rpid == -1 && errno == EINTR); 62 63 if (rpid == -1) { 64 error_setg_errno(err, errno, "failed to wait for child (pid: %d)", pid); 65 return; 66 } 67 68 g_assert(rpid == pid); 69 } 70 71 void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err) 72 { 73 const char *shutdown_flag; 74 Error *local_err = NULL; 75 pid_t pid; 76 int status; 77 78 slog("guest-shutdown called, mode: %s", mode); 79 if (!has_mode || strcmp(mode, "powerdown") == 0) { 80 shutdown_flag = "-P"; 81 } else if (strcmp(mode, "halt") == 0) { 82 shutdown_flag = "-H"; 83 } else if (strcmp(mode, "reboot") == 0) { 84 shutdown_flag = "-r"; 85 } else { 86 error_setg(err, 87 "mode is invalid (valid values are: halt|powerdown|reboot"); 88 return; 89 } 90 91 pid = fork(); 92 if (pid == 0) { 93 /* child, start the shutdown */ 94 setsid(); 95 reopen_fd_to_null(0); 96 reopen_fd_to_null(1); 97 reopen_fd_to_null(2); 98 99 execle("/sbin/shutdown", "shutdown", shutdown_flag, "+0", 100 "hypervisor initiated shutdown", (char*)NULL, environ); 101 _exit(EXIT_FAILURE); 102 } else if (pid < 0) { 103 error_setg_errno(err, errno, "failed to create child process"); 104 return; 105 } 106 107 ga_wait_child(pid, &status, &local_err); 108 if (error_is_set(&local_err)) { 109 error_propagate(err, local_err); 110 return; 111 } 112 113 if (!WIFEXITED(status)) { 114 error_setg(err, "child process has terminated abnormally"); 115 return; 116 } 117 118 if (WEXITSTATUS(status)) { 119 error_setg(err, "child process has failed to shutdown"); 120 return; 121 } 122 123 /* succeeded */ 124 } 125 126 int64_t qmp_guest_get_time(Error **errp) 127 { 128 int ret; 129 qemu_timeval tq; 130 int64_t time_ns; 131 132 ret = qemu_gettimeofday(&tq); 133 if (ret < 0) { 134 error_setg_errno(errp, errno, "Failed to get time"); 135 return -1; 136 } 137 138 time_ns = tq.tv_sec * 1000000000LL + tq.tv_usec * 1000; 139 return time_ns; 140 } 141 142 void qmp_guest_set_time(int64_t time_ns, Error **errp) 143 { 144 int ret; 145 int status; 146 pid_t pid; 147 Error *local_err = NULL; 148 struct timeval tv; 149 150 /* year-2038 will overflow in case time_t is 32bit */ 151 if (time_ns / 1000000000 != (time_t)(time_ns / 1000000000)) { 152 error_setg(errp, "Time %" PRId64 " is too large", time_ns); 153 return; 154 } 155 156 tv.tv_sec = time_ns / 1000000000; 157 tv.tv_usec = (time_ns % 1000000000) / 1000; 158 159 ret = settimeofday(&tv, NULL); 160 if (ret < 0) { 161 error_setg_errno(errp, errno, "Failed to set time to guest"); 162 return; 163 } 164 165 /* Set the Hardware Clock to the current System Time. */ 166 pid = fork(); 167 if (pid == 0) { 168 setsid(); 169 reopen_fd_to_null(0); 170 reopen_fd_to_null(1); 171 reopen_fd_to_null(2); 172 173 execle("/sbin/hwclock", "hwclock", "-w", NULL, environ); 174 _exit(EXIT_FAILURE); 175 } else if (pid < 0) { 176 error_setg_errno(errp, errno, "failed to create child process"); 177 return; 178 } 179 180 ga_wait_child(pid, &status, &local_err); 181 if (error_is_set(&local_err)) { 182 error_propagate(errp, local_err); 183 return; 184 } 185 186 if (!WIFEXITED(status)) { 187 error_setg(errp, "child process has terminated abnormally"); 188 return; 189 } 190 191 if (WEXITSTATUS(status)) { 192 error_setg(errp, "hwclock failed to set hardware clock to system time"); 193 return; 194 } 195 } 196 197 typedef struct GuestFileHandle { 198 uint64_t id; 199 FILE *fh; 200 QTAILQ_ENTRY(GuestFileHandle) next; 201 } GuestFileHandle; 202 203 static struct { 204 QTAILQ_HEAD(, GuestFileHandle) filehandles; 205 } guest_file_state; 206 207 static int64_t guest_file_handle_add(FILE *fh, Error **errp) 208 { 209 GuestFileHandle *gfh; 210 int64_t handle; 211 212 handle = ga_get_fd_handle(ga_state, errp); 213 if (error_is_set(errp)) { 214 return 0; 215 } 216 217 gfh = g_malloc0(sizeof(GuestFileHandle)); 218 gfh->id = handle; 219 gfh->fh = fh; 220 QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next); 221 222 return handle; 223 } 224 225 static GuestFileHandle *guest_file_handle_find(int64_t id, Error **err) 226 { 227 GuestFileHandle *gfh; 228 229 QTAILQ_FOREACH(gfh, &guest_file_state.filehandles, next) 230 { 231 if (gfh->id == id) { 232 return gfh; 233 } 234 } 235 236 error_setg(err, "handle '%" PRId64 "' has not been found", id); 237 return NULL; 238 } 239 240 int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, Error **err) 241 { 242 FILE *fh; 243 int fd; 244 int64_t ret = -1, handle; 245 246 if (!has_mode) { 247 mode = "r"; 248 } 249 slog("guest-file-open called, filepath: %s, mode: %s", path, mode); 250 fh = fopen(path, mode); 251 if (!fh) { 252 error_setg_errno(err, errno, "failed to open file '%s' (mode: '%s')", 253 path, mode); 254 return -1; 255 } 256 257 /* set fd non-blocking to avoid common use cases (like reading from a 258 * named pipe) from hanging the agent 259 */ 260 fd = fileno(fh); 261 ret = fcntl(fd, F_GETFL); 262 ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK); 263 if (ret == -1) { 264 error_setg_errno(err, errno, "failed to make file '%s' non-blocking", 265 path); 266 fclose(fh); 267 return -1; 268 } 269 270 handle = guest_file_handle_add(fh, err); 271 if (error_is_set(err)) { 272 fclose(fh); 273 return -1; 274 } 275 276 slog("guest-file-open, handle: %d", handle); 277 return handle; 278 } 279 280 void qmp_guest_file_close(int64_t handle, Error **err) 281 { 282 GuestFileHandle *gfh = guest_file_handle_find(handle, err); 283 int ret; 284 285 slog("guest-file-close called, handle: %ld", handle); 286 if (!gfh) { 287 return; 288 } 289 290 ret = fclose(gfh->fh); 291 if (ret == EOF) { 292 error_setg_errno(err, errno, "failed to close handle"); 293 return; 294 } 295 296 QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next); 297 g_free(gfh); 298 } 299 300 struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count, 301 int64_t count, Error **err) 302 { 303 GuestFileHandle *gfh = guest_file_handle_find(handle, err); 304 GuestFileRead *read_data = NULL; 305 guchar *buf; 306 FILE *fh; 307 size_t read_count; 308 309 if (!gfh) { 310 return NULL; 311 } 312 313 if (!has_count) { 314 count = QGA_READ_COUNT_DEFAULT; 315 } else if (count < 0) { 316 error_setg(err, "value '%" PRId64 "' is invalid for argument count", 317 count); 318 return NULL; 319 } 320 321 fh = gfh->fh; 322 buf = g_malloc0(count+1); 323 read_count = fread(buf, 1, count, fh); 324 if (ferror(fh)) { 325 error_setg_errno(err, errno, "failed to read file"); 326 slog("guest-file-read failed, handle: %ld", handle); 327 } else { 328 buf[read_count] = 0; 329 read_data = g_malloc0(sizeof(GuestFileRead)); 330 read_data->count = read_count; 331 read_data->eof = feof(fh); 332 if (read_count) { 333 read_data->buf_b64 = g_base64_encode(buf, read_count); 334 } 335 } 336 g_free(buf); 337 clearerr(fh); 338 339 return read_data; 340 } 341 342 GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64, 343 bool has_count, int64_t count, Error **err) 344 { 345 GuestFileWrite *write_data = NULL; 346 guchar *buf; 347 gsize buf_len; 348 int write_count; 349 GuestFileHandle *gfh = guest_file_handle_find(handle, err); 350 FILE *fh; 351 352 if (!gfh) { 353 return NULL; 354 } 355 356 fh = gfh->fh; 357 buf = g_base64_decode(buf_b64, &buf_len); 358 359 if (!has_count) { 360 count = buf_len; 361 } else if (count < 0 || count > buf_len) { 362 error_setg(err, "value '%" PRId64 "' is invalid for argument count", 363 count); 364 g_free(buf); 365 return NULL; 366 } 367 368 write_count = fwrite(buf, 1, count, fh); 369 if (ferror(fh)) { 370 error_setg_errno(err, errno, "failed to write to file"); 371 slog("guest-file-write failed, handle: %ld", handle); 372 } else { 373 write_data = g_malloc0(sizeof(GuestFileWrite)); 374 write_data->count = write_count; 375 write_data->eof = feof(fh); 376 } 377 g_free(buf); 378 clearerr(fh); 379 380 return write_data; 381 } 382 383 struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset, 384 int64_t whence, Error **err) 385 { 386 GuestFileHandle *gfh = guest_file_handle_find(handle, err); 387 GuestFileSeek *seek_data = NULL; 388 FILE *fh; 389 int ret; 390 391 if (!gfh) { 392 return NULL; 393 } 394 395 fh = gfh->fh; 396 ret = fseek(fh, offset, whence); 397 if (ret == -1) { 398 error_setg_errno(err, errno, "failed to seek file"); 399 } else { 400 seek_data = g_malloc0(sizeof(GuestFileRead)); 401 seek_data->position = ftell(fh); 402 seek_data->eof = feof(fh); 403 } 404 clearerr(fh); 405 406 return seek_data; 407 } 408 409 void qmp_guest_file_flush(int64_t handle, Error **err) 410 { 411 GuestFileHandle *gfh = guest_file_handle_find(handle, err); 412 FILE *fh; 413 int ret; 414 415 if (!gfh) { 416 return; 417 } 418 419 fh = gfh->fh; 420 ret = fflush(fh); 421 if (ret == EOF) { 422 error_setg_errno(err, errno, "failed to flush file"); 423 } 424 } 425 426 static void guest_file_init(void) 427 { 428 QTAILQ_INIT(&guest_file_state.filehandles); 429 } 430 431 /* linux-specific implementations. avoid this if at all possible. */ 432 #if defined(__linux__) 433 434 #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) 435 typedef struct FsMount { 436 char *dirname; 437 char *devtype; 438 QTAILQ_ENTRY(FsMount) next; 439 } FsMount; 440 441 typedef QTAILQ_HEAD(, FsMount) FsMountList; 442 443 static void free_fs_mount_list(FsMountList *mounts) 444 { 445 FsMount *mount, *temp; 446 447 if (!mounts) { 448 return; 449 } 450 451 QTAILQ_FOREACH_SAFE(mount, mounts, next, temp) { 452 QTAILQ_REMOVE(mounts, mount, next); 453 g_free(mount->dirname); 454 g_free(mount->devtype); 455 g_free(mount); 456 } 457 } 458 459 /* 460 * Walk the mount table and build a list of local file systems 461 */ 462 static void build_fs_mount_list(FsMountList *mounts, Error **err) 463 { 464 struct mntent *ment; 465 FsMount *mount; 466 char const *mtab = "/proc/self/mounts"; 467 FILE *fp; 468 469 fp = setmntent(mtab, "r"); 470 if (!fp) { 471 error_setg(err, "failed to open mtab file: '%s'", mtab); 472 return; 473 } 474 475 while ((ment = getmntent(fp))) { 476 /* 477 * An entry which device name doesn't start with a '/' is 478 * either a dummy file system or a network file system. 479 * Add special handling for smbfs and cifs as is done by 480 * coreutils as well. 481 */ 482 if ((ment->mnt_fsname[0] != '/') || 483 (strcmp(ment->mnt_type, "smbfs") == 0) || 484 (strcmp(ment->mnt_type, "cifs") == 0)) { 485 continue; 486 } 487 488 mount = g_malloc0(sizeof(FsMount)); 489 mount->dirname = g_strdup(ment->mnt_dir); 490 mount->devtype = g_strdup(ment->mnt_type); 491 492 QTAILQ_INSERT_TAIL(mounts, mount, next); 493 } 494 495 endmntent(fp); 496 } 497 #endif 498 499 #if defined(CONFIG_FSFREEZE) 500 501 typedef enum { 502 FSFREEZE_HOOK_THAW = 0, 503 FSFREEZE_HOOK_FREEZE, 504 } FsfreezeHookArg; 505 506 const char *fsfreeze_hook_arg_string[] = { 507 "thaw", 508 "freeze", 509 }; 510 511 static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **err) 512 { 513 int status; 514 pid_t pid; 515 const char *hook; 516 const char *arg_str = fsfreeze_hook_arg_string[arg]; 517 Error *local_err = NULL; 518 519 hook = ga_fsfreeze_hook(ga_state); 520 if (!hook) { 521 return; 522 } 523 if (access(hook, X_OK) != 0) { 524 error_setg_errno(err, errno, "can't access fsfreeze hook '%s'", hook); 525 return; 526 } 527 528 slog("executing fsfreeze hook with arg '%s'", arg_str); 529 pid = fork(); 530 if (pid == 0) { 531 setsid(); 532 reopen_fd_to_null(0); 533 reopen_fd_to_null(1); 534 reopen_fd_to_null(2); 535 536 execle(hook, hook, arg_str, NULL, environ); 537 _exit(EXIT_FAILURE); 538 } else if (pid < 0) { 539 error_setg_errno(err, errno, "failed to create child process"); 540 return; 541 } 542 543 ga_wait_child(pid, &status, &local_err); 544 if (error_is_set(&local_err)) { 545 error_propagate(err, local_err); 546 return; 547 } 548 549 if (!WIFEXITED(status)) { 550 error_setg(err, "fsfreeze hook has terminated abnormally"); 551 return; 552 } 553 554 status = WEXITSTATUS(status); 555 if (status) { 556 error_setg(err, "fsfreeze hook has failed with status %d", status); 557 return; 558 } 559 } 560 561 /* 562 * Return status of freeze/thaw 563 */ 564 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err) 565 { 566 if (ga_is_frozen(ga_state)) { 567 return GUEST_FSFREEZE_STATUS_FROZEN; 568 } 569 570 return GUEST_FSFREEZE_STATUS_THAWED; 571 } 572 573 /* 574 * Walk list of mounted file systems in the guest, and freeze the ones which 575 * are real local file systems. 576 */ 577 int64_t qmp_guest_fsfreeze_freeze(Error **err) 578 { 579 int ret = 0, i = 0; 580 FsMountList mounts; 581 struct FsMount *mount; 582 Error *local_err = NULL; 583 int fd; 584 585 slog("guest-fsfreeze called"); 586 587 execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err); 588 if (error_is_set(&local_err)) { 589 error_propagate(err, local_err); 590 return -1; 591 } 592 593 QTAILQ_INIT(&mounts); 594 build_fs_mount_list(&mounts, &local_err); 595 if (error_is_set(&local_err)) { 596 error_propagate(err, local_err); 597 return -1; 598 } 599 600 /* cannot risk guest agent blocking itself on a write in this state */ 601 ga_set_frozen(ga_state); 602 603 QTAILQ_FOREACH(mount, &mounts, next) { 604 fd = qemu_open(mount->dirname, O_RDONLY); 605 if (fd == -1) { 606 error_setg_errno(err, errno, "failed to open %s", mount->dirname); 607 goto error; 608 } 609 610 /* we try to cull filesytems we know won't work in advance, but other 611 * filesytems may not implement fsfreeze for less obvious reasons. 612 * these will report EOPNOTSUPP. we simply ignore these when tallying 613 * the number of frozen filesystems. 614 * 615 * any other error means a failure to freeze a filesystem we 616 * expect to be freezable, so return an error in those cases 617 * and return system to thawed state. 618 */ 619 ret = ioctl(fd, FIFREEZE); 620 if (ret == -1) { 621 if (errno != EOPNOTSUPP) { 622 error_setg_errno(err, errno, "failed to freeze %s", 623 mount->dirname); 624 close(fd); 625 goto error; 626 } 627 } else { 628 i++; 629 } 630 close(fd); 631 } 632 633 free_fs_mount_list(&mounts); 634 return i; 635 636 error: 637 free_fs_mount_list(&mounts); 638 qmp_guest_fsfreeze_thaw(NULL); 639 return 0; 640 } 641 642 /* 643 * Walk list of frozen file systems in the guest, and thaw them. 644 */ 645 int64_t qmp_guest_fsfreeze_thaw(Error **err) 646 { 647 int ret; 648 FsMountList mounts; 649 FsMount *mount; 650 int fd, i = 0, logged; 651 Error *local_err = NULL; 652 653 QTAILQ_INIT(&mounts); 654 build_fs_mount_list(&mounts, &local_err); 655 if (error_is_set(&local_err)) { 656 error_propagate(err, local_err); 657 return 0; 658 } 659 660 QTAILQ_FOREACH(mount, &mounts, next) { 661 logged = false; 662 fd = qemu_open(mount->dirname, O_RDONLY); 663 if (fd == -1) { 664 continue; 665 } 666 /* we have no way of knowing whether a filesystem was actually unfrozen 667 * as a result of a successful call to FITHAW, only that if an error 668 * was returned the filesystem was *not* unfrozen by that particular 669 * call. 670 * 671 * since multiple preceding FIFREEZEs require multiple calls to FITHAW 672 * to unfreeze, continuing issuing FITHAW until an error is returned, 673 * in which case either the filesystem is in an unfreezable state, or, 674 * more likely, it was thawed previously (and remains so afterward). 675 * 676 * also, since the most recent successful call is the one that did 677 * the actual unfreeze, we can use this to provide an accurate count 678 * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which 679 * may * be useful for determining whether a filesystem was unfrozen 680 * during the freeze/thaw phase by a process other than qemu-ga. 681 */ 682 do { 683 ret = ioctl(fd, FITHAW); 684 if (ret == 0 && !logged) { 685 i++; 686 logged = true; 687 } 688 } while (ret == 0); 689 close(fd); 690 } 691 692 ga_unset_frozen(ga_state); 693 free_fs_mount_list(&mounts); 694 695 execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, err); 696 697 return i; 698 } 699 700 static void guest_fsfreeze_cleanup(void) 701 { 702 Error *err = NULL; 703 704 if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) { 705 qmp_guest_fsfreeze_thaw(&err); 706 if (err) { 707 slog("failed to clean up frozen filesystems: %s", 708 error_get_pretty(err)); 709 error_free(err); 710 } 711 } 712 } 713 #endif /* CONFIG_FSFREEZE */ 714 715 #if defined(CONFIG_FSTRIM) 716 /* 717 * Walk list of mounted file systems in the guest, and trim them. 718 */ 719 void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err) 720 { 721 int ret = 0; 722 FsMountList mounts; 723 struct FsMount *mount; 724 int fd; 725 Error *local_err = NULL; 726 struct fstrim_range r = { 727 .start = 0, 728 .len = -1, 729 .minlen = has_minimum ? minimum : 0, 730 }; 731 732 slog("guest-fstrim called"); 733 734 QTAILQ_INIT(&mounts); 735 build_fs_mount_list(&mounts, &local_err); 736 if (error_is_set(&local_err)) { 737 error_propagate(err, local_err); 738 return; 739 } 740 741 QTAILQ_FOREACH(mount, &mounts, next) { 742 fd = qemu_open(mount->dirname, O_RDONLY); 743 if (fd == -1) { 744 error_setg_errno(err, errno, "failed to open %s", mount->dirname); 745 goto error; 746 } 747 748 /* We try to cull filesytems we know won't work in advance, but other 749 * filesytems may not implement fstrim for less obvious reasons. These 750 * will report EOPNOTSUPP; we simply ignore these errors. Any other 751 * error means an unexpected error, so return it in those cases. In 752 * some other cases ENOTTY will be reported (e.g. CD-ROMs). 753 */ 754 ret = ioctl(fd, FITRIM, &r); 755 if (ret == -1) { 756 if (errno != ENOTTY && errno != EOPNOTSUPP) { 757 error_setg_errno(err, errno, "failed to trim %s", 758 mount->dirname); 759 close(fd); 760 goto error; 761 } 762 } 763 close(fd); 764 } 765 766 error: 767 free_fs_mount_list(&mounts); 768 } 769 #endif /* CONFIG_FSTRIM */ 770 771 772 #define LINUX_SYS_STATE_FILE "/sys/power/state" 773 #define SUSPEND_SUPPORTED 0 774 #define SUSPEND_NOT_SUPPORTED 1 775 776 static void bios_supports_mode(const char *pmutils_bin, const char *pmutils_arg, 777 const char *sysfile_str, Error **err) 778 { 779 Error *local_err = NULL; 780 char *pmutils_path; 781 pid_t pid; 782 int status; 783 784 pmutils_path = g_find_program_in_path(pmutils_bin); 785 786 pid = fork(); 787 if (!pid) { 788 char buf[32]; /* hopefully big enough */ 789 ssize_t ret; 790 int fd; 791 792 setsid(); 793 reopen_fd_to_null(0); 794 reopen_fd_to_null(1); 795 reopen_fd_to_null(2); 796 797 if (pmutils_path) { 798 execle(pmutils_path, pmutils_bin, pmutils_arg, NULL, environ); 799 } 800 801 /* 802 * If we get here either pm-utils is not installed or execle() has 803 * failed. Let's try the manual method if the caller wants it. 804 */ 805 806 if (!sysfile_str) { 807 _exit(SUSPEND_NOT_SUPPORTED); 808 } 809 810 fd = open(LINUX_SYS_STATE_FILE, O_RDONLY); 811 if (fd < 0) { 812 _exit(SUSPEND_NOT_SUPPORTED); 813 } 814 815 ret = read(fd, buf, sizeof(buf)-1); 816 if (ret <= 0) { 817 _exit(SUSPEND_NOT_SUPPORTED); 818 } 819 buf[ret] = '\0'; 820 821 if (strstr(buf, sysfile_str)) { 822 _exit(SUSPEND_SUPPORTED); 823 } 824 825 _exit(SUSPEND_NOT_SUPPORTED); 826 } else if (pid < 0) { 827 error_setg_errno(err, errno, "failed to create child process"); 828 goto out; 829 } 830 831 ga_wait_child(pid, &status, &local_err); 832 if (error_is_set(&local_err)) { 833 error_propagate(err, local_err); 834 goto out; 835 } 836 837 if (!WIFEXITED(status)) { 838 error_setg(err, "child process has terminated abnormally"); 839 goto out; 840 } 841 842 switch (WEXITSTATUS(status)) { 843 case SUSPEND_SUPPORTED: 844 goto out; 845 case SUSPEND_NOT_SUPPORTED: 846 error_setg(err, 847 "the requested suspend mode is not supported by the guest"); 848 goto out; 849 default: 850 error_setg(err, 851 "the helper program '%s' returned an unexpected exit status" 852 " code (%d)", pmutils_path, WEXITSTATUS(status)); 853 goto out; 854 } 855 856 out: 857 g_free(pmutils_path); 858 } 859 860 static void guest_suspend(const char *pmutils_bin, const char *sysfile_str, 861 Error **err) 862 { 863 Error *local_err = NULL; 864 char *pmutils_path; 865 pid_t pid; 866 int status; 867 868 pmutils_path = g_find_program_in_path(pmutils_bin); 869 870 pid = fork(); 871 if (pid == 0) { 872 /* child */ 873 int fd; 874 875 setsid(); 876 reopen_fd_to_null(0); 877 reopen_fd_to_null(1); 878 reopen_fd_to_null(2); 879 880 if (pmutils_path) { 881 execle(pmutils_path, pmutils_bin, NULL, environ); 882 } 883 884 /* 885 * If we get here either pm-utils is not installed or execle() has 886 * failed. Let's try the manual method if the caller wants it. 887 */ 888 889 if (!sysfile_str) { 890 _exit(EXIT_FAILURE); 891 } 892 893 fd = open(LINUX_SYS_STATE_FILE, O_WRONLY); 894 if (fd < 0) { 895 _exit(EXIT_FAILURE); 896 } 897 898 if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) { 899 _exit(EXIT_FAILURE); 900 } 901 902 _exit(EXIT_SUCCESS); 903 } else if (pid < 0) { 904 error_setg_errno(err, errno, "failed to create child process"); 905 goto out; 906 } 907 908 ga_wait_child(pid, &status, &local_err); 909 if (error_is_set(&local_err)) { 910 error_propagate(err, local_err); 911 goto out; 912 } 913 914 if (!WIFEXITED(status)) { 915 error_setg(err, "child process has terminated abnormally"); 916 goto out; 917 } 918 919 if (WEXITSTATUS(status)) { 920 error_setg(err, "child process has failed to suspend"); 921 goto out; 922 } 923 924 out: 925 g_free(pmutils_path); 926 } 927 928 void qmp_guest_suspend_disk(Error **err) 929 { 930 bios_supports_mode("pm-is-supported", "--hibernate", "disk", err); 931 if (error_is_set(err)) { 932 return; 933 } 934 935 guest_suspend("pm-hibernate", "disk", err); 936 } 937 938 void qmp_guest_suspend_ram(Error **err) 939 { 940 bios_supports_mode("pm-is-supported", "--suspend", "mem", err); 941 if (error_is_set(err)) { 942 return; 943 } 944 945 guest_suspend("pm-suspend", "mem", err); 946 } 947 948 void qmp_guest_suspend_hybrid(Error **err) 949 { 950 bios_supports_mode("pm-is-supported", "--suspend-hybrid", NULL, err); 951 if (error_is_set(err)) { 952 return; 953 } 954 955 guest_suspend("pm-suspend-hybrid", NULL, err); 956 } 957 958 static GuestNetworkInterfaceList * 959 guest_find_interface(GuestNetworkInterfaceList *head, 960 const char *name) 961 { 962 for (; head; head = head->next) { 963 if (strcmp(head->value->name, name) == 0) { 964 break; 965 } 966 } 967 968 return head; 969 } 970 971 /* 972 * Build information about guest interfaces 973 */ 974 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) 975 { 976 GuestNetworkInterfaceList *head = NULL, *cur_item = NULL; 977 struct ifaddrs *ifap, *ifa; 978 979 if (getifaddrs(&ifap) < 0) { 980 error_setg_errno(errp, errno, "getifaddrs failed"); 981 goto error; 982 } 983 984 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 985 GuestNetworkInterfaceList *info; 986 GuestIpAddressList **address_list = NULL, *address_item = NULL; 987 char addr4[INET_ADDRSTRLEN]; 988 char addr6[INET6_ADDRSTRLEN]; 989 int sock; 990 struct ifreq ifr; 991 unsigned char *mac_addr; 992 void *p; 993 994 g_debug("Processing %s interface", ifa->ifa_name); 995 996 info = guest_find_interface(head, ifa->ifa_name); 997 998 if (!info) { 999 info = g_malloc0(sizeof(*info)); 1000 info->value = g_malloc0(sizeof(*info->value)); 1001 info->value->name = g_strdup(ifa->ifa_name); 1002 1003 if (!cur_item) { 1004 head = cur_item = info; 1005 } else { 1006 cur_item->next = info; 1007 cur_item = info; 1008 } 1009 } 1010 1011 if (!info->value->has_hardware_address && 1012 ifa->ifa_flags & SIOCGIFHWADDR) { 1013 /* we haven't obtained HW address yet */ 1014 sock = socket(PF_INET, SOCK_STREAM, 0); 1015 if (sock == -1) { 1016 error_setg_errno(errp, errno, "failed to create socket"); 1017 goto error; 1018 } 1019 1020 memset(&ifr, 0, sizeof(ifr)); 1021 pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->value->name); 1022 if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { 1023 error_setg_errno(errp, errno, 1024 "failed to get MAC address of %s", 1025 ifa->ifa_name); 1026 close(sock); 1027 goto error; 1028 } 1029 1030 close(sock); 1031 mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data; 1032 1033 info->value->hardware_address = 1034 g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", 1035 (int) mac_addr[0], (int) mac_addr[1], 1036 (int) mac_addr[2], (int) mac_addr[3], 1037 (int) mac_addr[4], (int) mac_addr[5]); 1038 1039 info->value->has_hardware_address = true; 1040 } 1041 1042 if (ifa->ifa_addr && 1043 ifa->ifa_addr->sa_family == AF_INET) { 1044 /* interface with IPv4 address */ 1045 p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; 1046 if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) { 1047 error_setg_errno(errp, errno, "inet_ntop failed"); 1048 goto error; 1049 } 1050 1051 address_item = g_malloc0(sizeof(*address_item)); 1052 address_item->value = g_malloc0(sizeof(*address_item->value)); 1053 address_item->value->ip_address = g_strdup(addr4); 1054 address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4; 1055 1056 if (ifa->ifa_netmask) { 1057 /* Count the number of set bits in netmask. 1058 * This is safe as '1' and '0' cannot be shuffled in netmask. */ 1059 p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr; 1060 address_item->value->prefix = ctpop32(((uint32_t *) p)[0]); 1061 } 1062 } else if (ifa->ifa_addr && 1063 ifa->ifa_addr->sa_family == AF_INET6) { 1064 /* interface with IPv6 address */ 1065 p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; 1066 if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) { 1067 error_setg_errno(errp, errno, "inet_ntop failed"); 1068 goto error; 1069 } 1070 1071 address_item = g_malloc0(sizeof(*address_item)); 1072 address_item->value = g_malloc0(sizeof(*address_item->value)); 1073 address_item->value->ip_address = g_strdup(addr6); 1074 address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6; 1075 1076 if (ifa->ifa_netmask) { 1077 /* Count the number of set bits in netmask. 1078 * This is safe as '1' and '0' cannot be shuffled in netmask. */ 1079 p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr; 1080 address_item->value->prefix = 1081 ctpop32(((uint32_t *) p)[0]) + 1082 ctpop32(((uint32_t *) p)[1]) + 1083 ctpop32(((uint32_t *) p)[2]) + 1084 ctpop32(((uint32_t *) p)[3]); 1085 } 1086 } 1087 1088 if (!address_item) { 1089 continue; 1090 } 1091 1092 address_list = &info->value->ip_addresses; 1093 1094 while (*address_list && (*address_list)->next) { 1095 address_list = &(*address_list)->next; 1096 } 1097 1098 if (!*address_list) { 1099 *address_list = address_item; 1100 } else { 1101 (*address_list)->next = address_item; 1102 } 1103 1104 info->value->has_ip_addresses = true; 1105 1106 1107 } 1108 1109 freeifaddrs(ifap); 1110 return head; 1111 1112 error: 1113 freeifaddrs(ifap); 1114 qapi_free_GuestNetworkInterfaceList(head); 1115 return NULL; 1116 } 1117 1118 #define SYSCONF_EXACT(name, err) sysconf_exact((name), #name, (err)) 1119 1120 static long sysconf_exact(int name, const char *name_str, Error **err) 1121 { 1122 long ret; 1123 1124 errno = 0; 1125 ret = sysconf(name); 1126 if (ret == -1) { 1127 if (errno == 0) { 1128 error_setg(err, "sysconf(%s): value indefinite", name_str); 1129 } else { 1130 error_setg_errno(err, errno, "sysconf(%s)", name_str); 1131 } 1132 } 1133 return ret; 1134 } 1135 1136 /* Transfer online/offline status between @vcpu and the guest system. 1137 * 1138 * On input either @errp or *@errp must be NULL. 1139 * 1140 * In system-to-@vcpu direction, the following @vcpu fields are accessed: 1141 * - R: vcpu->logical_id 1142 * - W: vcpu->online 1143 * - W: vcpu->can_offline 1144 * 1145 * In @vcpu-to-system direction, the following @vcpu fields are accessed: 1146 * - R: vcpu->logical_id 1147 * - R: vcpu->online 1148 * 1149 * Written members remain unmodified on error. 1150 */ 1151 static void transfer_vcpu(GuestLogicalProcessor *vcpu, bool sys2vcpu, 1152 Error **errp) 1153 { 1154 char *dirpath; 1155 int dirfd; 1156 1157 dirpath = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/", 1158 vcpu->logical_id); 1159 dirfd = open(dirpath, O_RDONLY | O_DIRECTORY); 1160 if (dirfd == -1) { 1161 error_setg_errno(errp, errno, "open(\"%s\")", dirpath); 1162 } else { 1163 static const char fn[] = "online"; 1164 int fd; 1165 int res; 1166 1167 fd = openat(dirfd, fn, sys2vcpu ? O_RDONLY : O_RDWR); 1168 if (fd == -1) { 1169 if (errno != ENOENT) { 1170 error_setg_errno(errp, errno, "open(\"%s/%s\")", dirpath, fn); 1171 } else if (sys2vcpu) { 1172 vcpu->online = true; 1173 vcpu->can_offline = false; 1174 } else if (!vcpu->online) { 1175 error_setg(errp, "logical processor #%" PRId64 " can't be " 1176 "offlined", vcpu->logical_id); 1177 } /* otherwise pretend successful re-onlining */ 1178 } else { 1179 unsigned char status; 1180 1181 res = pread(fd, &status, 1, 0); 1182 if (res == -1) { 1183 error_setg_errno(errp, errno, "pread(\"%s/%s\")", dirpath, fn); 1184 } else if (res == 0) { 1185 error_setg(errp, "pread(\"%s/%s\"): unexpected EOF", dirpath, 1186 fn); 1187 } else if (sys2vcpu) { 1188 vcpu->online = (status != '0'); 1189 vcpu->can_offline = true; 1190 } else if (vcpu->online != (status != '0')) { 1191 status = '0' + vcpu->online; 1192 if (pwrite(fd, &status, 1, 0) == -1) { 1193 error_setg_errno(errp, errno, "pwrite(\"%s/%s\")", dirpath, 1194 fn); 1195 } 1196 } /* otherwise pretend successful re-(on|off)-lining */ 1197 1198 res = close(fd); 1199 g_assert(res == 0); 1200 } 1201 1202 res = close(dirfd); 1203 g_assert(res == 0); 1204 } 1205 1206 g_free(dirpath); 1207 } 1208 1209 GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) 1210 { 1211 int64_t current; 1212 GuestLogicalProcessorList *head, **link; 1213 long sc_max; 1214 Error *local_err = NULL; 1215 1216 current = 0; 1217 head = NULL; 1218 link = &head; 1219 sc_max = SYSCONF_EXACT(_SC_NPROCESSORS_CONF, &local_err); 1220 1221 while (local_err == NULL && current < sc_max) { 1222 GuestLogicalProcessor *vcpu; 1223 GuestLogicalProcessorList *entry; 1224 1225 vcpu = g_malloc0(sizeof *vcpu); 1226 vcpu->logical_id = current++; 1227 vcpu->has_can_offline = true; /* lolspeak ftw */ 1228 transfer_vcpu(vcpu, true, &local_err); 1229 1230 entry = g_malloc0(sizeof *entry); 1231 entry->value = vcpu; 1232 1233 *link = entry; 1234 link = &entry->next; 1235 } 1236 1237 if (local_err == NULL) { 1238 /* there's no guest with zero VCPUs */ 1239 g_assert(head != NULL); 1240 return head; 1241 } 1242 1243 qapi_free_GuestLogicalProcessorList(head); 1244 error_propagate(errp, local_err); 1245 return NULL; 1246 } 1247 1248 int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) 1249 { 1250 int64_t processed; 1251 Error *local_err = NULL; 1252 1253 processed = 0; 1254 while (vcpus != NULL) { 1255 transfer_vcpu(vcpus->value, false, &local_err); 1256 if (local_err != NULL) { 1257 break; 1258 } 1259 ++processed; 1260 vcpus = vcpus->next; 1261 } 1262 1263 if (local_err != NULL) { 1264 if (processed == 0) { 1265 error_propagate(errp, local_err); 1266 } else { 1267 error_free(local_err); 1268 } 1269 } 1270 1271 return processed; 1272 } 1273 1274 #else /* defined(__linux__) */ 1275 1276 void qmp_guest_suspend_disk(Error **err) 1277 { 1278 error_set(err, QERR_UNSUPPORTED); 1279 } 1280 1281 void qmp_guest_suspend_ram(Error **err) 1282 { 1283 error_set(err, QERR_UNSUPPORTED); 1284 } 1285 1286 void qmp_guest_suspend_hybrid(Error **err) 1287 { 1288 error_set(err, QERR_UNSUPPORTED); 1289 } 1290 1291 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) 1292 { 1293 error_set(errp, QERR_UNSUPPORTED); 1294 return NULL; 1295 } 1296 1297 GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) 1298 { 1299 error_set(errp, QERR_UNSUPPORTED); 1300 return NULL; 1301 } 1302 1303 int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) 1304 { 1305 error_set(errp, QERR_UNSUPPORTED); 1306 return -1; 1307 } 1308 1309 #endif 1310 1311 #if !defined(CONFIG_FSFREEZE) 1312 1313 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err) 1314 { 1315 error_set(err, QERR_UNSUPPORTED); 1316 1317 return 0; 1318 } 1319 1320 int64_t qmp_guest_fsfreeze_freeze(Error **err) 1321 { 1322 error_set(err, QERR_UNSUPPORTED); 1323 1324 return 0; 1325 } 1326 1327 int64_t qmp_guest_fsfreeze_thaw(Error **err) 1328 { 1329 error_set(err, QERR_UNSUPPORTED); 1330 1331 return 0; 1332 } 1333 #endif /* CONFIG_FSFREEZE */ 1334 1335 #if !defined(CONFIG_FSTRIM) 1336 void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err) 1337 { 1338 error_set(err, QERR_UNSUPPORTED); 1339 } 1340 #endif 1341 1342 /* register init/cleanup routines for stateful command groups */ 1343 void ga_command_state_init(GAState *s, GACommandState *cs) 1344 { 1345 #if defined(CONFIG_FSFREEZE) 1346 ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup); 1347 #endif 1348 ga_command_state_add(cs, guest_file_init, NULL); 1349 } 1350