2 * QEMU Guest Agent POSIX-specific command implementations
4 * Copyright IBM Corp. 2011
7 * Michael Roth <mdroth@linux.vnet.ibm.com>
8 * Michal Privoznik <mprivozn@redhat.com>
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 void qmp_guest_shutdown(bool has_mode
, const char *mode
, Error
**err
)
39 const char *shutdown_flag
;
43 slog("guest-shutdown called, mode: %s", mode
);
44 if (!has_mode
|| strcmp(mode
, "powerdown") == 0) {
46 } else if (strcmp(mode
, "halt") == 0) {
48 } else if (strcmp(mode
, "reboot") == 0) {
51 error_set(err
, QERR_INVALID_PARAMETER_VALUE
, "mode",
52 "halt|powerdown|reboot");
58 /* child, start the shutdown */
64 ret
= execl("/sbin/shutdown", "shutdown", shutdown_flag
, "+0",
65 "hypervisor initiated shutdown", (char*)NULL
);
67 slog("guest-shutdown failed: %s", strerror(errno
));
75 rpid
= waitpid(pid
, &status
, 0);
76 } while (rpid
== -1 && errno
== EINTR
);
77 if (rpid
== pid
&& WIFEXITED(status
) && !WEXITSTATUS(status
)) {
82 error_set(err
, QERR_UNDEFINED_ERROR
);
85 typedef struct GuestFileHandle
{
88 QTAILQ_ENTRY(GuestFileHandle
) next
;
92 QTAILQ_HEAD(, GuestFileHandle
) filehandles
;
95 static void guest_file_handle_add(FILE *fh
)
99 gfh
= g_malloc0(sizeof(GuestFileHandle
));
100 gfh
->id
= fileno(fh
);
102 QTAILQ_INSERT_TAIL(&guest_file_state
.filehandles
, gfh
, next
);
105 static GuestFileHandle
*guest_file_handle_find(int64_t id
)
107 GuestFileHandle
*gfh
;
109 QTAILQ_FOREACH(gfh
, &guest_file_state
.filehandles
, next
)
119 int64_t qmp_guest_file_open(const char *path
, bool has_mode
, const char *mode
, Error
**err
)
128 slog("guest-file-open called, filepath: %s, mode: %s", path
, mode
);
129 fh
= fopen(path
, mode
);
131 error_set(err
, QERR_OPEN_FILE_FAILED
, path
);
135 /* set fd non-blocking to avoid common use cases (like reading from a
136 * named pipe) from hanging the agent
139 ret
= fcntl(fd
, F_GETFL
);
140 ret
= fcntl(fd
, F_SETFL
, ret
| O_NONBLOCK
);
142 error_set(err
, QERR_QGA_COMMAND_FAILED
, "fcntl() failed");
147 guest_file_handle_add(fh
);
148 slog("guest-file-open, handle: %d", fd
);
152 void qmp_guest_file_close(int64_t handle
, Error
**err
)
154 GuestFileHandle
*gfh
= guest_file_handle_find(handle
);
157 slog("guest-file-close called, handle: %ld", handle
);
159 error_set(err
, QERR_FD_NOT_FOUND
, "handle");
163 ret
= fclose(gfh
->fh
);
165 error_set(err
, QERR_QGA_COMMAND_FAILED
, "fclose() failed");
169 QTAILQ_REMOVE(&guest_file_state
.filehandles
, gfh
, next
);
173 struct GuestFileRead
*qmp_guest_file_read(int64_t handle
, bool has_count
,
174 int64_t count
, Error
**err
)
176 GuestFileHandle
*gfh
= guest_file_handle_find(handle
);
177 GuestFileRead
*read_data
= NULL
;
183 error_set(err
, QERR_FD_NOT_FOUND
, "handle");
188 count
= QGA_READ_COUNT_DEFAULT
;
189 } else if (count
< 0) {
190 error_set(err
, QERR_INVALID_PARAMETER
, "count");
195 buf
= g_malloc0(count
+1);
196 read_count
= fread(buf
, 1, count
, fh
);
198 slog("guest-file-read failed, handle: %ld", handle
);
199 error_set(err
, QERR_QGA_COMMAND_FAILED
, "fread() failed");
202 read_data
= g_malloc0(sizeof(GuestFileRead
));
203 read_data
->count
= read_count
;
204 read_data
->eof
= feof(fh
);
206 read_data
->buf_b64
= g_base64_encode(buf
, read_count
);
215 GuestFileWrite
*qmp_guest_file_write(int64_t handle
, const char *buf_b64
,
216 bool has_count
, int64_t count
, Error
**err
)
218 GuestFileWrite
*write_data
= NULL
;
222 GuestFileHandle
*gfh
= guest_file_handle_find(handle
);
226 error_set(err
, QERR_FD_NOT_FOUND
, "handle");
231 buf
= g_base64_decode(buf_b64
, &buf_len
);
235 } else if (count
< 0 || count
> buf_len
) {
237 error_set(err
, QERR_INVALID_PARAMETER
, "count");
241 write_count
= fwrite(buf
, 1, count
, fh
);
243 slog("guest-file-write failed, handle: %ld", handle
);
244 error_set(err
, QERR_QGA_COMMAND_FAILED
, "fwrite() error");
246 write_data
= g_malloc0(sizeof(GuestFileWrite
));
247 write_data
->count
= write_count
;
248 write_data
->eof
= feof(fh
);
256 struct GuestFileSeek
*qmp_guest_file_seek(int64_t handle
, int64_t offset
,
257 int64_t whence
, Error
**err
)
259 GuestFileHandle
*gfh
= guest_file_handle_find(handle
);
260 GuestFileSeek
*seek_data
= NULL
;
265 error_set(err
, QERR_FD_NOT_FOUND
, "handle");
270 ret
= fseek(fh
, offset
, whence
);
272 error_set(err
, QERR_QGA_COMMAND_FAILED
, strerror(errno
));
274 seek_data
= g_malloc0(sizeof(GuestFileRead
));
275 seek_data
->position
= ftell(fh
);
276 seek_data
->eof
= feof(fh
);
283 void qmp_guest_file_flush(int64_t handle
, Error
**err
)
285 GuestFileHandle
*gfh
= guest_file_handle_find(handle
);
290 error_set(err
, QERR_FD_NOT_FOUND
, "handle");
297 error_set(err
, QERR_QGA_COMMAND_FAILED
, strerror(errno
));
301 static void guest_file_init(void)
303 QTAILQ_INIT(&guest_file_state
.filehandles
);
306 /* linux-specific implementations. avoid this if at all possible. */
307 #if defined(__linux__)
309 #if defined(CONFIG_FSFREEZE)
311 typedef struct GuestFsfreezeMount
{
314 QTAILQ_ENTRY(GuestFsfreezeMount
) next
;
315 } GuestFsfreezeMount
;
317 typedef QTAILQ_HEAD(, GuestFsfreezeMount
) GuestFsfreezeMountList
;
319 static void guest_fsfreeze_free_mount_list(GuestFsfreezeMountList
*mounts
)
321 GuestFsfreezeMount
*mount
, *temp
;
327 QTAILQ_FOREACH_SAFE(mount
, mounts
, next
, temp
) {
328 QTAILQ_REMOVE(mounts
, mount
, next
);
329 g_free(mount
->dirname
);
330 g_free(mount
->devtype
);
336 * Walk the mount table and build a list of local file systems
338 static int guest_fsfreeze_build_mount_list(GuestFsfreezeMountList
*mounts
)
341 GuestFsfreezeMount
*mount
;
342 char const *mtab
= MOUNTED
;
345 fp
= setmntent(mtab
, "r");
347 g_warning("fsfreeze: unable to read mtab");
351 while ((ment
= getmntent(fp
))) {
353 * An entry which device name doesn't start with a '/' is
354 * either a dummy file system or a network file system.
355 * Add special handling for smbfs and cifs as is done by
358 if ((ment
->mnt_fsname
[0] != '/') ||
359 (strcmp(ment
->mnt_type
, "smbfs") == 0) ||
360 (strcmp(ment
->mnt_type
, "cifs") == 0)) {
364 mount
= g_malloc0(sizeof(GuestFsfreezeMount
));
365 mount
->dirname
= g_strdup(ment
->mnt_dir
);
366 mount
->devtype
= g_strdup(ment
->mnt_type
);
368 QTAILQ_INSERT_TAIL(mounts
, mount
, next
);
377 * Return status of freeze/thaw
379 GuestFsfreezeStatus
qmp_guest_fsfreeze_status(Error
**err
)
381 if (ga_is_frozen(ga_state
)) {
382 return GUEST_FSFREEZE_STATUS_FROZEN
;
385 return GUEST_FSFREEZE_STATUS_THAWED
;
389 * Walk list of mounted file systems in the guest, and freeze the ones which
390 * are real local file systems.
392 int64_t qmp_guest_fsfreeze_freeze(Error
**err
)
395 GuestFsfreezeMountList mounts
;
396 struct GuestFsfreezeMount
*mount
;
400 slog("guest-fsfreeze called");
402 QTAILQ_INIT(&mounts
);
403 ret
= guest_fsfreeze_build_mount_list(&mounts
);
408 /* cannot risk guest agent blocking itself on a write in this state */
409 ga_set_frozen(ga_state
);
411 QTAILQ_FOREACH(mount
, &mounts
, next
) {
412 fd
= qemu_open(mount
->dirname
, O_RDONLY
);
414 sprintf(err_msg
, "failed to open %s, %s", mount
->dirname
,
416 error_set(err
, QERR_QGA_COMMAND_FAILED
, err_msg
);
420 /* we try to cull filesytems we know won't work in advance, but other
421 * filesytems may not implement fsfreeze for less obvious reasons.
422 * these will report EOPNOTSUPP. we simply ignore these when tallying
423 * the number of frozen filesystems.
425 * any other error means a failure to freeze a filesystem we
426 * expect to be freezable, so return an error in those cases
427 * and return system to thawed state.
429 ret
= ioctl(fd
, FIFREEZE
);
431 if (errno
!= EOPNOTSUPP
) {
432 sprintf(err_msg
, "failed to freeze %s, %s",
433 mount
->dirname
, strerror(errno
));
434 error_set(err
, QERR_QGA_COMMAND_FAILED
, err_msg
);
444 guest_fsfreeze_free_mount_list(&mounts
);
448 guest_fsfreeze_free_mount_list(&mounts
);
449 qmp_guest_fsfreeze_thaw(NULL
);
454 * Walk list of frozen file systems in the guest, and thaw them.
456 int64_t qmp_guest_fsfreeze_thaw(Error
**err
)
459 GuestFsfreezeMountList mounts
;
460 GuestFsfreezeMount
*mount
;
461 int fd
, i
= 0, logged
;
463 QTAILQ_INIT(&mounts
);
464 ret
= guest_fsfreeze_build_mount_list(&mounts
);
466 error_set(err
, QERR_QGA_COMMAND_FAILED
,
467 "failed to enumerate filesystems");
471 QTAILQ_FOREACH(mount
, &mounts
, next
) {
473 fd
= qemu_open(mount
->dirname
, O_RDONLY
);
477 /* we have no way of knowing whether a filesystem was actually unfrozen
478 * as a result of a successful call to FITHAW, only that if an error
479 * was returned the filesystem was *not* unfrozen by that particular
482 * since multiple preceding FIFREEZEs require multiple calls to FITHAW
483 * to unfreeze, continuing issuing FITHAW until an error is returned,
484 * in which case either the filesystem is in an unfreezable state, or,
485 * more likely, it was thawed previously (and remains so afterward).
487 * also, since the most recent successful call is the one that did
488 * the actual unfreeze, we can use this to provide an accurate count
489 * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which
490 * may * be useful for determining whether a filesystem was unfrozen
491 * during the freeze/thaw phase by a process other than qemu-ga.
494 ret
= ioctl(fd
, FITHAW
);
495 if (ret
== 0 && !logged
) {
503 ga_unset_frozen(ga_state
);
504 guest_fsfreeze_free_mount_list(&mounts
);
508 static void guest_fsfreeze_cleanup(void)
513 if (ga_is_frozen(ga_state
) == GUEST_FSFREEZE_STATUS_FROZEN
) {
514 ret
= qmp_guest_fsfreeze_thaw(&err
);
515 if (ret
< 0 || err
) {
516 slog("failed to clean up frozen filesystems");
520 #endif /* CONFIG_FSFREEZE */
522 #define LINUX_SYS_STATE_FILE "/sys/power/state"
523 #define SUSPEND_SUPPORTED 0
524 #define SUSPEND_NOT_SUPPORTED 1
526 static void bios_supports_mode(const char *pmutils_bin
, const char *pmutils_arg
,
527 const char *sysfile_str
, Error
**err
)
533 pmutils_path
= g_find_program_in_path(pmutils_bin
);
537 char buf
[32]; /* hopefully big enough */
542 reopen_fd_to_null(0);
543 reopen_fd_to_null(1);
544 reopen_fd_to_null(2);
547 execle(pmutils_path
, pmutils_bin
, pmutils_arg
, NULL
, environ
);
551 * If we get here either pm-utils is not installed or execle() has
552 * failed. Let's try the manual method if the caller wants it.
556 _exit(SUSPEND_NOT_SUPPORTED
);
559 fd
= open(LINUX_SYS_STATE_FILE
, O_RDONLY
);
561 _exit(SUSPEND_NOT_SUPPORTED
);
564 ret
= read(fd
, buf
, sizeof(buf
)-1);
566 _exit(SUSPEND_NOT_SUPPORTED
);
570 if (strstr(buf
, sysfile_str
)) {
571 _exit(SUSPEND_SUPPORTED
);
574 _exit(SUSPEND_NOT_SUPPORTED
);
577 g_free(pmutils_path
);
584 rpid
= waitpid(pid
, &status
, 0);
585 } while (rpid
== -1 && errno
== EINTR
);
586 if (rpid
== pid
&& WIFEXITED(status
)) {
587 switch (WEXITSTATUS(status
)) {
588 case SUSPEND_SUPPORTED
:
590 case SUSPEND_NOT_SUPPORTED
:
591 error_set(err
, QERR_UNSUPPORTED
);
599 error_set(err
, QERR_UNDEFINED_ERROR
);
602 static void guest_suspend(const char *pmutils_bin
, const char *sysfile_str
,
609 pmutils_path
= g_find_program_in_path(pmutils_bin
);
617 reopen_fd_to_null(0);
618 reopen_fd_to_null(1);
619 reopen_fd_to_null(2);
622 execle(pmutils_path
, pmutils_bin
, NULL
, environ
);
626 * If we get here either pm-utils is not installed or execle() has
627 * failed. Let's try the manual method if the caller wants it.
634 fd
= open(LINUX_SYS_STATE_FILE
, O_WRONLY
);
639 if (write(fd
, sysfile_str
, strlen(sysfile_str
)) < 0) {
646 g_free(pmutils_path
);
653 rpid
= waitpid(pid
, &status
, 0);
654 } while (rpid
== -1 && errno
== EINTR
);
655 if (rpid
== pid
&& WIFEXITED(status
) && !WEXITSTATUS(status
)) {
660 error_set(err
, QERR_UNDEFINED_ERROR
);
663 void qmp_guest_suspend_disk(Error
**err
)
665 bios_supports_mode("pm-is-supported", "--hibernate", "disk", err
);
666 if (error_is_set(err
)) {
670 guest_suspend("pm-hibernate", "disk", err
);
673 void qmp_guest_suspend_ram(Error
**err
)
675 bios_supports_mode("pm-is-supported", "--suspend", "mem", err
);
676 if (error_is_set(err
)) {
680 guest_suspend("pm-suspend", "mem", err
);
683 void qmp_guest_suspend_hybrid(Error
**err
)
685 bios_supports_mode("pm-is-supported", "--suspend-hybrid", NULL
, err
);
686 if (error_is_set(err
)) {
690 guest_suspend("pm-suspend-hybrid", NULL
, err
);
693 static GuestNetworkInterfaceList
*
694 guest_find_interface(GuestNetworkInterfaceList
*head
,
697 for (; head
; head
= head
->next
) {
698 if (strcmp(head
->value
->name
, name
) == 0) {
707 * Build information about guest interfaces
709 GuestNetworkInterfaceList
*qmp_guest_network_get_interfaces(Error
**errp
)
711 GuestNetworkInterfaceList
*head
= NULL
, *cur_item
= NULL
;
712 struct ifaddrs
*ifap
, *ifa
;
715 if (getifaddrs(&ifap
) < 0) {
716 snprintf(err_msg
, sizeof(err_msg
),
717 "getifaddrs failed: %s", strerror(errno
));
718 error_set(errp
, QERR_QGA_COMMAND_FAILED
, err_msg
);
722 for (ifa
= ifap
; ifa
; ifa
= ifa
->ifa_next
) {
723 GuestNetworkInterfaceList
*info
;
724 GuestIpAddressList
**address_list
= NULL
, *address_item
= NULL
;
725 char addr4
[INET_ADDRSTRLEN
];
726 char addr6
[INET6_ADDRSTRLEN
];
729 unsigned char *mac_addr
;
732 g_debug("Processing %s interface", ifa
->ifa_name
);
734 info
= guest_find_interface(head
, ifa
->ifa_name
);
737 info
= g_malloc0(sizeof(*info
));
738 info
->value
= g_malloc0(sizeof(*info
->value
));
739 info
->value
->name
= g_strdup(ifa
->ifa_name
);
742 head
= cur_item
= info
;
744 cur_item
->next
= info
;
749 if (!info
->value
->has_hardware_address
&&
750 ifa
->ifa_flags
& SIOCGIFHWADDR
) {
751 /* we haven't obtained HW address yet */
752 sock
= socket(PF_INET
, SOCK_STREAM
, 0);
754 snprintf(err_msg
, sizeof(err_msg
),
755 "failed to create socket: %s", strerror(errno
));
756 error_set(errp
, QERR_QGA_COMMAND_FAILED
, err_msg
);
760 memset(&ifr
, 0, sizeof(ifr
));
761 strncpy(ifr
.ifr_name
, info
->value
->name
, IF_NAMESIZE
);
762 if (ioctl(sock
, SIOCGIFHWADDR
, &ifr
) == -1) {
763 snprintf(err_msg
, sizeof(err_msg
),
764 "failed to get MAC address of %s: %s",
767 error_set(errp
, QERR_QGA_COMMAND_FAILED
, err_msg
);
771 mac_addr
= (unsigned char *) &ifr
.ifr_hwaddr
.sa_data
;
773 if (asprintf(&info
->value
->hardware_address
,
774 "%02x:%02x:%02x:%02x:%02x:%02x",
775 (int) mac_addr
[0], (int) mac_addr
[1],
776 (int) mac_addr
[2], (int) mac_addr
[3],
777 (int) mac_addr
[4], (int) mac_addr
[5]) == -1) {
778 snprintf(err_msg
, sizeof(err_msg
),
779 "failed to format MAC: %s", strerror(errno
));
780 error_set(errp
, QERR_QGA_COMMAND_FAILED
, err_msg
);
784 info
->value
->has_hardware_address
= true;
789 ifa
->ifa_addr
->sa_family
== AF_INET
) {
790 /* interface with IPv4 address */
791 address_item
= g_malloc0(sizeof(*address_item
));
792 address_item
->value
= g_malloc0(sizeof(*address_item
->value
));
793 p
= &((struct sockaddr_in
*)ifa
->ifa_addr
)->sin_addr
;
794 if (!inet_ntop(AF_INET
, p
, addr4
, sizeof(addr4
))) {
795 snprintf(err_msg
, sizeof(err_msg
),
796 "inet_ntop failed : %s", strerror(errno
));
797 error_set(errp
, QERR_QGA_COMMAND_FAILED
, err_msg
);
801 address_item
->value
->ip_address
= g_strdup(addr4
);
802 address_item
->value
->ip_address_type
= GUEST_IP_ADDRESS_TYPE_IPV4
;
804 if (ifa
->ifa_netmask
) {
805 /* Count the number of set bits in netmask.
806 * This is safe as '1' and '0' cannot be shuffled in netmask. */
807 p
= &((struct sockaddr_in
*)ifa
->ifa_netmask
)->sin_addr
;
808 address_item
->value
->prefix
= ctpop32(((uint32_t *) p
)[0]);
810 } else if (ifa
->ifa_addr
&&
811 ifa
->ifa_addr
->sa_family
== AF_INET6
) {
812 /* interface with IPv6 address */
813 address_item
= g_malloc0(sizeof(*address_item
));
814 address_item
->value
= g_malloc0(sizeof(*address_item
->value
));
815 p
= &((struct sockaddr_in6
*)ifa
->ifa_addr
)->sin6_addr
;
816 if (!inet_ntop(AF_INET6
, p
, addr6
, sizeof(addr6
))) {
817 snprintf(err_msg
, sizeof(err_msg
),
818 "inet_ntop failed : %s", strerror(errno
));
819 error_set(errp
, QERR_QGA_COMMAND_FAILED
, err_msg
);
823 address_item
->value
->ip_address
= g_strdup(addr6
);
824 address_item
->value
->ip_address_type
= GUEST_IP_ADDRESS_TYPE_IPV6
;
826 if (ifa
->ifa_netmask
) {
827 /* Count the number of set bits in netmask.
828 * This is safe as '1' and '0' cannot be shuffled in netmask. */
829 p
= &((struct sockaddr_in6
*)ifa
->ifa_netmask
)->sin6_addr
;
830 address_item
->value
->prefix
=
831 ctpop32(((uint32_t *) p
)[0]) +
832 ctpop32(((uint32_t *) p
)[1]) +
833 ctpop32(((uint32_t *) p
)[2]) +
834 ctpop32(((uint32_t *) p
)[3]);
842 address_list
= &info
->value
->ip_addresses
;
844 while (*address_list
&& (*address_list
)->next
) {
845 address_list
= &(*address_list
)->next
;
848 if (!*address_list
) {
849 *address_list
= address_item
;
851 (*address_list
)->next
= address_item
;
854 info
->value
->has_ip_addresses
= true;
864 qapi_free_GuestNetworkInterfaceList(head
);
868 #else /* defined(__linux__) */
870 void qmp_guest_suspend_disk(Error
**err
)
872 error_set(err
, QERR_UNSUPPORTED
);
875 void qmp_guest_suspend_ram(Error
**err
)
877 error_set(err
, QERR_UNSUPPORTED
);
880 void qmp_guest_suspend_hybrid(Error
**err
)
882 error_set(err
, QERR_UNSUPPORTED
);
885 GuestNetworkInterfaceList
*qmp_guest_network_get_interfaces(Error
**errp
)
887 error_set(errp
, QERR_UNSUPPORTED
);
893 #if !defined(CONFIG_FSFREEZE)
895 GuestFsfreezeStatus
qmp_guest_fsfreeze_status(Error
**err
)
897 error_set(err
, QERR_UNSUPPORTED
);
902 int64_t qmp_guest_fsfreeze_freeze(Error
**err
)
904 error_set(err
, QERR_UNSUPPORTED
);
909 int64_t qmp_guest_fsfreeze_thaw(Error
**err
)
911 error_set(err
, QERR_UNSUPPORTED
);
918 /* register init/cleanup routines for stateful command groups */
919 void ga_command_state_init(GAState
*s
, GACommandState
*cs
)
921 #if defined(CONFIG_FSFREEZE)
922 ga_command_state_add(cs
, NULL
, guest_fsfreeze_cleanup
);
924 ga_command_state_add(cs
, guest_file_init
, NULL
);