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>
18 #include "qga/guest-agent-core.h"
19 #include "qga-qmp-commands.h"
21 #include "qemu-queue.h"
22 #include "host-utils.h"
24 #ifndef CONFIG_HAS_ENVIRON
25 extern char **environ;
28 #if defined(__linux__)
32 #include <arpa/inet.h>
33 #include <sys/socket.h>
36 #if defined(__linux__) && defined(FIFREEZE)
37 #define CONFIG_FSFREEZE
41 void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
43 const char *shutdown_flag;
47 slog("guest-shutdown called, mode: %s", mode);
48 if (!has_mode || strcmp(mode, "powerdown") == 0) {
50 } else if (strcmp(mode, "halt") == 0) {
52 } else if (strcmp(mode, "reboot") == 0) {
55 error_set(err, QERR_INVALID_PARAMETER_VALUE, "mode",
56 "halt|powerdown|reboot");
62 /* child, start the shutdown */
68 execle("/sbin/shutdown", "shutdown", shutdown_flag, "+0",
69 "hypervisor initiated shutdown", (char*)NULL, environ);
76 rpid = waitpid(pid, &status, 0);
77 } while (rpid == -1 && errno == EINTR);
78 if (rpid == pid && WIFEXITED(status) && !WEXITSTATUS(status)) {
83 error_set(err, QERR_UNDEFINED_ERROR);
86 typedef struct GuestFileHandle {
89 QTAILQ_ENTRY(GuestFileHandle) next;
93 QTAILQ_HEAD(, GuestFileHandle) filehandles;
96 static void guest_file_handle_add(FILE *fh)
100 gfh = g_malloc0(sizeof(GuestFileHandle));
101 gfh->id = fileno(fh);
103 QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
106 static GuestFileHandle *guest_file_handle_find(int64_t id)
108 GuestFileHandle *gfh;
110 QTAILQ_FOREACH(gfh, &guest_file_state.filehandles, next)
120 int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, Error **err)
129 slog("guest-file-open called, filepath: %s, mode: %s", path, mode);
130 fh = fopen(path, mode);
132 error_set(err, QERR_OPEN_FILE_FAILED, path);
136 /* set fd non-blocking to avoid common use cases (like reading from a
137 * named pipe) from hanging the agent
140 ret = fcntl(fd, F_GETFL);
141 ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK);
143 error_set(err, QERR_QGA_COMMAND_FAILED, "fcntl() failed");
148 guest_file_handle_add(fh);
149 slog("guest-file-open, handle: %d", fd);
153 void qmp_guest_file_close(int64_t handle, Error **err)
155 GuestFileHandle *gfh = guest_file_handle_find(handle);
158 slog("guest-file-close called, handle: %ld", handle);
160 error_set(err, QERR_FD_NOT_FOUND, "handle");
164 ret = fclose(gfh->fh);
166 error_set(err, QERR_QGA_COMMAND_FAILED, "fclose() failed");
170 QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next);
174 struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
175 int64_t count, Error **err)
177 GuestFileHandle *gfh = guest_file_handle_find(handle);
178 GuestFileRead *read_data = NULL;
184 error_set(err, QERR_FD_NOT_FOUND, "handle");
189 count = QGA_READ_COUNT_DEFAULT;
190 } else if (count < 0) {
191 error_set(err, QERR_INVALID_PARAMETER, "count");
196 buf = g_malloc0(count+1);
197 read_count = fread(buf, 1, count, fh);
199 slog("guest-file-read failed, handle: %ld", handle);
200 error_set(err, QERR_QGA_COMMAND_FAILED, "fread() failed");
203 read_data = g_malloc0(sizeof(GuestFileRead));
204 read_data->count = read_count;
205 read_data->eof = feof(fh);
207 read_data->buf_b64 = g_base64_encode(buf, read_count);
216 GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
217 bool has_count, int64_t count, Error **err)
219 GuestFileWrite *write_data = NULL;
223 GuestFileHandle *gfh = guest_file_handle_find(handle);
227 error_set(err, QERR_FD_NOT_FOUND, "handle");
232 buf = g_base64_decode(buf_b64, &buf_len);
236 } else if (count < 0 || count > buf_len) {
238 error_set(err, QERR_INVALID_PARAMETER, "count");
242 write_count = fwrite(buf, 1, count, fh);
244 slog("guest-file-write failed, handle: %ld", handle);
245 error_set(err, QERR_QGA_COMMAND_FAILED, "fwrite() error");
247 write_data = g_malloc0(sizeof(GuestFileWrite));
248 write_data->count = write_count;
249 write_data->eof = feof(fh);
257 struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
258 int64_t whence, Error **err)
260 GuestFileHandle *gfh = guest_file_handle_find(handle);
261 GuestFileSeek *seek_data = NULL;
266 error_set(err, QERR_FD_NOT_FOUND, "handle");
271 ret = fseek(fh, offset, whence);
273 error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno));
275 seek_data = g_malloc0(sizeof(GuestFileRead));
276 seek_data->position = ftell(fh);
277 seek_data->eof = feof(fh);
284 void qmp_guest_file_flush(int64_t handle, Error **err)
286 GuestFileHandle *gfh = guest_file_handle_find(handle);
291 error_set(err, QERR_FD_NOT_FOUND, "handle");
298 error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno));
302 static void guest_file_init(void)
304 QTAILQ_INIT(&guest_file_state.filehandles);
307 /* linux-specific implementations. avoid this if at all possible. */
308 #if defined(__linux__)
310 #if defined(CONFIG_FSFREEZE)
312 typedef struct GuestFsfreezeMount {
315 QTAILQ_ENTRY(GuestFsfreezeMount) next;
316 } GuestFsfreezeMount;
318 typedef QTAILQ_HEAD(, GuestFsfreezeMount) GuestFsfreezeMountList;
320 static void guest_fsfreeze_free_mount_list(GuestFsfreezeMountList *mounts)
322 GuestFsfreezeMount *mount, *temp;
328 QTAILQ_FOREACH_SAFE(mount, mounts, next, temp) {
329 QTAILQ_REMOVE(mounts, mount, next);
330 g_free(mount->dirname);
331 g_free(mount->devtype);
337 * Walk the mount table and build a list of local file systems
339 static int guest_fsfreeze_build_mount_list(GuestFsfreezeMountList *mounts)
342 GuestFsfreezeMount *mount;
343 char const *mtab = MOUNTED;
346 fp = setmntent(mtab, "r");
348 g_warning("fsfreeze: unable to read mtab");
352 while ((ment = getmntent(fp))) {
354 * An entry which device name doesn't start with a '/' is
355 * either a dummy file system or a network file system.
356 * Add special handling for smbfs and cifs as is done by
359 if ((ment->mnt_fsname[0] != '/') ||
360 (strcmp(ment->mnt_type, "smbfs") == 0) ||
361 (strcmp(ment->mnt_type, "cifs") == 0)) {
365 mount = g_malloc0(sizeof(GuestFsfreezeMount));
366 mount->dirname = g_strdup(ment->mnt_dir);
367 mount->devtype = g_strdup(ment->mnt_type);
369 QTAILQ_INSERT_TAIL(mounts, mount, next);
378 * Return status of freeze/thaw
380 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
382 if (ga_is_frozen(ga_state)) {
383 return GUEST_FSFREEZE_STATUS_FROZEN;
386 return GUEST_FSFREEZE_STATUS_THAWED;
390 * Walk list of mounted file systems in the guest, and freeze the ones which
391 * are real local file systems.
393 int64_t qmp_guest_fsfreeze_freeze(Error **err)
396 GuestFsfreezeMountList mounts;
397 struct GuestFsfreezeMount *mount;
401 slog("guest-fsfreeze called");
403 QTAILQ_INIT(&mounts);
404 ret = guest_fsfreeze_build_mount_list(&mounts);
409 /* cannot risk guest agent blocking itself on a write in this state */
410 ga_set_frozen(ga_state);
412 QTAILQ_FOREACH(mount, &mounts, next) {
413 fd = qemu_open(mount->dirname, O_RDONLY);
415 sprintf(err_msg, "failed to open %s, %s", mount->dirname,
417 error_set(err, QERR_QGA_COMMAND_FAILED, err_msg);
421 /* we try to cull filesytems we know won't work in advance, but other
422 * filesytems may not implement fsfreeze for less obvious reasons.
423 * these will report EOPNOTSUPP. we simply ignore these when tallying
424 * the number of frozen filesystems.
426 * any other error means a failure to freeze a filesystem we
427 * expect to be freezable, so return an error in those cases
428 * and return system to thawed state.
430 ret = ioctl(fd, FIFREEZE);
432 if (errno != EOPNOTSUPP) {
433 sprintf(err_msg, "failed to freeze %s, %s",
434 mount->dirname, strerror(errno));
435 error_set(err, QERR_QGA_COMMAND_FAILED, err_msg);
445 guest_fsfreeze_free_mount_list(&mounts);
449 guest_fsfreeze_free_mount_list(&mounts);
450 qmp_guest_fsfreeze_thaw(NULL);
455 * Walk list of frozen file systems in the guest, and thaw them.
457 int64_t qmp_guest_fsfreeze_thaw(Error **err)
460 GuestFsfreezeMountList mounts;
461 GuestFsfreezeMount *mount;
462 int fd, i = 0, logged;
464 QTAILQ_INIT(&mounts);
465 ret = guest_fsfreeze_build_mount_list(&mounts);
467 error_set(err, QERR_QGA_COMMAND_FAILED,
468 "failed to enumerate filesystems");
472 QTAILQ_FOREACH(mount, &mounts, next) {
474 fd = qemu_open(mount->dirname, O_RDONLY);
478 /* we have no way of knowing whether a filesystem was actually unfrozen
479 * as a result of a successful call to FITHAW, only that if an error
480 * was returned the filesystem was *not* unfrozen by that particular
483 * since multiple preceding FIFREEZEs require multiple calls to FITHAW
484 * to unfreeze, continuing issuing FITHAW until an error is returned,
485 * in which case either the filesystem is in an unfreezable state, or,
486 * more likely, it was thawed previously (and remains so afterward).
488 * also, since the most recent successful call is the one that did
489 * the actual unfreeze, we can use this to provide an accurate count
490 * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which
491 * may * be useful for determining whether a filesystem was unfrozen
492 * during the freeze/thaw phase by a process other than qemu-ga.
495 ret = ioctl(fd, FITHAW);
496 if (ret == 0 && !logged) {
504 ga_unset_frozen(ga_state);
505 guest_fsfreeze_free_mount_list(&mounts);
509 static void guest_fsfreeze_cleanup(void)
514 if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) {
515 ret = qmp_guest_fsfreeze_thaw(&err);
516 if (ret < 0 || err) {
517 slog("failed to clean up frozen filesystems");
521 #endif /* CONFIG_FSFREEZE */
523 #define LINUX_SYS_STATE_FILE "/sys/power/state"
524 #define SUSPEND_SUPPORTED 0
525 #define SUSPEND_NOT_SUPPORTED 1
527 static void bios_supports_mode(const char *pmutils_bin, const char *pmutils_arg,
528 const char *sysfile_str, Error **err)
534 pmutils_path = g_find_program_in_path(pmutils_bin);
538 char buf[32]; /* hopefully big enough */
543 reopen_fd_to_null(0);
544 reopen_fd_to_null(1);
545 reopen_fd_to_null(2);
548 execle(pmutils_path, pmutils_bin, pmutils_arg, NULL, environ);
552 * If we get here either pm-utils is not installed or execle() has
553 * failed. Let's try the manual method if the caller wants it.
557 _exit(SUSPEND_NOT_SUPPORTED);
560 fd = open(LINUX_SYS_STATE_FILE, O_RDONLY);
562 _exit(SUSPEND_NOT_SUPPORTED);
565 ret = read(fd, buf, sizeof(buf)-1);
567 _exit(SUSPEND_NOT_SUPPORTED);
571 if (strstr(buf, sysfile_str)) {
572 _exit(SUSPEND_SUPPORTED);
575 _exit(SUSPEND_NOT_SUPPORTED);
578 g_free(pmutils_path);
585 rpid = waitpid(pid, &status, 0);
586 } while (rpid == -1 && errno == EINTR);
587 if (rpid == pid && WIFEXITED(status)) {
588 switch (WEXITSTATUS(status)) {
589 case SUSPEND_SUPPORTED:
591 case SUSPEND_NOT_SUPPORTED:
592 error_set(err, QERR_UNSUPPORTED);
600 error_set(err, QERR_UNDEFINED_ERROR);
603 static void guest_suspend(const char *pmutils_bin, const char *sysfile_str,
610 pmutils_path = g_find_program_in_path(pmutils_bin);
618 reopen_fd_to_null(0);
619 reopen_fd_to_null(1);
620 reopen_fd_to_null(2);
623 execle(pmutils_path, pmutils_bin, NULL, environ);
627 * If we get here either pm-utils is not installed or execle() has
628 * failed. Let's try the manual method if the caller wants it.
635 fd = open(LINUX_SYS_STATE_FILE, O_WRONLY);
640 if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) {
647 g_free(pmutils_path);
654 rpid = waitpid(pid, &status, 0);
655 } while (rpid == -1 && errno == EINTR);
656 if (rpid == pid && WIFEXITED(status) && !WEXITSTATUS(status)) {
661 error_set(err, QERR_UNDEFINED_ERROR);
664 void qmp_guest_suspend_disk(Error **err)
666 bios_supports_mode("pm-is-supported", "--hibernate", "disk", err);
667 if (error_is_set(err)) {
671 guest_suspend("pm-hibernate", "disk", err);
674 void qmp_guest_suspend_ram(Error **err)
676 bios_supports_mode("pm-is-supported", "--suspend", "mem", err);
677 if (error_is_set(err)) {
681 guest_suspend("pm-suspend", "mem", err);
684 void qmp_guest_suspend_hybrid(Error **err)
686 bios_supports_mode("pm-is-supported", "--suspend-hybrid", NULL, err);
687 if (error_is_set(err)) {
691 guest_suspend("pm-suspend-hybrid", NULL, err);
694 static GuestNetworkInterfaceList *
695 guest_find_interface(GuestNetworkInterfaceList *head,
698 for (; head; head = head->next) {
699 if (strcmp(head->value->name, name) == 0) {
708 * Build information about guest interfaces
710 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
712 GuestNetworkInterfaceList *head = NULL, *cur_item = NULL;
713 struct ifaddrs *ifap, *ifa;
716 if (getifaddrs(&ifap) < 0) {
717 snprintf(err_msg, sizeof(err_msg),
718 "getifaddrs failed: %s", strerror(errno));
719 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
723 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
724 GuestNetworkInterfaceList *info;
725 GuestIpAddressList **address_list = NULL, *address_item = NULL;
726 char addr4[INET_ADDRSTRLEN];
727 char addr6[INET6_ADDRSTRLEN];
730 unsigned char *mac_addr;
733 g_debug("Processing %s interface", ifa->ifa_name);
735 info = guest_find_interface(head, ifa->ifa_name);
738 info = g_malloc0(sizeof(*info));
739 info->value = g_malloc0(sizeof(*info->value));
740 info->value->name = g_strdup(ifa->ifa_name);
743 head = cur_item = info;
745 cur_item->next = info;
750 if (!info->value->has_hardware_address &&
751 ifa->ifa_flags & SIOCGIFHWADDR) {
752 /* we haven't obtained HW address yet */
753 sock = socket(PF_INET, SOCK_STREAM, 0);
755 snprintf(err_msg, sizeof(err_msg),
756 "failed to create socket: %s", strerror(errno));
757 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
761 memset(&ifr, 0, sizeof(ifr));
762 strncpy(ifr.ifr_name, info->value->name, IF_NAMESIZE);
763 if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
764 snprintf(err_msg, sizeof(err_msg),
765 "failed to get MAC address of %s: %s",
768 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
772 mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
774 if (asprintf(&info->value->hardware_address,
775 "%02x:%02x:%02x:%02x:%02x:%02x",
776 (int) mac_addr[0], (int) mac_addr[1],
777 (int) mac_addr[2], (int) mac_addr[3],
778 (int) mac_addr[4], (int) mac_addr[5]) == -1) {
779 snprintf(err_msg, sizeof(err_msg),
780 "failed to format MAC: %s", strerror(errno));
781 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
785 info->value->has_hardware_address = true;
790 ifa->ifa_addr->sa_family == AF_INET) {
791 /* interface with IPv4 address */
792 address_item = g_malloc0(sizeof(*address_item));
793 address_item->value = g_malloc0(sizeof(*address_item->value));
794 p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
795 if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) {
796 snprintf(err_msg, sizeof(err_msg),
797 "inet_ntop failed : %s", strerror(errno));
798 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
802 address_item->value->ip_address = g_strdup(addr4);
803 address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4;
805 if (ifa->ifa_netmask) {
806 /* Count the number of set bits in netmask.
807 * This is safe as '1' and '0' cannot be shuffled in netmask. */
808 p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
809 address_item->value->prefix = ctpop32(((uint32_t *) p)[0]);
811 } else if (ifa->ifa_addr &&
812 ifa->ifa_addr->sa_family == AF_INET6) {
813 /* interface with IPv6 address */
814 address_item = g_malloc0(sizeof(*address_item));
815 address_item->value = g_malloc0(sizeof(*address_item->value));
816 p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
817 if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) {
818 snprintf(err_msg, sizeof(err_msg),
819 "inet_ntop failed : %s", strerror(errno));
820 error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg);
824 address_item->value->ip_address = g_strdup(addr6);
825 address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6;
827 if (ifa->ifa_netmask) {
828 /* Count the number of set bits in netmask.
829 * This is safe as '1' and '0' cannot be shuffled in netmask. */
830 p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr;
831 address_item->value->prefix =
832 ctpop32(((uint32_t *) p)[0]) +
833 ctpop32(((uint32_t *) p)[1]) +
834 ctpop32(((uint32_t *) p)[2]) +
835 ctpop32(((uint32_t *) p)[3]);
843 address_list = &info->value->ip_addresses;
845 while (*address_list && (*address_list)->next) {
846 address_list = &(*address_list)->next;
849 if (!*address_list) {
850 *address_list = address_item;
852 (*address_list)->next = address_item;
855 info->value->has_ip_addresses = true;
865 qapi_free_GuestNetworkInterfaceList(head);
869 #else /* defined(__linux__) */
871 void qmp_guest_suspend_disk(Error **err)
873 error_set(err, QERR_UNSUPPORTED);
876 void qmp_guest_suspend_ram(Error **err)
878 error_set(err, QERR_UNSUPPORTED);
881 void qmp_guest_suspend_hybrid(Error **err)
883 error_set(err, QERR_UNSUPPORTED);
886 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
888 error_set(errp, QERR_UNSUPPORTED);
894 #if !defined(CONFIG_FSFREEZE)
896 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
898 error_set(err, QERR_UNSUPPORTED);
903 int64_t qmp_guest_fsfreeze_freeze(Error **err)
905 error_set(err, QERR_UNSUPPORTED);
910 int64_t qmp_guest_fsfreeze_thaw(Error **err)
912 error_set(err, QERR_UNSUPPORTED);
919 /* register init/cleanup routines for stateful command groups */
920 void ga_command_state_init(GAState *s, GACommandState *cs)
922 #if defined(CONFIG_FSFREEZE)
923 ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup);
925 ga_command_state_add(cs, guest_file_init, NULL);