2 * QEMU Guest Agent POSIX-specific command implementations
4 * Copyright IBM Corp. 2011
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.
15 #include <sys/types.h>
16 #include <sys/ioctl.h>
17 #include "qga/guest-agent-core.h"
18 #include "qga-qmp-commands.h"
20 #include "qemu-queue.h"
21 #include "host-utils.h"
23 #if defined(__linux__)
27 #include <arpa/inet.h>
28 #include <sys/socket.h>
32 #if defined(__linux__) && defined(FIFREEZE)
33 #define CONFIG_FSFREEZE
37 #if defined(__linux__)
38 /* TODO: use this in place of all post-fork() fclose(std*) callers */
39 static void reopen_fd_to_null(int fd)
43 nullfd = open("/dev/null", O_RDWR);
54 #endif /* defined(__linux__) */
56 void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
59 const char *shutdown_flag;
61 slog("guest-shutdown called, mode: %s", mode);
62 if (!has_mode || strcmp(mode, "powerdown") == 0) {
64 } else if (strcmp(mode, "halt") == 0) {
66 } else if (strcmp(mode, "reboot") == 0) {
69 error_set(err, QERR_INVALID_PARAMETER_VALUE, "mode",
70 "halt|powerdown|reboot");
76 /* child, start the shutdown */
82 ret = execl("/sbin/shutdown", "shutdown", shutdown_flag, "+0",
83 "hypervisor initiated shutdown", (char*)NULL);
85 slog("guest-shutdown failed: %s", strerror(errno));
89 error_set(err, QERR_UNDEFINED_ERROR);
93 typedef struct GuestFileHandle {
96 QTAILQ_ENTRY(GuestFileHandle) next;
100 QTAILQ_HEAD(, GuestFileHandle) filehandles;
103 static void guest_file_handle_add(FILE *fh)
105 GuestFileHandle *gfh;
107 gfh = g_malloc0(sizeof(GuestFileHandle));
108 gfh->id = fileno(fh);
110 QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
113 static GuestFileHandle *guest_file_handle_find(int64_t id)
115 GuestFileHandle *gfh;
117 QTAILQ_FOREACH(gfh, &guest_file_state.filehandles, next)
127 int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, Error **err)
136 slog("guest-file-open called, filepath: %s, mode: %s", path, mode);
137 fh = fopen(path, mode);
139 error_set(err, QERR_OPEN_FILE_FAILED, path);
143 /* set fd non-blocking to avoid common use cases (like reading from a
144 * named pipe) from hanging the agent
147 ret = fcntl(fd, F_GETFL);
148 ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK);
150 error_set(err, QERR_QGA_COMMAND_FAILED, "fcntl() failed");
155 guest_file_handle_add(fh);
156 slog("guest-file-open, handle: %d", fd);
160 void qmp_guest_file_close(int64_t handle, Error **err)
162 GuestFileHandle *gfh = guest_file_handle_find(handle);
165 slog("guest-file-close called, handle: %ld", handle);
167 error_set(err, QERR_FD_NOT_FOUND, "handle");
171 ret = fclose(gfh->fh);
173 error_set(err, QERR_QGA_COMMAND_FAILED, "fclose() failed");
177 QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next);
181 struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
182 int64_t count, Error **err)
184 GuestFileHandle *gfh = guest_file_handle_find(handle);
185 GuestFileRead *read_data = NULL;
191 error_set(err, QERR_FD_NOT_FOUND, "handle");
196 count = QGA_READ_COUNT_DEFAULT;
197 } else if (count < 0) {
198 error_set(err, QERR_INVALID_PARAMETER, "count");
203 buf = g_malloc0(count+1);
204 read_count = fread(buf, 1, count, fh);
206 slog("guest-file-read failed, handle: %ld", handle);
207 error_set(err, QERR_QGA_COMMAND_FAILED, "fread() failed");
210 read_data = g_malloc0(sizeof(GuestFileRead));
211 read_data->count = read_count;
212 read_data->eof = feof(fh);
214 read_data->buf_b64 = g_base64_encode(buf, read_count);
223 GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
224 bool has_count, int64_t count, Error **err)
226 GuestFileWrite *write_data = NULL;
230 GuestFileHandle *gfh = guest_file_handle_find(handle);
234 error_set(err, QERR_FD_NOT_FOUND, "handle");
239 buf = g_base64_decode(buf_b64, &buf_len);
243 } else if (count < 0 || count > buf_len) {
245 error_set(err, QERR_INVALID_PARAMETER, "count");
249 write_count = fwrite(buf, 1, count, fh);
251 slog("guest-file-write failed, handle: %ld", handle);
252 error_set(err, QERR_QGA_COMMAND_FAILED, "fwrite() error");
254 write_data = g_malloc0(sizeof(GuestFileWrite));
255 write_data->count = write_count;
256 write_data->eof = feof(fh);
264 struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
265 int64_t whence, Error **err)
267 GuestFileHandle *gfh = guest_file_handle_find(handle);
268 GuestFileSeek *seek_data = NULL;
273 error_set(err, QERR_FD_NOT_FOUND, "handle");
278 ret = fseek(fh, offset, whence);
280 error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno));
282 seek_data = g_malloc0(sizeof(GuestFileRead));
283 seek_data->position = ftell(fh);
284 seek_data->eof = feof(fh);
291 void qmp_guest_file_flush(int64_t handle, Error **err)
293 GuestFileHandle *gfh = guest_file_handle_find(handle);
298 error_set(err, QERR_FD_NOT_FOUND, "handle");
305 error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno));
309 static void guest_file_init(void)
311 QTAILQ_INIT(&guest_file_state.filehandles);
314 /* linux-specific implementations. avoid this if at all possible. */
315 #if defined(__linux__)
317 #if defined(CONFIG_FSFREEZE)
319 typedef struct GuestFsfreezeMount {
322 QTAILQ_ENTRY(GuestFsfreezeMount) next;
323 } GuestFsfreezeMount;
325 typedef QTAILQ_HEAD(, GuestFsfreezeMount) GuestFsfreezeMountList;
327 static void guest_fsfreeze_free_mount_list(GuestFsfreezeMountList *mounts)
329 GuestFsfreezeMount *mount, *temp;
335 QTAILQ_FOREACH_SAFE(mount, mounts, next, temp) {
336 QTAILQ_REMOVE(mounts, mount, next);
337 g_free(mount->dirname);
338 g_free(mount->devtype);
344 * Walk the mount table and build a list of local file systems
346 static int guest_fsfreeze_build_mount_list(GuestFsfreezeMountList *mounts)
349 GuestFsfreezeMount *mount;
350 char const *mtab = MOUNTED;
353 fp = setmntent(mtab, "r");
355 g_warning("fsfreeze: unable to read mtab");
359 while ((ment = getmntent(fp))) {
361 * An entry which device name doesn't start with a '/' is
362 * either a dummy file system or a network file system.
363 * Add special handling for smbfs and cifs as is done by
366 if ((ment->mnt_fsname[0] != '/') ||
367 (strcmp(ment->mnt_type, "smbfs") == 0) ||
368 (strcmp(ment->mnt_type, "cifs") == 0)) {
372 mount = g_malloc0(sizeof(GuestFsfreezeMount));
373 mount->dirname = g_strdup(ment->mnt_dir);
374 mount->devtype = g_strdup(ment->mnt_type);
376 QTAILQ_INSERT_TAIL(mounts, mount, next);
385 * Return status of freeze/thaw
387 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
389 if (ga_is_frozen(ga_state)) {
390 return GUEST_FSFREEZE_STATUS_FROZEN;
393 return GUEST_FSFREEZE_STATUS_THAWED;
397 * Walk list of mounted file systems in the guest, and freeze the ones which
398 * are real local file systems.
400 int64_t qmp_guest_fsfreeze_freeze(Error **err)
403 GuestFsfreezeMountList mounts;
404 struct GuestFsfreezeMount *mount;
408 slog("guest-fsfreeze called");
410 QTAILQ_INIT(&mounts);
411 ret = guest_fsfreeze_build_mount_list(&mounts);
416 /* cannot risk guest agent blocking itself on a write in this state */
417 ga_set_frozen(ga_state);
419 QTAILQ_FOREACH(mount, &mounts, next) {
420 fd = qemu_open(mount->dirname, O_RDONLY);
422 sprintf(err_msg, "failed to open %s, %s", mount->dirname,
424 error_set(err, QERR_QGA_COMMAND_FAILED, err_msg);
428 /* we try to cull filesytems we know won't work in advance, but other
429 * filesytems may not implement fsfreeze for less obvious reasons.
430 * these will report EOPNOTSUPP. we simply ignore these when tallying
431 * the number of frozen filesystems.
433 * any other error means a failure to freeze a filesystem we
434 * expect to be freezable, so return an error in those cases
435 * and return system to thawed state.
437 ret = ioctl(fd, FIFREEZE);
439 if (errno != EOPNOTSUPP) {
440 sprintf(err_msg, "failed to freeze %s, %s",
441 mount->dirname, strerror(errno));
442 error_set(err, QERR_QGA_COMMAND_FAILED, err_msg);
452 guest_fsfreeze_free_mount_list(&mounts);
456 guest_fsfreeze_free_mount_list(&mounts);
457 qmp_guest_fsfreeze_thaw(NULL);
462 * Walk list of frozen file systems in the guest, and thaw them.
464 int64_t qmp_guest_fsfreeze_thaw(Error **err)
467 GuestFsfreezeMountList mounts;
468 GuestFsfreezeMount *mount;
469 int fd, i = 0, logged;
471 QTAILQ_INIT(&mounts);
472 ret = guest_fsfreeze_build_mount_list(&mounts);
474 error_set(err, QERR_QGA_COMMAND_FAILED,
475 "failed to enumerate filesystems");
479 QTAILQ_FOREACH(mount, &mounts, next) {
481 fd = qemu_open(mount->dirname, O_RDONLY);
485 /* we have no way of knowing whether a filesystem was actually unfrozen
486 * as a result of a successful call to FITHAW, only that if an error
487 * was returned the filesystem was *not* unfrozen by that particular
490 * since multiple preceding FIFREEZEs require multiple calls to FITHAW
491 * to unfreeze, continuing issuing FITHAW until an error is returned,
492 * in which case either the filesystem is in an unfreezable state, or,
493 * more likely, it was thawed previously (and remains so afterward).
495 * also, since the most recent successful call is the one that did
496 * the actual unfreeze, we can use this to provide an accurate count
497 * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which
498 * may * be useful for determining whether a filesystem was unfrozen
499 * during the freeze/thaw phase by a process other than qemu-ga.
502 ret = ioctl(fd, FITHAW);
503 if (ret == 0 && !logged) {
511 ga_unset_frozen(ga_state);
512 guest_fsfreeze_free_mount_list(&mounts);
516 static void guest_fsfreeze_cleanup(void)
521 if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) {
522 ret = qmp_guest_fsfreeze_thaw(&err);
523 if (ret < 0 || err) {
524 slog("failed to clean up frozen filesystems");
528 #endif /* CONFIG_FSFREEZE */
530 #define LINUX_SYS_STATE_FILE "/sys/power/state"
531 #define SUSPEND_SUPPORTED 0
532 #define SUSPEND_NOT_SUPPORTED 1
535 * This function forks twice and the information about the mode support
536 * status is passed to the qemu-ga process via a pipe.
538 * This approach allows us to keep the way we reap terminated children
539 * in qemu-ga quite simple.
541 static void bios_supports_mode(const char *pmutils_bin, const char *pmutils_arg,
542 const char *sysfile_str, Error **err)
547 int status, pipefds[2];
549 if (pipe(pipefds) < 0) {
550 error_set(err, QERR_UNDEFINED_ERROR);
554 pmutils_path = g_find_program_in_path(pmutils_bin);
558 struct sigaction act;
560 memset(&act, 0, sizeof(act));
561 act.sa_handler = SIG_DFL;
562 sigaction(SIGCHLD, &act, NULL);
566 reopen_fd_to_null(0);
567 reopen_fd_to_null(1);
568 reopen_fd_to_null(2);
573 char buf[32]; /* hopefully big enough */
576 execle(pmutils_path, pmutils_bin, pmutils_arg, NULL, environ);
580 * If we get here either pm-utils is not installed or execle() has
581 * failed. Let's try the manual method if the caller wants it.
585 _exit(SUSPEND_NOT_SUPPORTED);
588 fd = open(LINUX_SYS_STATE_FILE, O_RDONLY);
590 _exit(SUSPEND_NOT_SUPPORTED);
593 ret = read(fd, buf, sizeof(buf)-1);
595 _exit(SUSPEND_NOT_SUPPORTED);
599 if (strstr(buf, sysfile_str)) {
600 _exit(SUSPEND_SUPPORTED);
603 _exit(SUSPEND_NOT_SUPPORTED);
609 status = SUSPEND_NOT_SUPPORTED;
612 ret = write(pipefds[1], &status, sizeof(status));
613 if (ret != sizeof(status)) {
621 g_free(pmutils_path);
624 error_set(err, QERR_UNDEFINED_ERROR);
628 ret = read(pipefds[0], &status, sizeof(status));
629 if (ret == sizeof(status) && WIFEXITED(status) &&
630 WEXITSTATUS(status) == SUSPEND_SUPPORTED) {
634 error_set(err, QERR_UNSUPPORTED);
640 static void guest_suspend(const char *pmutils_bin, const char *sysfile_str,
646 pmutils_path = g_find_program_in_path(pmutils_bin);
654 reopen_fd_to_null(0);
655 reopen_fd_to_null(1);
656 reopen_fd_to_null(2);
659 execle(pmutils_path, pmutils_bin, NULL, environ);
663 * If we get here either pm-utils is not installed or execle() has
664 * failed. Let's try the manual method if the caller wants it.
671 fd = open(LINUX_SYS_STATE_FILE, O_WRONLY);
676 if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) {
683 g_free(pmutils_path);
686 error_set(err, QERR_UNDEFINED_ERROR);
691 void qmp_guest_suspend_disk(Error **err)
693 bios_supports_mode("pm-is-supported", "--hibernate", "disk", err);
694 if (error_is_set(err)) {
698 guest_suspend("pm-hibernate", "disk", err);
701 void qmp_guest_suspend_ram(Error **err)
703 bios_supports_mode("pm-is-supported", "--suspend", "mem", err);
704 if (error_is_set(err)) {
708 guest_suspend("pm-suspend", "mem", err);
711 void qmp_guest_suspend_hybrid(Error **err)
713 bios_supports_mode("pm-is-supported", "--suspend-hybrid", NULL, err);
714 if (error_is_set(err)) {
718 guest_suspend("pm-suspend-hybrid", NULL, err);
721 static GuestNetworkInterfaceList *
722 guest_find_interface(GuestNetworkInterfaceList *head,
725 for (; head; head = head->next) {
726 if (strcmp(head->value->name, name) == 0) {
735 * Build information about guest interfaces
737 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
739 GuestNetworkInterfaceList *head = NULL, *cur_item = NULL;
740 struct ifaddrs *ifap, *ifa;
743 if (getifaddrs(&ifap) < 0) {
744 snprintf(err_msg, sizeof(err_msg),
745 "getifaddrs failed: %s", strerror(errno));
746 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
750 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
751 GuestNetworkInterfaceList *info;
752 GuestIpAddressList **address_list = NULL, *address_item = NULL;
753 char addr4[INET_ADDRSTRLEN];
754 char addr6[INET6_ADDRSTRLEN];
757 unsigned char *mac_addr;
760 g_debug("Processing %s interface", ifa->ifa_name);
762 info = guest_find_interface(head, ifa->ifa_name);
765 info = g_malloc0(sizeof(*info));
766 info->value = g_malloc0(sizeof(*info->value));
767 info->value->name = g_strdup(ifa->ifa_name);
770 head = cur_item = info;
772 cur_item->next = info;
777 if (!info->value->has_hardware_address &&
778 ifa->ifa_flags & SIOCGIFHWADDR) {
779 /* we haven't obtained HW address yet */
780 sock = socket(PF_INET, SOCK_STREAM, 0);
782 snprintf(err_msg, sizeof(err_msg),
783 "failed to create socket: %s", strerror(errno));
784 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
788 memset(&ifr, 0, sizeof(ifr));
789 strncpy(ifr.ifr_name, info->value->name, IF_NAMESIZE);
790 if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
791 snprintf(err_msg, sizeof(err_msg),
792 "failed to get MAC address of %s: %s",
795 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
799 mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
801 if (asprintf(&info->value->hardware_address,
802 "%02x:%02x:%02x:%02x:%02x:%02x",
803 (int) mac_addr[0], (int) mac_addr[1],
804 (int) mac_addr[2], (int) mac_addr[3],
805 (int) mac_addr[4], (int) mac_addr[5]) == -1) {
806 snprintf(err_msg, sizeof(err_msg),
807 "failed to format MAC: %s", strerror(errno));
808 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
812 info->value->has_hardware_address = true;
817 ifa->ifa_addr->sa_family == AF_INET) {
818 /* interface with IPv4 address */
819 address_item = g_malloc0(sizeof(*address_item));
820 address_item->value = g_malloc0(sizeof(*address_item->value));
821 p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
822 if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) {
823 snprintf(err_msg, sizeof(err_msg),
824 "inet_ntop failed : %s", strerror(errno));
825 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
829 address_item->value->ip_address = g_strdup(addr4);
830 address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4;
832 if (ifa->ifa_netmask) {
833 /* Count the number of set bits in netmask.
834 * This is safe as '1' and '0' cannot be shuffled in netmask. */
835 p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
836 address_item->value->prefix = ctpop32(((uint32_t *) p)[0]);
838 } else if (ifa->ifa_addr &&
839 ifa->ifa_addr->sa_family == AF_INET6) {
840 /* interface with IPv6 address */
841 address_item = g_malloc0(sizeof(*address_item));
842 address_item->value = g_malloc0(sizeof(*address_item->value));
843 p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
844 if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) {
845 snprintf(err_msg, sizeof(err_msg),
846 "inet_ntop failed : %s", strerror(errno));
847 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
851 address_item->value->ip_address = g_strdup(addr6);
852 address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6;
854 if (ifa->ifa_netmask) {
855 /* Count the number of set bits in netmask.
856 * This is safe as '1' and '0' cannot be shuffled in netmask. */
857 p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr;
858 address_item->value->prefix =
859 ctpop32(((uint32_t *) p)[0]) +
860 ctpop32(((uint32_t *) p)[1]) +
861 ctpop32(((uint32_t *) p)[2]) +
862 ctpop32(((uint32_t *) p)[3]);
870 address_list = &info->value->ip_addresses;
872 while (*address_list && (*address_list)->next) {
873 address_list = &(*address_list)->next;
876 if (!*address_list) {
877 *address_list = address_item;
879 (*address_list)->next = address_item;
882 info->value->has_ip_addresses = true;
892 qapi_free_GuestNetworkInterfaceList(head);
896 #else /* defined(__linux__) */
898 void qmp_guest_suspend_disk(Error **err)
900 error_set(err, QERR_UNSUPPORTED);
903 void qmp_guest_suspend_ram(Error **err)
905 error_set(err, QERR_UNSUPPORTED);
908 void qmp_guest_suspend_hybrid(Error **err)
910 error_set(err, QERR_UNSUPPORTED);
913 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
915 error_set(errp, QERR_UNSUPPORTED);
921 #if !defined(CONFIG_FSFREEZE)
923 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
925 error_set(err, QERR_UNSUPPORTED);
930 int64_t qmp_guest_fsfreeze_freeze(Error **err)
932 error_set(err, QERR_UNSUPPORTED);
937 int64_t qmp_guest_fsfreeze_thaw(Error **err)
939 error_set(err, QERR_UNSUPPORTED);
946 /* register init/cleanup routines for stateful command groups */
947 void ga_command_state_init(GAState *s, GACommandState *cs)
949 #if defined(CONFIG_FSFREEZE)
950 ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup);
952 ga_command_state_add(cs, guest_file_init, NULL);