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