Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'qga-pull-2022-10-26' of https://github.com/kostyanf14/qemu …
…into staging qga-pull-2022-10-26 # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEwsLBCepDxjwUI+uE711egWG6hOcFAmNZcDMACgkQ711egWG6 # hOdRPQ/8D5T9GpkC+Ar9GLlx/DZFZx0+FxdolV06TcuSXTz3SXYtVKJUSaLjW3SF # ZRMbBYxqO1NKXWfe8kPKzSR7lJY9fBdn75AUbN88iYW7xu2x+A8LNskVOanu8vbo # eqcjO1x3sStzdZHfA4uFUsF7J9A2zqflmZxTMWm1UDt1HTklAJLPkb/E6DnVc3Rp # WhI89JWvAZBOZoVBq7MyfBPEyf3KibHHMWENVY7vGmmXaw9EJQYpXNEMTeBP1VI3 # tTLxrr8WoGr5w2K4a3Kku2ixD+IOPPWXbZXmSjAGgOwiVSkORwMbUVHnN/A11O3O # b8XOGZ5LkFjgORTsm9ePxXJvcHlsxWZIb80ZnZA9oGF/33S7RbW1Kcl6OAVGdm0S # ZzysqPLPJStxuUvesqmFfGkvZ29EHNlWjrIfXQz5mnlDsnOi/0Bus0vNjc/kBNPF # KfHW6MNw4A2gmVcrNg2f2rlYveHa6e+4XsS5xJJ74WDMHWxMZRaFXyO+qU6p7lEJ # I5pLD9oEM856y2CpQJpoJnZ6ddLEag652x08WpCFMI76x5XLN8D0lszlgJghR7M7 # 84TKSF6HBvrMS+jQc3xZZlK7ELSluKtUFnSTkNZg9WiuQC/FS+7XRcC6lek1qBAL # WVsKL5UwM/Eyq+O/B8R7w6TEWFxnEFmjddq1rD6kH8LYx1Lmt4M= # =h41f # -----END PGP SIGNATURE----- # gpg: Signature made Wed 26 Oct 2022 13:36:51 EDT # gpg: using RSA key C2C2C109EA43C63C1423EB84EF5D5E8161BA84E7 # gpg: Good signature from "Kostiantyn Kostiuk (Upstream PR sign) <kkostiuk@redhat.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: C2C2 C109 EA43 C63C 1423 EB84 EF5D 5E81 61BA 84E7 * tag 'qga-pull-2022-10-26' of https://github.com/kostyanf14/qemu: qga: add channel path to error messages qga: Add HW address getting for FreeBSD qga: Move HW address getting to a separate function qga: Add support for user password setting in FreeBSD qga: Add shutdown/halt/reboot support for FreeBSD qga: Add UFS freeze/thaw support for FreeBSD qga: Move Linux-specific FS freeze/thaw code to a separate file qga: Add initial FreeBSD support Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
- Loading branch information
Showing
8 changed files
with
780 additions
and
440 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
/* | ||
* QEMU Guest Agent BSD-specific command implementations | ||
* | ||
* Copyright (c) Virtuozzo International GmbH. | ||
* | ||
* Authors: | ||
* Alexander Ivanov <alexander.ivanov@virtuozzo.com> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or later. | ||
* See the COPYING file in the top-level directory. | ||
*/ | ||
|
||
#include "qemu/osdep.h" | ||
#include "qga-qapi-commands.h" | ||
#include "qapi/qmp/qerror.h" | ||
#include "qapi/error.h" | ||
#include "qemu/queue.h" | ||
#include "commands-common.h" | ||
#include <sys/ioctl.h> | ||
#include <sys/param.h> | ||
#include <sys/ucred.h> | ||
#include <sys/mount.h> | ||
#include <net/if_dl.h> | ||
#include <net/ethernet.h> | ||
#include <paths.h> | ||
|
||
#if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) | ||
bool build_fs_mount_list(FsMountList *mounts, Error **errp) | ||
{ | ||
FsMount *mount; | ||
struct statfs *mntbuf, *mntp; | ||
struct stat statbuf; | ||
int i, count, ret; | ||
|
||
count = getmntinfo(&mntbuf, MNT_NOWAIT); | ||
if (count == 0) { | ||
error_setg_errno(errp, errno, "getmntinfo failed"); | ||
return false; | ||
} | ||
|
||
for (i = 0; i < count; i++) { | ||
mntp = &mntbuf[i]; | ||
ret = stat(mntp->f_mntonname, &statbuf); | ||
if (ret != 0) { | ||
error_setg_errno(errp, errno, "stat failed on %s", | ||
mntp->f_mntonname); | ||
return false; | ||
} | ||
|
||
mount = g_new0(FsMount, 1); | ||
|
||
mount->dirname = g_strdup(mntp->f_mntonname); | ||
mount->devtype = g_strdup(mntp->f_fstypename); | ||
mount->devmajor = major(mount->dev); | ||
mount->devminor = minor(mount->dev); | ||
mount->fsid = mntp->f_fsid; | ||
mount->dev = statbuf.st_dev; | ||
|
||
QTAILQ_INSERT_TAIL(mounts, mount, next); | ||
} | ||
return true; | ||
} | ||
#endif /* CONFIG_FSFREEZE || CONFIG_FSTRIM */ | ||
|
||
#if defined(CONFIG_FSFREEZE) | ||
static int ufssuspend_fd = -1; | ||
static int ufssuspend_cnt; | ||
|
||
int64_t qmp_guest_fsfreeze_do_freeze_list(bool has_mountpoints, | ||
strList *mountpoints, | ||
FsMountList mounts, | ||
Error **errp) | ||
{ | ||
int ret; | ||
strList *list; | ||
struct FsMount *mount; | ||
|
||
if (ufssuspend_fd != -1) { | ||
error_setg(errp, "filesystems have already frozen"); | ||
return -1; | ||
} | ||
|
||
ufssuspend_cnt = 0; | ||
ufssuspend_fd = qemu_open(_PATH_UFSSUSPEND, O_RDWR, errp); | ||
if (ufssuspend_fd == -1) { | ||
return -1; | ||
} | ||
|
||
QTAILQ_FOREACH_REVERSE(mount, &mounts, next) { | ||
/* | ||
* To issue fsfreeze in the reverse order of mounts, check if the | ||
* mount is listed in the list here | ||
*/ | ||
if (has_mountpoints) { | ||
for (list = mountpoints; list; list = list->next) { | ||
if (g_str_equal(list->value, mount->dirname)) { | ||
break; | ||
} | ||
} | ||
if (!list) { | ||
continue; | ||
} | ||
} | ||
|
||
/* Only UFS supports suspend */ | ||
if (!g_str_equal(mount->devtype, "ufs")) { | ||
continue; | ||
} | ||
|
||
ret = ioctl(ufssuspend_fd, UFSSUSPEND, &mount->fsid); | ||
if (ret == -1) { | ||
/* | ||
* ioctl returns EBUSY for all the FS except the first one | ||
* that was suspended | ||
*/ | ||
if (errno == EBUSY) { | ||
continue; | ||
} | ||
error_setg_errno(errp, errno, "failed to freeze %s", | ||
mount->dirname); | ||
goto error; | ||
} | ||
ufssuspend_cnt++; | ||
} | ||
return ufssuspend_cnt; | ||
error: | ||
close(ufssuspend_fd); | ||
ufssuspend_fd = -1; | ||
return -1; | ||
|
||
} | ||
|
||
/* | ||
* We don't need to call UFSRESUME ioctl because all the frozen FS | ||
* are thawed on /dev/ufssuspend closing. | ||
*/ | ||
int qmp_guest_fsfreeze_do_thaw(Error **errp) | ||
{ | ||
int ret = ufssuspend_cnt; | ||
ufssuspend_cnt = 0; | ||
if (ufssuspend_fd != -1) { | ||
close(ufssuspend_fd); | ||
ufssuspend_fd = -1; | ||
} | ||
return ret; | ||
} | ||
|
||
GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) | ||
{ | ||
error_setg(errp, QERR_UNSUPPORTED); | ||
return NULL; | ||
} | ||
|
||
GuestDiskInfoList *qmp_guest_get_disks(Error **errp) | ||
{ | ||
error_setg(errp, QERR_UNSUPPORTED); | ||
return NULL; | ||
} | ||
|
||
GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp) | ||
{ | ||
error_setg(errp, QERR_UNSUPPORTED); | ||
return NULL; | ||
} | ||
|
||
GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp) | ||
{ | ||
error_setg(errp, QERR_UNSUPPORTED); | ||
return NULL; | ||
} | ||
#endif /* CONFIG_FSFREEZE */ | ||
|
||
#ifdef HAVE_GETIFADDRS | ||
/* | ||
* Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a | ||
* buffer with ETHER_ADDR_LEN length at least. | ||
* | ||
* Returns false in case of an error, otherwise true. "obtained" arguument | ||
* is true if a MAC address was obtained successful, otherwise false. | ||
*/ | ||
bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf, | ||
bool *obtained, Error **errp) | ||
{ | ||
struct sockaddr_dl *sdp; | ||
|
||
*obtained = false; | ||
|
||
if (ifa->ifa_addr->sa_family != AF_LINK) { | ||
/* We can get HW address only for AF_LINK family. */ | ||
g_debug("failed to get MAC address of %s", ifa->ifa_name); | ||
return true; | ||
} | ||
|
||
sdp = (struct sockaddr_dl *)ifa->ifa_addr; | ||
memcpy(buf, sdp->sdl_data + sdp->sdl_nlen, ETHER_ADDR_LEN); | ||
*obtained = true; | ||
|
||
return true; | ||
} | ||
#endif /* HAVE_GETIFADDRS */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.