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 <dirent.h> 22 #include <stdio.h> 23 #include <string.h> 24 #include <sys/stat.h> 25 #include <inttypes.h> 26 #include "qga/guest-agent-core.h" 27 #include "qga-qmp-commands.h" 28 #include "qapi/qmp/qerror.h" 29 #include "qemu/queue.h" 30 #include "qemu/host-utils.h" 31 32 #ifndef CONFIG_HAS_ENVIRON 33 #ifdef __APPLE__ 34 #include <crt_externs.h> 35 #define environ (*_NSGetEnviron()) 36 #else 37 extern char **environ; 38 #endif 39 #endif 40 41 #if defined(__linux__) 42 #include <mntent.h> 43 #include <linux/fs.h> 44 #include <ifaddrs.h> 45 #include <arpa/inet.h> 46 #include <sys/socket.h> 47 #include <net/if.h> 48 49 #ifdef FIFREEZE 50 #define CONFIG_FSFREEZE 51 #endif 52 #ifdef FITRIM 53 #define CONFIG_FSTRIM 54 #endif 55 #endif 56 57 static void ga_wait_child(pid_t pid, int *status, Error **errp) 58 { 59 pid_t rpid; 60 61 *status = 0; 62 63 do { 64 rpid = waitpid(pid, status, 0); 65 } while (rpid == -1 && errno == EINTR); 66 67 if (rpid == -1) { 68 error_setg_errno(errp, errno, "failed to wait for child (pid: %d)", 69 pid); 70 return; 71 } 72 73 g_assert(rpid == pid); 74 } 75 76 void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp) 77 { 78 const char *shutdown_flag; 79 Error *local_err = NULL; 80 pid_t pid; 81 int status; 82 83 slog("guest-shutdown called, mode: %s", mode); 84 if (!has_mode || strcmp(mode, "powerdown") == 0) { 85 shutdown_flag = "-P"; 86 } else if (strcmp(mode, "halt") == 0) { 87 shutdown_flag = "-H"; 88 } else if (strcmp(mode, "reboot") == 0) { 89 shutdown_flag = "-r"; 90 } else { 91 error_setg(errp, 92 "mode is invalid (valid values are: halt|powerdown|reboot"); 93 return; 94 } 95 96 pid = fork(); 97 if (pid == 0) { 98 /* child, start the shutdown */ 99 setsid(); 100 reopen_fd_to_null(0); 101 reopen_fd_to_null(1); 102 reopen_fd_to_null(2); 103 104 execle("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0", 105 "hypervisor initiated shutdown", (char*)NULL, environ); 106 _exit(EXIT_FAILURE); 107 } else if (pid < 0) { 108 error_setg_errno(errp, errno, "failed to create child process"); 109 return; 110 } 111 112 ga_wait_child(pid, &status, &local_err); 113 if (local_err) { 114 error_propagate(errp, local_err); 115 return; 116 } 117 118 if (!WIFEXITED(status)) { 119 error_setg(errp, "child process has terminated abnormally"); 120 return; 121 } 122 123 if (WEXITSTATUS(status)) { 124 error_setg(errp, "child process has failed to shutdown"); 125 return; 126 } 127 128 /* succeeded */ 129 } 130 131 int64_t qmp_guest_get_time(Error **errp) 132 { 133 int ret; 134 qemu_timeval tq; 135 int64_t time_ns; 136 137 ret = qemu_gettimeofday(&tq); 138 if (ret < 0) { 139 error_setg_errno(errp, errno, "Failed to get time"); 140 return -1; 141 } 142 143 time_ns = tq.tv_sec * 1000000000LL + tq.tv_usec * 1000; 144 return time_ns; 145 } 146 147 void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp) 148 { 149 int ret; 150 int status; 151 pid_t pid; 152 Error *local_err = NULL; 153 struct timeval tv; 154 155 /* If user has passed a time, validate and set it. */ 156 if (has_time) { 157 /* year-2038 will overflow in case time_t is 32bit */ 158 if (time_ns / 1000000000 != (time_t)(time_ns / 1000000000)) { 159 error_setg(errp, "Time %" PRId64 " is too large", time_ns); 160 return; 161 } 162 163 tv.tv_sec = time_ns / 1000000000; 164 tv.tv_usec = (time_ns % 1000000000) / 1000; 165 166 ret = settimeofday(&tv, NULL); 167 if (ret < 0) { 168 error_setg_errno(errp, errno, "Failed to set time to guest"); 169 return; 170 } 171 } 172 173 /* Now, if user has passed a time to set and the system time is set, we 174 * just need to synchronize the hardware clock. However, if no time was 175 * passed, user is requesting the opposite: set the system time from the 176 * hardware clock (RTC). */ 177 pid = fork(); 178 if (pid == 0) { 179 setsid(); 180 reopen_fd_to_null(0); 181 reopen_fd_to_null(1); 182 reopen_fd_to_null(2); 183 184 /* Use '/sbin/hwclock -w' to set RTC from the system time, 185 * or '/sbin/hwclock -s' to set the system time from RTC. */ 186 execle("/sbin/hwclock", "hwclock", has_time ? "-w" : "-s", 187 NULL, environ); 188 _exit(EXIT_FAILURE); 189 } else if (pid < 0) { 190 error_setg_errno(errp, errno, "failed to create child process"); 191 return; 192 } 193 194 ga_wait_child(pid, &status, &local_err); 195 if (local_err) { 196 error_propagate(errp, local_err); 197 return; 198 } 199 200 if (!WIFEXITED(status)) { 201 error_setg(errp, "child process has terminated abnormally"); 202 return; 203 } 204 205 if (WEXITSTATUS(status)) { 206 error_setg(errp, "hwclock failed to set hardware clock to system time"); 207 return; 208 } 209 } 210 211 typedef struct GuestFileHandle { 212 uint64_t id; 213 FILE *fh; 214 QTAILQ_ENTRY(GuestFileHandle) next; 215 } GuestFileHandle; 216 217 static struct { 218 QTAILQ_HEAD(, GuestFileHandle) filehandles; 219 } guest_file_state; 220 221 static int64_t guest_file_handle_add(FILE *fh, Error **errp) 222 { 223 GuestFileHandle *gfh; 224 int64_t handle; 225 226 handle = ga_get_fd_handle(ga_state, errp); 227 if (handle < 0) { 228 return -1; 229 } 230 231 gfh = g_malloc0(sizeof(GuestFileHandle)); 232 gfh->id = handle; 233 gfh->fh = fh; 234 QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next); 235 236 return handle; 237 } 238 239 static GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp) 240 { 241 GuestFileHandle *gfh; 242 243 QTAILQ_FOREACH(gfh, &guest_file_state.filehandles, next) 244 { 245 if (gfh->id == id) { 246 return gfh; 247 } 248 } 249 250 error_setg(errp, "handle '%" PRId64 "' has not been found", id); 251 return NULL; 252 } 253 254 typedef const char * const ccpc; 255 256 #ifndef O_BINARY 257 #define O_BINARY 0 258 #endif 259 260 /* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html */ 261 static const struct { 262 ccpc *forms; 263 int oflag_base; 264 } guest_file_open_modes[] = { 265 { (ccpc[]){ "r", NULL }, O_RDONLY }, 266 { (ccpc[]){ "rb", NULL }, O_RDONLY | O_BINARY }, 267 { (ccpc[]){ "w", NULL }, O_WRONLY | O_CREAT | O_TRUNC }, 268 { (ccpc[]){ "wb", NULL }, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY }, 269 { (ccpc[]){ "a", NULL }, O_WRONLY | O_CREAT | O_APPEND }, 270 { (ccpc[]){ "ab", NULL }, O_WRONLY | O_CREAT | O_APPEND | O_BINARY }, 271 { (ccpc[]){ "r+", NULL }, O_RDWR }, 272 { (ccpc[]){ "rb+", "r+b", NULL }, O_RDWR | O_BINARY }, 273 { (ccpc[]){ "w+", NULL }, O_RDWR | O_CREAT | O_TRUNC }, 274 { (ccpc[]){ "wb+", "w+b", NULL }, O_RDWR | O_CREAT | O_TRUNC | O_BINARY }, 275 { (ccpc[]){ "a+", NULL }, O_RDWR | O_CREAT | O_APPEND }, 276 { (ccpc[]){ "ab+", "a+b", NULL }, O_RDWR | O_CREAT | O_APPEND | O_BINARY } 277 }; 278 279 static int 280 find_open_flag(const char *mode_str, Error **errp) 281 { 282 unsigned mode; 283 284 for (mode = 0; mode < ARRAY_SIZE(guest_file_open_modes); ++mode) { 285 ccpc *form; 286 287 form = guest_file_open_modes[mode].forms; 288 while (*form != NULL && strcmp(*form, mode_str) != 0) { 289 ++form; 290 } 291 if (*form != NULL) { 292 break; 293 } 294 } 295 296 if (mode == ARRAY_SIZE(guest_file_open_modes)) { 297 error_setg(errp, "invalid file open mode '%s'", mode_str); 298 return -1; 299 } 300 return guest_file_open_modes[mode].oflag_base | O_NOCTTY | O_NONBLOCK; 301 } 302 303 #define DEFAULT_NEW_FILE_MODE (S_IRUSR | S_IWUSR | \ 304 S_IRGRP | S_IWGRP | \ 305 S_IROTH | S_IWOTH) 306 307 static FILE * 308 safe_open_or_create(const char *path, const char *mode, Error **errp) 309 { 310 Error *local_err = NULL; 311 int oflag; 312 313 oflag = find_open_flag(mode, &local_err); 314 if (local_err == NULL) { 315 int fd; 316 317 /* If the caller wants / allows creation of a new file, we implement it 318 * with a two step process: open() + (open() / fchmod()). 319 * 320 * First we insist on creating the file exclusively as a new file. If 321 * that succeeds, we're free to set any file-mode bits on it. (The 322 * motivation is that we want to set those file-mode bits independently 323 * of the current umask.) 324 * 325 * If the exclusive creation fails because the file already exists 326 * (EEXIST is not possible for any other reason), we just attempt to 327 * open the file, but in this case we won't be allowed to change the 328 * file-mode bits on the preexistent file. 329 * 330 * The pathname should never disappear between the two open()s in 331 * practice. If it happens, then someone very likely tried to race us. 332 * In this case just go ahead and report the ENOENT from the second 333 * open() to the caller. 334 * 335 * If the caller wants to open a preexistent file, then the first 336 * open() is decisive and its third argument is ignored, and the second 337 * open() and the fchmod() are never called. 338 */ 339 fd = open(path, oflag | ((oflag & O_CREAT) ? O_EXCL : 0), 0); 340 if (fd == -1 && errno == EEXIST) { 341 oflag &= ~(unsigned)O_CREAT; 342 fd = open(path, oflag); 343 } 344 345 if (fd == -1) { 346 error_setg_errno(&local_err, errno, "failed to open file '%s' " 347 "(mode: '%s')", path, mode); 348 } else { 349 qemu_set_cloexec(fd); 350 351 if ((oflag & O_CREAT) && fchmod(fd, DEFAULT_NEW_FILE_MODE) == -1) { 352 error_setg_errno(&local_err, errno, "failed to set permission " 353 "0%03o on new file '%s' (mode: '%s')", 354 (unsigned)DEFAULT_NEW_FILE_MODE, path, mode); 355 } else { 356 FILE *f; 357 358 f = fdopen(fd, mode); 359 if (f == NULL) { 360 error_setg_errno(&local_err, errno, "failed to associate " 361 "stdio stream with file descriptor %d, " 362 "file '%s' (mode: '%s')", fd, path, mode); 363 } else { 364 return f; 365 } 366 } 367 368 close(fd); 369 if (oflag & O_CREAT) { 370 unlink(path); 371 } 372 } 373 } 374 375 error_propagate(errp, local_err); 376 return NULL; 377 } 378 379 int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, 380 Error **errp) 381 { 382 FILE *fh; 383 Error *local_err = NULL; 384 int fd; 385 int64_t ret = -1, handle; 386 387 if (!has_mode) { 388 mode = "r"; 389 } 390 slog("guest-file-open called, filepath: %s, mode: %s", path, mode); 391 fh = safe_open_or_create(path, mode, &local_err); 392 if (local_err != NULL) { 393 error_propagate(errp, local_err); 394 return -1; 395 } 396 397 /* set fd non-blocking to avoid common use cases (like reading from a 398 * named pipe) from hanging the agent 399 */ 400 fd = fileno(fh); 401 ret = fcntl(fd, F_GETFL); 402 ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK); 403 if (ret == -1) { 404 error_setg_errno(errp, errno, "failed to make file '%s' non-blocking", 405 path); 406 fclose(fh); 407 return -1; 408 } 409 410 handle = guest_file_handle_add(fh, errp); 411 if (handle < 0) { 412 fclose(fh); 413 return -1; 414 } 415 416 slog("guest-file-open, handle: %" PRId64, handle); 417 return handle; 418 } 419 420 void qmp_guest_file_close(int64_t handle, Error **errp) 421 { 422 GuestFileHandle *gfh = guest_file_handle_find(handle, errp); 423 int ret; 424 425 slog("guest-file-close called, handle: %" PRId64, handle); 426 if (!gfh) { 427 return; 428 } 429 430 ret = fclose(gfh->fh); 431 if (ret == EOF) { 432 error_setg_errno(errp, errno, "failed to close handle"); 433 return; 434 } 435 436 QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next); 437 g_free(gfh); 438 } 439 440 struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count, 441 int64_t count, Error **errp) 442 { 443 GuestFileHandle *gfh = guest_file_handle_find(handle, errp); 444 GuestFileRead *read_data = NULL; 445 guchar *buf; 446 FILE *fh; 447 size_t read_count; 448 449 if (!gfh) { 450 return NULL; 451 } 452 453 if (!has_count) { 454 count = QGA_READ_COUNT_DEFAULT; 455 } else if (count < 0) { 456 error_setg(errp, "value '%" PRId64 "' is invalid for argument count", 457 count); 458 return NULL; 459 } 460 461 fh = gfh->fh; 462 buf = g_malloc0(count+1); 463 read_count = fread(buf, 1, count, fh); 464 if (ferror(fh)) { 465 error_setg_errno(errp, errno, "failed to read file"); 466 slog("guest-file-read failed, handle: %" PRId64, handle); 467 } else { 468 buf[read_count] = 0; 469 read_data = g_malloc0(sizeof(GuestFileRead)); 470 read_data->count = read_count; 471 read_data->eof = feof(fh); 472 if (read_count) { 473 read_data->buf_b64 = g_base64_encode(buf, read_count); 474 } 475 } 476 g_free(buf); 477 clearerr(fh); 478 479 return read_data; 480 } 481 482 GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64, 483 bool has_count, int64_t count, 484 Error **errp) 485 { 486 GuestFileWrite *write_data = NULL; 487 guchar *buf; 488 gsize buf_len; 489 int write_count; 490 GuestFileHandle *gfh = guest_file_handle_find(handle, errp); 491 FILE *fh; 492 493 if (!gfh) { 494 return NULL; 495 } 496 497 fh = gfh->fh; 498 buf = g_base64_decode(buf_b64, &buf_len); 499 500 if (!has_count) { 501 count = buf_len; 502 } else if (count < 0 || count > buf_len) { 503 error_setg(errp, "value '%" PRId64 "' is invalid for argument count", 504 count); 505 g_free(buf); 506 return NULL; 507 } 508 509 write_count = fwrite(buf, 1, count, fh); 510 if (ferror(fh)) { 511 error_setg_errno(errp, errno, "failed to write to file"); 512 slog("guest-file-write failed, handle: %" PRId64, handle); 513 } else { 514 write_data = g_malloc0(sizeof(GuestFileWrite)); 515 write_data->count = write_count; 516 write_data->eof = feof(fh); 517 } 518 g_free(buf); 519 clearerr(fh); 520 521 return write_data; 522 } 523 524 struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset, 525 int64_t whence, Error **errp) 526 { 527 GuestFileHandle *gfh = guest_file_handle_find(handle, errp); 528 GuestFileSeek *seek_data = NULL; 529 FILE *fh; 530 int ret; 531 532 if (!gfh) { 533 return NULL; 534 } 535 536 fh = gfh->fh; 537 ret = fseek(fh, offset, whence); 538 if (ret == -1) { 539 error_setg_errno(errp, errno, "failed to seek file"); 540 } else { 541 seek_data = g_new0(GuestFileSeek, 1); 542 seek_data->position = ftell(fh); 543 seek_data->eof = feof(fh); 544 } 545 clearerr(fh); 546 547 return seek_data; 548 } 549 550 void qmp_guest_file_flush(int64_t handle, Error **errp) 551 { 552 GuestFileHandle *gfh = guest_file_handle_find(handle, errp); 553 FILE *fh; 554 int ret; 555 556 if (!gfh) { 557 return; 558 } 559 560 fh = gfh->fh; 561 ret = fflush(fh); 562 if (ret == EOF) { 563 error_setg_errno(errp, errno, "failed to flush file"); 564 } 565 } 566 567 static void guest_file_init(void) 568 { 569 QTAILQ_INIT(&guest_file_state.filehandles); 570 } 571 572 /* linux-specific implementations. avoid this if at all possible. */ 573 #if defined(__linux__) 574 575 #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) 576 typedef struct FsMount { 577 char *dirname; 578 char *devtype; 579 unsigned int devmajor, devminor; 580 QTAILQ_ENTRY(FsMount) next; 581 } FsMount; 582 583 typedef QTAILQ_HEAD(FsMountList, FsMount) FsMountList; 584 585 static void free_fs_mount_list(FsMountList *mounts) 586 { 587 FsMount *mount, *temp; 588 589 if (!mounts) { 590 return; 591 } 592 593 QTAILQ_FOREACH_SAFE(mount, mounts, next, temp) { 594 QTAILQ_REMOVE(mounts, mount, next); 595 g_free(mount->dirname); 596 g_free(mount->devtype); 597 g_free(mount); 598 } 599 } 600 601 static int dev_major_minor(const char *devpath, 602 unsigned int *devmajor, unsigned int *devminor) 603 { 604 struct stat st; 605 606 *devmajor = 0; 607 *devminor = 0; 608 609 if (stat(devpath, &st) < 0) { 610 slog("failed to stat device file '%s': %s", devpath, strerror(errno)); 611 return -1; 612 } 613 if (S_ISDIR(st.st_mode)) { 614 /* It is bind mount */ 615 return -2; 616 } 617 if (S_ISBLK(st.st_mode)) { 618 *devmajor = major(st.st_rdev); 619 *devminor = minor(st.st_rdev); 620 return 0; 621 } 622 return -1; 623 } 624 625 /* 626 * Walk the mount table and build a list of local file systems 627 */ 628 static void build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp) 629 { 630 struct mntent *ment; 631 FsMount *mount; 632 char const *mtab = "/proc/self/mounts"; 633 FILE *fp; 634 unsigned int devmajor, devminor; 635 636 fp = setmntent(mtab, "r"); 637 if (!fp) { 638 error_setg(errp, "failed to open mtab file: '%s'", mtab); 639 return; 640 } 641 642 while ((ment = getmntent(fp))) { 643 /* 644 * An entry which device name doesn't start with a '/' is 645 * either a dummy file system or a network file system. 646 * Add special handling for smbfs and cifs as is done by 647 * coreutils as well. 648 */ 649 if ((ment->mnt_fsname[0] != '/') || 650 (strcmp(ment->mnt_type, "smbfs") == 0) || 651 (strcmp(ment->mnt_type, "cifs") == 0)) { 652 continue; 653 } 654 if (dev_major_minor(ment->mnt_fsname, &devmajor, &devminor) == -2) { 655 /* Skip bind mounts */ 656 continue; 657 } 658 659 mount = g_malloc0(sizeof(FsMount)); 660 mount->dirname = g_strdup(ment->mnt_dir); 661 mount->devtype = g_strdup(ment->mnt_type); 662 mount->devmajor = devmajor; 663 mount->devminor = devminor; 664 665 QTAILQ_INSERT_TAIL(mounts, mount, next); 666 } 667 668 endmntent(fp); 669 } 670 671 static void decode_mntname(char *name, int len) 672 { 673 int i, j = 0; 674 for (i = 0; i <= len; i++) { 675 if (name[i] != '\\') { 676 name[j++] = name[i]; 677 } else if (name[i + 1] == '\\') { 678 name[j++] = '\\'; 679 i++; 680 } else if (name[i + 1] >= '0' && name[i + 1] <= '3' && 681 name[i + 2] >= '0' && name[i + 2] <= '7' && 682 name[i + 3] >= '0' && name[i + 3] <= '7') { 683 name[j++] = (name[i + 1] - '0') * 64 + 684 (name[i + 2] - '0') * 8 + 685 (name[i + 3] - '0'); 686 i += 3; 687 } else { 688 name[j++] = name[i]; 689 } 690 } 691 } 692 693 static void build_fs_mount_list(FsMountList *mounts, Error **errp) 694 { 695 FsMount *mount; 696 char const *mountinfo = "/proc/self/mountinfo"; 697 FILE *fp; 698 char *line = NULL, *dash; 699 size_t n; 700 char check; 701 unsigned int devmajor, devminor; 702 int ret, dir_s, dir_e, type_s, type_e, dev_s, dev_e; 703 704 fp = fopen(mountinfo, "r"); 705 if (!fp) { 706 build_fs_mount_list_from_mtab(mounts, errp); 707 return; 708 } 709 710 while (getline(&line, &n, fp) != -1) { 711 ret = sscanf(line, "%*u %*u %u:%u %*s %n%*s%n%c", 712 &devmajor, &devminor, &dir_s, &dir_e, &check); 713 if (ret < 3) { 714 continue; 715 } 716 dash = strstr(line + dir_e, " - "); 717 if (!dash) { 718 continue; 719 } 720 ret = sscanf(dash, " - %n%*s%n %n%*s%n%c", 721 &type_s, &type_e, &dev_s, &dev_e, &check); 722 if (ret < 1) { 723 continue; 724 } 725 line[dir_e] = 0; 726 dash[type_e] = 0; 727 dash[dev_e] = 0; 728 decode_mntname(line + dir_s, dir_e - dir_s); 729 decode_mntname(dash + dev_s, dev_e - dev_s); 730 if (devmajor == 0) { 731 /* btrfs reports major number = 0 */ 732 if (strcmp("btrfs", dash + type_s) != 0 || 733 dev_major_minor(dash + dev_s, &devmajor, &devminor) < 0) { 734 continue; 735 } 736 } 737 738 mount = g_malloc0(sizeof(FsMount)); 739 mount->dirname = g_strdup(line + dir_s); 740 mount->devtype = g_strdup(dash + type_s); 741 mount->devmajor = devmajor; 742 mount->devminor = devminor; 743 744 QTAILQ_INSERT_TAIL(mounts, mount, next); 745 } 746 free(line); 747 748 fclose(fp); 749 } 750 #endif 751 752 #if defined(CONFIG_FSFREEZE) 753 754 static char *get_pci_driver(char const *syspath, int pathlen, Error **errp) 755 { 756 char *path; 757 char *dpath; 758 char *driver = NULL; 759 char buf[PATH_MAX]; 760 ssize_t len; 761 762 path = g_strndup(syspath, pathlen); 763 dpath = g_strdup_printf("%s/driver", path); 764 len = readlink(dpath, buf, sizeof(buf) - 1); 765 if (len != -1) { 766 buf[len] = 0; 767 driver = g_strdup(basename(buf)); 768 } 769 g_free(dpath); 770 g_free(path); 771 return driver; 772 } 773 774 static int compare_uint(const void *_a, const void *_b) 775 { 776 unsigned int a = *(unsigned int *)_a; 777 unsigned int b = *(unsigned int *)_b; 778 779 return a < b ? -1 : a > b ? 1 : 0; 780 } 781 782 /* Walk the specified sysfs and build a sorted list of host or ata numbers */ 783 static int build_hosts(char const *syspath, char const *host, bool ata, 784 unsigned int *hosts, int hosts_max, Error **errp) 785 { 786 char *path; 787 DIR *dir; 788 struct dirent *entry; 789 int i = 0; 790 791 path = g_strndup(syspath, host - syspath); 792 dir = opendir(path); 793 if (!dir) { 794 error_setg_errno(errp, errno, "opendir(\"%s\")", path); 795 g_free(path); 796 return -1; 797 } 798 799 while (i < hosts_max) { 800 entry = readdir(dir); 801 if (!entry) { 802 break; 803 } 804 if (ata && sscanf(entry->d_name, "ata%d", hosts + i) == 1) { 805 ++i; 806 } else if (!ata && sscanf(entry->d_name, "host%d", hosts + i) == 1) { 807 ++i; 808 } 809 } 810 811 qsort(hosts, i, sizeof(hosts[0]), compare_uint); 812 813 g_free(path); 814 closedir(dir); 815 return i; 816 } 817 818 /* Store disk device info specified by @sysfs into @fs */ 819 static void build_guest_fsinfo_for_real_device(char const *syspath, 820 GuestFilesystemInfo *fs, 821 Error **errp) 822 { 823 unsigned int pci[4], host, hosts[8], tgt[3]; 824 int i, nhosts = 0, pcilen; 825 GuestDiskAddress *disk; 826 GuestPCIAddress *pciaddr; 827 GuestDiskAddressList *list = NULL; 828 bool has_ata = false, has_host = false, has_tgt = false; 829 char *p, *q, *driver = NULL; 830 831 p = strstr(syspath, "/devices/pci"); 832 if (!p || sscanf(p + 12, "%*x:%*x/%x:%x:%x.%x%n", 833 pci, pci + 1, pci + 2, pci + 3, &pcilen) < 4) { 834 g_debug("only pci device is supported: sysfs path \"%s\"", syspath); 835 return; 836 } 837 838 driver = get_pci_driver(syspath, (p + 12 + pcilen) - syspath, errp); 839 if (!driver) { 840 goto cleanup; 841 } 842 843 p = strstr(syspath, "/target"); 844 if (p && sscanf(p + 7, "%*u:%*u:%*u/%*u:%u:%u:%u", 845 tgt, tgt + 1, tgt + 2) == 3) { 846 has_tgt = true; 847 } 848 849 p = strstr(syspath, "/ata"); 850 if (p) { 851 q = p + 4; 852 has_ata = true; 853 } else { 854 p = strstr(syspath, "/host"); 855 q = p + 5; 856 } 857 if (p && sscanf(q, "%u", &host) == 1) { 858 has_host = true; 859 nhosts = build_hosts(syspath, p, has_ata, hosts, 860 sizeof(hosts) / sizeof(hosts[0]), errp); 861 if (nhosts < 0) { 862 goto cleanup; 863 } 864 } 865 866 pciaddr = g_malloc0(sizeof(*pciaddr)); 867 pciaddr->domain = pci[0]; 868 pciaddr->bus = pci[1]; 869 pciaddr->slot = pci[2]; 870 pciaddr->function = pci[3]; 871 872 disk = g_malloc0(sizeof(*disk)); 873 disk->pci_controller = pciaddr; 874 875 list = g_malloc0(sizeof(*list)); 876 list->value = disk; 877 878 if (strcmp(driver, "ata_piix") == 0) { 879 /* a host per ide bus, target*:0:<unit>:0 */ 880 if (!has_host || !has_tgt) { 881 g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver); 882 goto cleanup; 883 } 884 for (i = 0; i < nhosts; i++) { 885 if (host == hosts[i]) { 886 disk->bus_type = GUEST_DISK_BUS_TYPE_IDE; 887 disk->bus = i; 888 disk->unit = tgt[1]; 889 break; 890 } 891 } 892 if (i >= nhosts) { 893 g_debug("no host for '%s' (driver '%s')", syspath, driver); 894 goto cleanup; 895 } 896 } else if (strcmp(driver, "sym53c8xx") == 0) { 897 /* scsi(LSI Logic): target*:0:<unit>:0 */ 898 if (!has_tgt) { 899 g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver); 900 goto cleanup; 901 } 902 disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI; 903 disk->unit = tgt[1]; 904 } else if (strcmp(driver, "virtio-pci") == 0) { 905 if (has_tgt) { 906 /* virtio-scsi: target*:0:0:<unit> */ 907 disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI; 908 disk->unit = tgt[2]; 909 } else { 910 /* virtio-blk: 1 disk per 1 device */ 911 disk->bus_type = GUEST_DISK_BUS_TYPE_VIRTIO; 912 } 913 } else if (strcmp(driver, "ahci") == 0) { 914 /* ahci: 1 host per 1 unit */ 915 if (!has_host || !has_tgt) { 916 g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver); 917 goto cleanup; 918 } 919 for (i = 0; i < nhosts; i++) { 920 if (host == hosts[i]) { 921 disk->unit = i; 922 disk->bus_type = GUEST_DISK_BUS_TYPE_SATA; 923 break; 924 } 925 } 926 if (i >= nhosts) { 927 g_debug("no host for '%s' (driver '%s')", syspath, driver); 928 goto cleanup; 929 } 930 } else { 931 g_debug("unknown driver '%s' (sysfs path '%s')", driver, syspath); 932 goto cleanup; 933 } 934 935 list->next = fs->disk; 936 fs->disk = list; 937 g_free(driver); 938 return; 939 940 cleanup: 941 if (list) { 942 qapi_free_GuestDiskAddressList(list); 943 } 944 g_free(driver); 945 } 946 947 static void build_guest_fsinfo_for_device(char const *devpath, 948 GuestFilesystemInfo *fs, 949 Error **errp); 950 951 /* Store a list of slave devices of virtual volume specified by @syspath into 952 * @fs */ 953 static void build_guest_fsinfo_for_virtual_device(char const *syspath, 954 GuestFilesystemInfo *fs, 955 Error **errp) 956 { 957 DIR *dir; 958 char *dirpath; 959 struct dirent *entry; 960 961 dirpath = g_strdup_printf("%s/slaves", syspath); 962 dir = opendir(dirpath); 963 if (!dir) { 964 error_setg_errno(errp, errno, "opendir(\"%s\")", dirpath); 965 g_free(dirpath); 966 return; 967 } 968 969 for (;;) { 970 errno = 0; 971 entry = readdir(dir); 972 if (entry == NULL) { 973 if (errno) { 974 error_setg_errno(errp, errno, "readdir(\"%s\")", dirpath); 975 } 976 break; 977 } 978 979 if (entry->d_type == DT_LNK) { 980 char *path; 981 982 g_debug(" slave device '%s'", entry->d_name); 983 path = g_strdup_printf("%s/slaves/%s", syspath, entry->d_name); 984 build_guest_fsinfo_for_device(path, fs, errp); 985 g_free(path); 986 987 if (*errp) { 988 break; 989 } 990 } 991 } 992 993 g_free(dirpath); 994 closedir(dir); 995 } 996 997 /* Dispatch to functions for virtual/real device */ 998 static void build_guest_fsinfo_for_device(char const *devpath, 999 GuestFilesystemInfo *fs, 1000 Error **errp) 1001 { 1002 char *syspath = realpath(devpath, NULL); 1003 1004 if (!syspath) { 1005 error_setg_errno(errp, errno, "realpath(\"%s\")", devpath); 1006 return; 1007 } 1008 1009 if (!fs->name) { 1010 fs->name = g_strdup(basename(syspath)); 1011 } 1012 1013 g_debug(" parse sysfs path '%s'", syspath); 1014 1015 if (strstr(syspath, "/devices/virtual/block/")) { 1016 build_guest_fsinfo_for_virtual_device(syspath, fs, errp); 1017 } else { 1018 build_guest_fsinfo_for_real_device(syspath, fs, errp); 1019 } 1020 1021 free(syspath); 1022 } 1023 1024 /* Return a list of the disk device(s)' info which @mount lies on */ 1025 static GuestFilesystemInfo *build_guest_fsinfo(struct FsMount *mount, 1026 Error **errp) 1027 { 1028 GuestFilesystemInfo *fs = g_malloc0(sizeof(*fs)); 1029 char *devpath = g_strdup_printf("/sys/dev/block/%u:%u", 1030 mount->devmajor, mount->devminor); 1031 1032 fs->mountpoint = g_strdup(mount->dirname); 1033 fs->type = g_strdup(mount->devtype); 1034 build_guest_fsinfo_for_device(devpath, fs, errp); 1035 1036 g_free(devpath); 1037 return fs; 1038 } 1039 1040 GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) 1041 { 1042 FsMountList mounts; 1043 struct FsMount *mount; 1044 GuestFilesystemInfoList *new, *ret = NULL; 1045 Error *local_err = NULL; 1046 1047 QTAILQ_INIT(&mounts); 1048 build_fs_mount_list(&mounts, &local_err); 1049 if (local_err) { 1050 error_propagate(errp, local_err); 1051 return NULL; 1052 } 1053 1054 QTAILQ_FOREACH(mount, &mounts, next) { 1055 g_debug("Building guest fsinfo for '%s'", mount->dirname); 1056 1057 new = g_malloc0(sizeof(*ret)); 1058 new->value = build_guest_fsinfo(mount, &local_err); 1059 new->next = ret; 1060 ret = new; 1061 if (local_err) { 1062 error_propagate(errp, local_err); 1063 qapi_free_GuestFilesystemInfoList(ret); 1064 ret = NULL; 1065 break; 1066 } 1067 } 1068 1069 free_fs_mount_list(&mounts); 1070 return ret; 1071 } 1072 1073 1074 typedef enum { 1075 FSFREEZE_HOOK_THAW = 0, 1076 FSFREEZE_HOOK_FREEZE, 1077 } FsfreezeHookArg; 1078 1079 static const char *fsfreeze_hook_arg_string[] = { 1080 "thaw", 1081 "freeze", 1082 }; 1083 1084 static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp) 1085 { 1086 int status; 1087 pid_t pid; 1088 const char *hook; 1089 const char *arg_str = fsfreeze_hook_arg_string[arg]; 1090 Error *local_err = NULL; 1091 1092 hook = ga_fsfreeze_hook(ga_state); 1093 if (!hook) { 1094 return; 1095 } 1096 if (access(hook, X_OK) != 0) { 1097 error_setg_errno(errp, errno, "can't access fsfreeze hook '%s'", hook); 1098 return; 1099 } 1100 1101 slog("executing fsfreeze hook with arg '%s'", arg_str); 1102 pid = fork(); 1103 if (pid == 0) { 1104 setsid(); 1105 reopen_fd_to_null(0); 1106 reopen_fd_to_null(1); 1107 reopen_fd_to_null(2); 1108 1109 execle(hook, hook, arg_str, NULL, environ); 1110 _exit(EXIT_FAILURE); 1111 } else if (pid < 0) { 1112 error_setg_errno(errp, errno, "failed to create child process"); 1113 return; 1114 } 1115 1116 ga_wait_child(pid, &status, &local_err); 1117 if (local_err) { 1118 error_propagate(errp, local_err); 1119 return; 1120 } 1121 1122 if (!WIFEXITED(status)) { 1123 error_setg(errp, "fsfreeze hook has terminated abnormally"); 1124 return; 1125 } 1126 1127 status = WEXITSTATUS(status); 1128 if (status) { 1129 error_setg(errp, "fsfreeze hook has failed with status %d", status); 1130 return; 1131 } 1132 } 1133 1134 /* 1135 * Return status of freeze/thaw 1136 */ 1137 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp) 1138 { 1139 if (ga_is_frozen(ga_state)) { 1140 return GUEST_FSFREEZE_STATUS_FROZEN; 1141 } 1142 1143 return GUEST_FSFREEZE_STATUS_THAWED; 1144 } 1145 1146 int64_t qmp_guest_fsfreeze_freeze(Error **errp) 1147 { 1148 return qmp_guest_fsfreeze_freeze_list(false, NULL, errp); 1149 } 1150 1151 /* 1152 * Walk list of mounted file systems in the guest, and freeze the ones which 1153 * are real local file systems. 1154 */ 1155 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, 1156 strList *mountpoints, 1157 Error **errp) 1158 { 1159 int ret = 0, i = 0; 1160 strList *list; 1161 FsMountList mounts; 1162 struct FsMount *mount; 1163 Error *local_err = NULL; 1164 int fd; 1165 1166 slog("guest-fsfreeze called"); 1167 1168 execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err); 1169 if (local_err) { 1170 error_propagate(errp, local_err); 1171 return -1; 1172 } 1173 1174 QTAILQ_INIT(&mounts); 1175 build_fs_mount_list(&mounts, &local_err); 1176 if (local_err) { 1177 error_propagate(errp, local_err); 1178 return -1; 1179 } 1180 1181 /* cannot risk guest agent blocking itself on a write in this state */ 1182 ga_set_frozen(ga_state); 1183 1184 QTAILQ_FOREACH_REVERSE(mount, &mounts, FsMountList, next) { 1185 /* To issue fsfreeze in the reverse order of mounts, check if the 1186 * mount is listed in the list here */ 1187 if (has_mountpoints) { 1188 for (list = mountpoints; list; list = list->next) { 1189 if (strcmp(list->value, mount->dirname) == 0) { 1190 break; 1191 } 1192 } 1193 if (!list) { 1194 continue; 1195 } 1196 } 1197 1198 fd = qemu_open(mount->dirname, O_RDONLY); 1199 if (fd == -1) { 1200 error_setg_errno(errp, errno, "failed to open %s", mount->dirname); 1201 goto error; 1202 } 1203 1204 /* we try to cull filesytems we know won't work in advance, but other 1205 * filesytems may not implement fsfreeze for less obvious reasons. 1206 * these will report EOPNOTSUPP. we simply ignore these when tallying 1207 * the number of frozen filesystems. 1208 * 1209 * any other error means a failure to freeze a filesystem we 1210 * expect to be freezable, so return an error in those cases 1211 * and return system to thawed state. 1212 */ 1213 ret = ioctl(fd, FIFREEZE); 1214 if (ret == -1) { 1215 if (errno != EOPNOTSUPP) { 1216 error_setg_errno(errp, errno, "failed to freeze %s", 1217 mount->dirname); 1218 close(fd); 1219 goto error; 1220 } 1221 } else { 1222 i++; 1223 } 1224 close(fd); 1225 } 1226 1227 free_fs_mount_list(&mounts); 1228 return i; 1229 1230 error: 1231 free_fs_mount_list(&mounts); 1232 qmp_guest_fsfreeze_thaw(NULL); 1233 return 0; 1234 } 1235 1236 /* 1237 * Walk list of frozen file systems in the guest, and thaw them. 1238 */ 1239 int64_t qmp_guest_fsfreeze_thaw(Error **errp) 1240 { 1241 int ret; 1242 FsMountList mounts; 1243 FsMount *mount; 1244 int fd, i = 0, logged; 1245 Error *local_err = NULL; 1246 1247 QTAILQ_INIT(&mounts); 1248 build_fs_mount_list(&mounts, &local_err); 1249 if (local_err) { 1250 error_propagate(errp, local_err); 1251 return 0; 1252 } 1253 1254 QTAILQ_FOREACH(mount, &mounts, next) { 1255 logged = false; 1256 fd = qemu_open(mount->dirname, O_RDONLY); 1257 if (fd == -1) { 1258 continue; 1259 } 1260 /* we have no way of knowing whether a filesystem was actually unfrozen 1261 * as a result of a successful call to FITHAW, only that if an error 1262 * was returned the filesystem was *not* unfrozen by that particular 1263 * call. 1264 * 1265 * since multiple preceding FIFREEZEs require multiple calls to FITHAW 1266 * to unfreeze, continuing issuing FITHAW until an error is returned, 1267 * in which case either the filesystem is in an unfreezable state, or, 1268 * more likely, it was thawed previously (and remains so afterward). 1269 * 1270 * also, since the most recent successful call is the one that did 1271 * the actual unfreeze, we can use this to provide an accurate count 1272 * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which 1273 * may * be useful for determining whether a filesystem was unfrozen 1274 * during the freeze/thaw phase by a process other than qemu-ga. 1275 */ 1276 do { 1277 ret = ioctl(fd, FITHAW); 1278 if (ret == 0 && !logged) { 1279 i++; 1280 logged = true; 1281 } 1282 } while (ret == 0); 1283 close(fd); 1284 } 1285 1286 ga_unset_frozen(ga_state); 1287 free_fs_mount_list(&mounts); 1288 1289 execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp); 1290 1291 return i; 1292 } 1293 1294 static void guest_fsfreeze_cleanup(void) 1295 { 1296 Error *err = NULL; 1297 1298 if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) { 1299 qmp_guest_fsfreeze_thaw(&err); 1300 if (err) { 1301 slog("failed to clean up frozen filesystems: %s", 1302 error_get_pretty(err)); 1303 error_free(err); 1304 } 1305 } 1306 } 1307 #endif /* CONFIG_FSFREEZE */ 1308 1309 #if defined(CONFIG_FSTRIM) 1310 /* 1311 * Walk list of mounted file systems in the guest, and trim them. 1312 */ 1313 void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp) 1314 { 1315 int ret = 0; 1316 FsMountList mounts; 1317 struct FsMount *mount; 1318 int fd; 1319 Error *local_err = NULL; 1320 struct fstrim_range r = { 1321 .start = 0, 1322 .len = -1, 1323 .minlen = has_minimum ? minimum : 0, 1324 }; 1325 1326 slog("guest-fstrim called"); 1327 1328 QTAILQ_INIT(&mounts); 1329 build_fs_mount_list(&mounts, &local_err); 1330 if (local_err) { 1331 error_propagate(errp, local_err); 1332 return; 1333 } 1334 1335 QTAILQ_FOREACH(mount, &mounts, next) { 1336 fd = qemu_open(mount->dirname, O_RDONLY); 1337 if (fd == -1) { 1338 error_setg_errno(errp, errno, "failed to open %s", mount->dirname); 1339 goto error; 1340 } 1341 1342 /* We try to cull filesytems we know won't work in advance, but other 1343 * filesytems may not implement fstrim for less obvious reasons. These 1344 * will report EOPNOTSUPP; we simply ignore these errors. Any other 1345 * error means an unexpected error, so return it in those cases. In 1346 * some other cases ENOTTY will be reported (e.g. CD-ROMs). 1347 */ 1348 ret = ioctl(fd, FITRIM, &r); 1349 if (ret == -1) { 1350 if (errno != ENOTTY && errno != EOPNOTSUPP) { 1351 error_setg_errno(errp, errno, "failed to trim %s", 1352 mount->dirname); 1353 close(fd); 1354 goto error; 1355 } 1356 } 1357 close(fd); 1358 } 1359 1360 error: 1361 free_fs_mount_list(&mounts); 1362 } 1363 #endif /* CONFIG_FSTRIM */ 1364 1365 1366 #define LINUX_SYS_STATE_FILE "/sys/power/state" 1367 #define SUSPEND_SUPPORTED 0 1368 #define SUSPEND_NOT_SUPPORTED 1 1369 1370 static void bios_supports_mode(const char *pmutils_bin, const char *pmutils_arg, 1371 const char *sysfile_str, Error **errp) 1372 { 1373 Error *local_err = NULL; 1374 char *pmutils_path; 1375 pid_t pid; 1376 int status; 1377 1378 pmutils_path = g_find_program_in_path(pmutils_bin); 1379 1380 pid = fork(); 1381 if (!pid) { 1382 char buf[32]; /* hopefully big enough */ 1383 ssize_t ret; 1384 int fd; 1385 1386 setsid(); 1387 reopen_fd_to_null(0); 1388 reopen_fd_to_null(1); 1389 reopen_fd_to_null(2); 1390 1391 if (pmutils_path) { 1392 execle(pmutils_path, pmutils_bin, pmutils_arg, NULL, environ); 1393 } 1394 1395 /* 1396 * If we get here either pm-utils is not installed or execle() has 1397 * failed. Let's try the manual method if the caller wants it. 1398 */ 1399 1400 if (!sysfile_str) { 1401 _exit(SUSPEND_NOT_SUPPORTED); 1402 } 1403 1404 fd = open(LINUX_SYS_STATE_FILE, O_RDONLY); 1405 if (fd < 0) { 1406 _exit(SUSPEND_NOT_SUPPORTED); 1407 } 1408 1409 ret = read(fd, buf, sizeof(buf)-1); 1410 if (ret <= 0) { 1411 _exit(SUSPEND_NOT_SUPPORTED); 1412 } 1413 buf[ret] = '\0'; 1414 1415 if (strstr(buf, sysfile_str)) { 1416 _exit(SUSPEND_SUPPORTED); 1417 } 1418 1419 _exit(SUSPEND_NOT_SUPPORTED); 1420 } else if (pid < 0) { 1421 error_setg_errno(errp, errno, "failed to create child process"); 1422 goto out; 1423 } 1424 1425 ga_wait_child(pid, &status, &local_err); 1426 if (local_err) { 1427 error_propagate(errp, local_err); 1428 goto out; 1429 } 1430 1431 if (!WIFEXITED(status)) { 1432 error_setg(errp, "child process has terminated abnormally"); 1433 goto out; 1434 } 1435 1436 switch (WEXITSTATUS(status)) { 1437 case SUSPEND_SUPPORTED: 1438 goto out; 1439 case SUSPEND_NOT_SUPPORTED: 1440 error_setg(errp, 1441 "the requested suspend mode is not supported by the guest"); 1442 goto out; 1443 default: 1444 error_setg(errp, 1445 "the helper program '%s' returned an unexpected exit status" 1446 " code (%d)", pmutils_path, WEXITSTATUS(status)); 1447 goto out; 1448 } 1449 1450 out: 1451 g_free(pmutils_path); 1452 } 1453 1454 static void guest_suspend(const char *pmutils_bin, const char *sysfile_str, 1455 Error **errp) 1456 { 1457 Error *local_err = NULL; 1458 char *pmutils_path; 1459 pid_t pid; 1460 int status; 1461 1462 pmutils_path = g_find_program_in_path(pmutils_bin); 1463 1464 pid = fork(); 1465 if (pid == 0) { 1466 /* child */ 1467 int fd; 1468 1469 setsid(); 1470 reopen_fd_to_null(0); 1471 reopen_fd_to_null(1); 1472 reopen_fd_to_null(2); 1473 1474 if (pmutils_path) { 1475 execle(pmutils_path, pmutils_bin, NULL, environ); 1476 } 1477 1478 /* 1479 * If we get here either pm-utils is not installed or execle() has 1480 * failed. Let's try the manual method if the caller wants it. 1481 */ 1482 1483 if (!sysfile_str) { 1484 _exit(EXIT_FAILURE); 1485 } 1486 1487 fd = open(LINUX_SYS_STATE_FILE, O_WRONLY); 1488 if (fd < 0) { 1489 _exit(EXIT_FAILURE); 1490 } 1491 1492 if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) { 1493 _exit(EXIT_FAILURE); 1494 } 1495 1496 _exit(EXIT_SUCCESS); 1497 } else if (pid < 0) { 1498 error_setg_errno(errp, errno, "failed to create child process"); 1499 goto out; 1500 } 1501 1502 ga_wait_child(pid, &status, &local_err); 1503 if (local_err) { 1504 error_propagate(errp, local_err); 1505 goto out; 1506 } 1507 1508 if (!WIFEXITED(status)) { 1509 error_setg(errp, "child process has terminated abnormally"); 1510 goto out; 1511 } 1512 1513 if (WEXITSTATUS(status)) { 1514 error_setg(errp, "child process has failed to suspend"); 1515 goto out; 1516 } 1517 1518 out: 1519 g_free(pmutils_path); 1520 } 1521 1522 void qmp_guest_suspend_disk(Error **errp) 1523 { 1524 Error *local_err = NULL; 1525 1526 bios_supports_mode("pm-is-supported", "--hibernate", "disk", &local_err); 1527 if (local_err) { 1528 error_propagate(errp, local_err); 1529 return; 1530 } 1531 1532 guest_suspend("pm-hibernate", "disk", errp); 1533 } 1534 1535 void qmp_guest_suspend_ram(Error **errp) 1536 { 1537 Error *local_err = NULL; 1538 1539 bios_supports_mode("pm-is-supported", "--suspend", "mem", &local_err); 1540 if (local_err) { 1541 error_propagate(errp, local_err); 1542 return; 1543 } 1544 1545 guest_suspend("pm-suspend", "mem", errp); 1546 } 1547 1548 void qmp_guest_suspend_hybrid(Error **errp) 1549 { 1550 Error *local_err = NULL; 1551 1552 bios_supports_mode("pm-is-supported", "--suspend-hybrid", NULL, 1553 &local_err); 1554 if (local_err) { 1555 error_propagate(errp, local_err); 1556 return; 1557 } 1558 1559 guest_suspend("pm-suspend-hybrid", NULL, errp); 1560 } 1561 1562 static GuestNetworkInterfaceList * 1563 guest_find_interface(GuestNetworkInterfaceList *head, 1564 const char *name) 1565 { 1566 for (; head; head = head->next) { 1567 if (strcmp(head->value->name, name) == 0) { 1568 break; 1569 } 1570 } 1571 1572 return head; 1573 } 1574 1575 /* 1576 * Build information about guest interfaces 1577 */ 1578 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) 1579 { 1580 GuestNetworkInterfaceList *head = NULL, *cur_item = NULL; 1581 struct ifaddrs *ifap, *ifa; 1582 1583 if (getifaddrs(&ifap) < 0) { 1584 error_setg_errno(errp, errno, "getifaddrs failed"); 1585 goto error; 1586 } 1587 1588 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1589 GuestNetworkInterfaceList *info; 1590 GuestIpAddressList **address_list = NULL, *address_item = NULL; 1591 char addr4[INET_ADDRSTRLEN]; 1592 char addr6[INET6_ADDRSTRLEN]; 1593 int sock; 1594 struct ifreq ifr; 1595 unsigned char *mac_addr; 1596 void *p; 1597 1598 g_debug("Processing %s interface", ifa->ifa_name); 1599 1600 info = guest_find_interface(head, ifa->ifa_name); 1601 1602 if (!info) { 1603 info = g_malloc0(sizeof(*info)); 1604 info->value = g_malloc0(sizeof(*info->value)); 1605 info->value->name = g_strdup(ifa->ifa_name); 1606 1607 if (!cur_item) { 1608 head = cur_item = info; 1609 } else { 1610 cur_item->next = info; 1611 cur_item = info; 1612 } 1613 } 1614 1615 if (!info->value->has_hardware_address && 1616 ifa->ifa_flags & SIOCGIFHWADDR) { 1617 /* we haven't obtained HW address yet */ 1618 sock = socket(PF_INET, SOCK_STREAM, 0); 1619 if (sock == -1) { 1620 error_setg_errno(errp, errno, "failed to create socket"); 1621 goto error; 1622 } 1623 1624 memset(&ifr, 0, sizeof(ifr)); 1625 pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->value->name); 1626 if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { 1627 error_setg_errno(errp, errno, 1628 "failed to get MAC address of %s", 1629 ifa->ifa_name); 1630 close(sock); 1631 goto error; 1632 } 1633 1634 close(sock); 1635 mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data; 1636 1637 info->value->hardware_address = 1638 g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", 1639 (int) mac_addr[0], (int) mac_addr[1], 1640 (int) mac_addr[2], (int) mac_addr[3], 1641 (int) mac_addr[4], (int) mac_addr[5]); 1642 1643 info->value->has_hardware_address = true; 1644 } 1645 1646 if (ifa->ifa_addr && 1647 ifa->ifa_addr->sa_family == AF_INET) { 1648 /* interface with IPv4 address */ 1649 p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; 1650 if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) { 1651 error_setg_errno(errp, errno, "inet_ntop failed"); 1652 goto error; 1653 } 1654 1655 address_item = g_malloc0(sizeof(*address_item)); 1656 address_item->value = g_malloc0(sizeof(*address_item->value)); 1657 address_item->value->ip_address = g_strdup(addr4); 1658 address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4; 1659 1660 if (ifa->ifa_netmask) { 1661 /* Count the number of set bits in netmask. 1662 * This is safe as '1' and '0' cannot be shuffled in netmask. */ 1663 p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr; 1664 address_item->value->prefix = ctpop32(((uint32_t *) p)[0]); 1665 } 1666 } else if (ifa->ifa_addr && 1667 ifa->ifa_addr->sa_family == AF_INET6) { 1668 /* interface with IPv6 address */ 1669 p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; 1670 if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) { 1671 error_setg_errno(errp, errno, "inet_ntop failed"); 1672 goto error; 1673 } 1674 1675 address_item = g_malloc0(sizeof(*address_item)); 1676 address_item->value = g_malloc0(sizeof(*address_item->value)); 1677 address_item->value->ip_address = g_strdup(addr6); 1678 address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6; 1679 1680 if (ifa->ifa_netmask) { 1681 /* Count the number of set bits in netmask. 1682 * This is safe as '1' and '0' cannot be shuffled in netmask. */ 1683 p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr; 1684 address_item->value->prefix = 1685 ctpop32(((uint32_t *) p)[0]) + 1686 ctpop32(((uint32_t *) p)[1]) + 1687 ctpop32(((uint32_t *) p)[2]) + 1688 ctpop32(((uint32_t *) p)[3]); 1689 } 1690 } 1691 1692 if (!address_item) { 1693 continue; 1694 } 1695 1696 address_list = &info->value->ip_addresses; 1697 1698 while (*address_list && (*address_list)->next) { 1699 address_list = &(*address_list)->next; 1700 } 1701 1702 if (!*address_list) { 1703 *address_list = address_item; 1704 } else { 1705 (*address_list)->next = address_item; 1706 } 1707 1708 info->value->has_ip_addresses = true; 1709 1710 1711 } 1712 1713 freeifaddrs(ifap); 1714 return head; 1715 1716 error: 1717 freeifaddrs(ifap); 1718 qapi_free_GuestNetworkInterfaceList(head); 1719 return NULL; 1720 } 1721 1722 #define SYSCONF_EXACT(name, errp) sysconf_exact((name), #name, (errp)) 1723 1724 static long sysconf_exact(int name, const char *name_str, Error **errp) 1725 { 1726 long ret; 1727 1728 errno = 0; 1729 ret = sysconf(name); 1730 if (ret == -1) { 1731 if (errno == 0) { 1732 error_setg(errp, "sysconf(%s): value indefinite", name_str); 1733 } else { 1734 error_setg_errno(errp, errno, "sysconf(%s)", name_str); 1735 } 1736 } 1737 return ret; 1738 } 1739 1740 /* Transfer online/offline status between @vcpu and the guest system. 1741 * 1742 * On input either @errp or *@errp must be NULL. 1743 * 1744 * In system-to-@vcpu direction, the following @vcpu fields are accessed: 1745 * - R: vcpu->logical_id 1746 * - W: vcpu->online 1747 * - W: vcpu->can_offline 1748 * 1749 * In @vcpu-to-system direction, the following @vcpu fields are accessed: 1750 * - R: vcpu->logical_id 1751 * - R: vcpu->online 1752 * 1753 * Written members remain unmodified on error. 1754 */ 1755 static void transfer_vcpu(GuestLogicalProcessor *vcpu, bool sys2vcpu, 1756 Error **errp) 1757 { 1758 char *dirpath; 1759 int dirfd; 1760 1761 dirpath = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/", 1762 vcpu->logical_id); 1763 dirfd = open(dirpath, O_RDONLY | O_DIRECTORY); 1764 if (dirfd == -1) { 1765 error_setg_errno(errp, errno, "open(\"%s\")", dirpath); 1766 } else { 1767 static const char fn[] = "online"; 1768 int fd; 1769 int res; 1770 1771 fd = openat(dirfd, fn, sys2vcpu ? O_RDONLY : O_RDWR); 1772 if (fd == -1) { 1773 if (errno != ENOENT) { 1774 error_setg_errno(errp, errno, "open(\"%s/%s\")", dirpath, fn); 1775 } else if (sys2vcpu) { 1776 vcpu->online = true; 1777 vcpu->can_offline = false; 1778 } else if (!vcpu->online) { 1779 error_setg(errp, "logical processor #%" PRId64 " can't be " 1780 "offlined", vcpu->logical_id); 1781 } /* otherwise pretend successful re-onlining */ 1782 } else { 1783 unsigned char status; 1784 1785 res = pread(fd, &status, 1, 0); 1786 if (res == -1) { 1787 error_setg_errno(errp, errno, "pread(\"%s/%s\")", dirpath, fn); 1788 } else if (res == 0) { 1789 error_setg(errp, "pread(\"%s/%s\"): unexpected EOF", dirpath, 1790 fn); 1791 } else if (sys2vcpu) { 1792 vcpu->online = (status != '0'); 1793 vcpu->can_offline = true; 1794 } else if (vcpu->online != (status != '0')) { 1795 status = '0' + vcpu->online; 1796 if (pwrite(fd, &status, 1, 0) == -1) { 1797 error_setg_errno(errp, errno, "pwrite(\"%s/%s\")", dirpath, 1798 fn); 1799 } 1800 } /* otherwise pretend successful re-(on|off)-lining */ 1801 1802 res = close(fd); 1803 g_assert(res == 0); 1804 } 1805 1806 res = close(dirfd); 1807 g_assert(res == 0); 1808 } 1809 1810 g_free(dirpath); 1811 } 1812 1813 GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) 1814 { 1815 int64_t current; 1816 GuestLogicalProcessorList *head, **link; 1817 long sc_max; 1818 Error *local_err = NULL; 1819 1820 current = 0; 1821 head = NULL; 1822 link = &head; 1823 sc_max = SYSCONF_EXACT(_SC_NPROCESSORS_CONF, &local_err); 1824 1825 while (local_err == NULL && current < sc_max) { 1826 GuestLogicalProcessor *vcpu; 1827 GuestLogicalProcessorList *entry; 1828 1829 vcpu = g_malloc0(sizeof *vcpu); 1830 vcpu->logical_id = current++; 1831 vcpu->has_can_offline = true; /* lolspeak ftw */ 1832 transfer_vcpu(vcpu, true, &local_err); 1833 1834 entry = g_malloc0(sizeof *entry); 1835 entry->value = vcpu; 1836 1837 *link = entry; 1838 link = &entry->next; 1839 } 1840 1841 if (local_err == NULL) { 1842 /* there's no guest with zero VCPUs */ 1843 g_assert(head != NULL); 1844 return head; 1845 } 1846 1847 qapi_free_GuestLogicalProcessorList(head); 1848 error_propagate(errp, local_err); 1849 return NULL; 1850 } 1851 1852 int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) 1853 { 1854 int64_t processed; 1855 Error *local_err = NULL; 1856 1857 processed = 0; 1858 while (vcpus != NULL) { 1859 transfer_vcpu(vcpus->value, false, &local_err); 1860 if (local_err != NULL) { 1861 break; 1862 } 1863 ++processed; 1864 vcpus = vcpus->next; 1865 } 1866 1867 if (local_err != NULL) { 1868 if (processed == 0) { 1869 error_propagate(errp, local_err); 1870 } else { 1871 error_free(local_err); 1872 } 1873 } 1874 1875 return processed; 1876 } 1877 1878 #else /* defined(__linux__) */ 1879 1880 void qmp_guest_suspend_disk(Error **errp) 1881 { 1882 error_set(errp, QERR_UNSUPPORTED); 1883 } 1884 1885 void qmp_guest_suspend_ram(Error **errp) 1886 { 1887 error_set(errp, QERR_UNSUPPORTED); 1888 } 1889 1890 void qmp_guest_suspend_hybrid(Error **errp) 1891 { 1892 error_set(errp, QERR_UNSUPPORTED); 1893 } 1894 1895 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) 1896 { 1897 error_set(errp, QERR_UNSUPPORTED); 1898 return NULL; 1899 } 1900 1901 GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) 1902 { 1903 error_set(errp, QERR_UNSUPPORTED); 1904 return NULL; 1905 } 1906 1907 int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) 1908 { 1909 error_set(errp, QERR_UNSUPPORTED); 1910 return -1; 1911 } 1912 1913 #endif 1914 1915 #if !defined(CONFIG_FSFREEZE) 1916 1917 GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) 1918 { 1919 error_set(errp, QERR_UNSUPPORTED); 1920 return NULL; 1921 } 1922 1923 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp) 1924 { 1925 error_set(errp, QERR_UNSUPPORTED); 1926 1927 return 0; 1928 } 1929 1930 int64_t qmp_guest_fsfreeze_freeze(Error **errp) 1931 { 1932 error_set(errp, QERR_UNSUPPORTED); 1933 1934 return 0; 1935 } 1936 1937 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, 1938 strList *mountpoints, 1939 Error **errp) 1940 { 1941 error_set(errp, QERR_UNSUPPORTED); 1942 1943 return 0; 1944 } 1945 1946 int64_t qmp_guest_fsfreeze_thaw(Error **errp) 1947 { 1948 error_set(errp, QERR_UNSUPPORTED); 1949 1950 return 0; 1951 } 1952 #endif /* CONFIG_FSFREEZE */ 1953 1954 #if !defined(CONFIG_FSTRIM) 1955 void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp) 1956 { 1957 error_set(errp, QERR_UNSUPPORTED); 1958 } 1959 #endif 1960 1961 /* add unsupported commands to the blacklist */ 1962 GList *ga_command_blacklist_init(GList *blacklist) 1963 { 1964 #if !defined(__linux__) 1965 { 1966 const char *list[] = { 1967 "guest-suspend-disk", "guest-suspend-ram", 1968 "guest-suspend-hybrid", "guest-network-get-interfaces", 1969 "guest-get-vcpus", "guest-set-vcpus", NULL}; 1970 char **p = (char **)list; 1971 1972 while (*p) { 1973 blacklist = g_list_append(blacklist, *p++); 1974 } 1975 } 1976 #endif 1977 1978 #if !defined(CONFIG_FSFREEZE) 1979 { 1980 const char *list[] = { 1981 "guest-get-fsinfo", "guest-fsfreeze-status", 1982 "guest-fsfreeze-freeze", "guest-fsfreeze-freeze-list", 1983 "guest-fsfreeze-thaw", "guest-get-fsinfo", NULL}; 1984 char **p = (char **)list; 1985 1986 while (*p) { 1987 blacklist = g_list_append(blacklist, *p++); 1988 } 1989 } 1990 #endif 1991 1992 #if !defined(CONFIG_FSTRIM) 1993 blacklist = g_list_append(blacklist, (char *)"guest-fstrim"); 1994 #endif 1995 1996 return blacklist; 1997 } 1998 1999 /* register init/cleanup routines for stateful command groups */ 2000 void ga_command_state_init(GAState *s, GACommandState *cs) 2001 { 2002 #if defined(CONFIG_FSFREEZE) 2003 ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup); 2004 #endif 2005 ga_command_state_add(cs, guest_file_init, NULL); 2006 } 2007