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