Reviewed-by: Kostiantyn Kostiuk <[email protected]> On Fri, Jul 3, 2026 at 7:32 PM Roman Bogorodskiy <[email protected]> wrote:
> Implement the qmp_guest_get_fsinfo() API for FreeBSD. > To implement it, reuse build_fs_mount_list() which is already > implemented for FreeBSD. Extend the FsMount type to include > a string "fromname" attribute to store the disk the FS is mounted from. > > Disk mapping info is not covered by this implementation. > > Signed-off-by: Roman Bogorodskiy <[email protected]> > Acked-by: Markus Armbruster <[email protected]> > --- > Changes since v1: > > - Replace g_malloc0() with g_new0(.., 1) for GuestFilesystemInfo > > > qga/commands-bsd.c | 62 ++++++++++++++++++++++++++++++++++++++++++- > qga/commands-common.h | 1 + > qga/commands-posix.c | 3 +++ > qga/qapi-schema.json | 12 ++++----- > 4 files changed, 71 insertions(+), 7 deletions(-) > > diff --git a/qga/commands-bsd.c b/qga/commands-bsd.c > index 94ff6fee6a..7f65f2b8db 100644 > --- a/qga/commands-bsd.c > +++ b/qga/commands-bsd.c > @@ -20,6 +20,7 @@ > #include <sys/ucred.h> > #include <sys/mount.h> > #include <net/if_dl.h> > +#include <sys/statvfs.h> > #if defined(__NetBSD__) || defined(__OpenBSD__) > #include <net/if_arp.h> > #include <netinet/if_ether.h> > @@ -28,7 +29,7 @@ > #endif > #include <paths.h> > > -#if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) > +#if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) || > defined(__FreeBSD__) > bool build_fs_mount_list(FsMountList *mounts, Error **errp) > { > FsMount *mount; > @@ -55,6 +56,7 @@ bool build_fs_mount_list(FsMountList *mounts, Error > **errp) > > mount->dirname = g_strdup(mntp->f_mntonname); > mount->devtype = g_strdup(mntp->f_fstypename); > + mount->fromname = g_strdup(mntp->f_mntfromname); > mount->devmajor = major(mount->dev); > mount->devminor = minor(mount->dev); > mount->fsid = mntp->f_fsid; > @@ -178,3 +180,61 @@ bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned > char *buf, > return true; > } > #endif /* HAVE_GETIFADDRS */ > + > +#if defined(__FreeBSD__) > +static GuestFilesystemInfo *build_guest_fsinfo(struct FsMount *mount, > + Error **errp) > +{ > + GuestFilesystemInfo *fs = g_new0(GuestFilesystemInfo, 1); > + struct statvfs buf; > + unsigned long used, nonroot_total, fr_size; > + > + fs->mountpoint = g_strdup(mount->dirname); > + fs->type = g_strdup(mount->devtype); > + fs->name = g_strdup(g_path_get_basename(mount->fromname)); > + > + if (statvfs(fs->mountpoint, &buf) == 0) { > + fr_size = buf.f_frsize; > + used = buf.f_blocks - buf.f_bfree; > + nonroot_total = used + buf.f_bavail; > + fs->used_bytes = used * fr_size; > + fs->total_bytes = nonroot_total * fr_size; > + fs->total_bytes_privileged = buf.f_blocks * fr_size; > + > + fs->has_total_bytes = true; > + fs->has_total_bytes_privileged = true; > + fs->has_used_bytes = true; > + } > + > + return fs; > +} > + > +GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) > +{ > + FsMountList mounts; > + struct FsMount *mount; > + GuestFilesystemInfoList *ret = NULL; > + Error *local_err = NULL; > + > + QTAILQ_INIT(&mounts); > + if (!build_fs_mount_list(&mounts, &local_err)) { > + error_propagate(errp, local_err); > + return NULL; > + } > + > + QTAILQ_FOREACH(mount, &mounts, next) { > + g_debug("Building guest fsinfo for '%s'", mount->dirname); > + > + QAPI_LIST_PREPEND(ret, build_guest_fsinfo(mount, &local_err)); > + if (local_err) { > + error_propagate(errp, local_err); > + qapi_free_GuestFilesystemInfoList(ret); > + ret = NULL; > + break; > + } > + } > + > + free_fs_mount_list(&mounts); > + return ret; > +} > +#endif /* __FreeBSD__ */ > diff --git a/qga/commands-common.h b/qga/commands-common.h > index 263e7c0525..a07d0885f5 100644 > --- a/qga/commands-common.h > +++ b/qga/commands-common.h > @@ -29,6 +29,7 @@ typedef struct FsMount { > #if defined(__FreeBSD__) > dev_t dev; > fsid_t fsid; > + char *fromname; > #endif > QTAILQ_ENTRY(FsMount) next; > } FsMount; > diff --git a/qga/commands-posix.c b/qga/commands-posix.c > index 837be51c40..837e285b6d 100644 > --- a/qga/commands-posix.c > +++ b/qga/commands-posix.c > @@ -731,6 +731,9 @@ void free_fs_mount_list(FsMountList *mounts) > QTAILQ_REMOVE(mounts, mount, next); > g_free(mount->dirname); > g_free(mount->devtype); > +#if defined(__FreeBSD__) > + g_free(mount->fromname); > +#endif > g_free(mount); > } > } > diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json > index c57bc9a02f..8cd0ba048b 100644 > --- a/qga/qapi-schema.json > +++ b/qga/qapi-schema.json > @@ -874,7 +874,7 @@ > 'data': [ 'ide', 'fdc', 'scsi', 'virtio', 'xen', 'usb', 'uml', 'sata', > 'sd', 'unknown', 'ieee1394', 'ssa', 'fibre', 'raid', 'iscsi', > 'sas', 'mmc', 'virtual', 'file-backed-virtual', 'nvme' ], > - 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX' ] } } > + 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX', 'CONFIG_FREEBSD' ] } } > > ## > # @GuestPCIAddress: > @@ -892,7 +892,7 @@ > { 'struct': 'GuestPCIAddress', > 'data': {'domain': 'int', 'bus': 'int', > 'slot': 'int', 'function': 'int'}, > - 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX' ] } } > + 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX', 'CONFIG_FREEBSD' ] } } > > ## > # @GuestCCWAddress: > @@ -912,7 +912,7 @@ > 'ssid': 'int', > 'subchno': 'int', > 'devno': 'int'}, > - 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX' ] } } > + 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX', 'CONFIG_FREEBSD' ] } } > > ## > # @GuestDiskAddress: > @@ -942,7 +942,7 @@ > 'bus': 'int', 'target': 'int', 'unit': 'int', > '*serial': 'str', '*dev': 'str', > '*ccw-address': 'GuestCCWAddress'}, > - 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX' ] } } > + 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX', 'CONFIG_FREEBSD' ] } } > > ## > # @GuestNVMeSmart: > @@ -1063,7 +1063,7 @@ > 'data': {'name': 'str', 'mountpoint': 'str', 'type': 'str', > '*used-bytes': 'uint64', '*total-bytes': 'uint64', > '*total-bytes-privileged': 'uint64', 'disk': > ['GuestDiskAddress']}, > - 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX' ] } } > + 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX', 'CONFIG_FREEBSD' ] } } > > ## > # @guest-get-fsinfo: > @@ -1077,7 +1077,7 @@ > ## > { 'command': 'guest-get-fsinfo', > 'returns': ['GuestFilesystemInfo'], > - 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX' ] } } > + 'if': { 'any': [ 'CONFIG_WIN32', 'CONFIG_LINUX', 'CONFIG_FREEBSD' ] } } > > ## > # @guest-set-user-password: > -- > 2.52.0 > >
