common/mlutils: Unix_utils.StatVFS.statvfs: This commit implements a
full-featured binding for the statvfs(3) function which also includes
the statfs(2) f_type field.
We then use this to reimplement the daemon statvfs API in OCaml.
Note that the Gnulib fallback is fixed in this commit. It previously
referenced non-existent field names in the fs_usage struct.
---
common/mlutils/unix_utils-c.c | 171 ++++++++++++++++++++++++++++++++++++---
common/mlutils/unix_utils.ml | 22 ++++-
common/mlutils/unix_utils.mli | 26 +++++-
daemon/Makefile.am | 11 ++-
daemon/statvfs.c | 184 ------------------------------------------
daemon/statvfs.ml | 43 ++++++++++
daemon/statvfs.mli | 33 ++++++++
docs/C_SOURCE_FILES | 1 -
generator/actions_core.ml | 1 +
m4/guestfs_libraries.m4 | 5 +-
po/POTFILES | 1 -
sparsify/copying.ml | 2 +-
v2v/v2v.ml | 2 +-
13 files changed, 294 insertions(+), 208 deletions(-)
diff --git a/common/mlutils/unix_utils-c.c b/common/mlutils/unix_utils-c.c
index 631f1fddd..95501ba22 100644
--- a/common/mlutils/unix_utils-c.c
+++ b/common/mlutils/unix_utils-c.c
@@ -27,7 +27,18 @@
#include <fnmatch.h>
#include <errno.h>
#include <sys/types.h>
+
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+
+#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
+#endif
+
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
#if MAJOR_IN_MKDEV
#include <sys/mkdev.h>
@@ -36,12 +47,20 @@
/* else it's in sys/types.h, included above */
#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
#include <caml/alloc.h>
#include <caml/fail.h>
#include <caml/memory.h>
#include <caml/mlvalues.h>
#include <caml/unixsupport.h>
+#include "fsusage.h"
+
+#include "cleanups.h"
+
extern value guestfs_int_mllib_dev_t_makedev (value majv, value minv);
extern value guestfs_int_mllib_dev_t_major (value devv);
extern value guestfs_int_mllib_dev_t_minor (value devv);
@@ -52,7 +71,7 @@ extern value guestfs_int_mllib_sync (value unitv);
extern value guestfs_int_mllib_fsync_file (value filenamev);
extern value guestfs_int_mllib_mkdtemp (value val_pattern);
extern value guestfs_int_mllib_realpath (value pathv);
-extern value guestfs_int_mllib_statvfs_free_space (value pathv);
+extern value guestfs_int_mllib_statvfs_statvfs (value pathv);
/* NB: This is a "noalloc" call. */
value
@@ -207,20 +226,150 @@ guestfs_int_mllib_realpath (value pathv)
}
value
-guestfs_int_mllib_statvfs_free_space (value pathv)
+guestfs_int_mllib_statvfs_statvfs (value pathv)
{
CAMLparam1 (pathv);
- CAMLlocal1 (rv);
- struct statvfs buf;
- int64_t free_space;
+ int64_t f_bsize;
+ int64_t f_frsize;
+ int64_t f_blocks;
+ int64_t f_bfree;
+ int64_t f_bavail;
+ int64_t f_files;
+ int64_t f_ffree;
+ int64_t f_favail;
+ int64_t f_fsid;
+ int64_t f_flag;
+ int64_t f_namemax;
+ int64_t f_type;
+ CAMLlocal2 (rv, v);
- if (statvfs (String_val (pathv), &buf) == -1) {
- perror ("statvfs");
- caml_failwith ("statvfs");
- }
+#ifdef HAVE_FSTATVFS
+ CLEANUP_CLOSE int fd = -1;
+ struct statvfs buf1;
+#ifdef HAVE_FSTATFS
+ struct statfs buf2;
+#endif
- free_space = (int64_t) buf.f_bsize * buf.f_bavail;
- rv = caml_copy_int64 (free_space);
+ fd = open (String_val (pathv), O_RDONLY);
+ if (fd == -1)
+ unix_error (errno, (char *) "statvfs: open", pathv);
+ if (fstatvfs (fd, &buf1) == -1)
+ unix_error (errno, (char *) "statvfs: statvfs", pathv);
+#ifdef HAVE_FSTATFS
+ if (fstatfs (fd, &buf2) == -1)
+ unix_error (errno, (char *) "statvfs: statfs", pathv);
+#endif
+
+ f_bsize = buf1.f_bsize;
+ f_frsize = buf1.f_frsize;
+ f_blocks = buf1.f_blocks;
+ f_bfree = buf1.f_bfree;
+ f_bavail = buf1.f_bavail;
+ f_files = buf1.f_files;
+ f_ffree = buf1.f_ffree;
+ f_favail = buf1.f_favail;
+ f_fsid = buf1.f_fsid;
+ f_flag = buf1.f_flag;
+ f_namemax = buf1.f_namemax;
+#ifdef HAVE_FSTATFS
+ f_type = buf2.f_type;
+#else
+ f_type = -1;
+#endif
+
+#else /* !HAVE_FSTATVFS */
+# if WIN32
+ ULONGLONG free_bytes_available; /* for user - similar to bavail */
+ ULONGLONG total_number_of_bytes;
+ ULONGLONG total_number_of_free_bytes; /* for everyone - bfree */
+
+ if (!GetDiskFreeSpaceEx (String_val (pathv),
+ (PULARGE_INTEGER) &free_bytes_available,
+ (PULARGE_INTEGER) &total_number_of_bytes,
+ (PULARGE_INTEGER) &total_number_of_free_bytes))
+ unix_error (EIO, (char *) "statvfs: GetDiskFreeSpaceEx", pathv);
+
+ /* XXX I couldn't determine how to get block size. MSDN has a
+ * unhelpful hard-coded list here:
+ *
http://support.microsoft.com/kb/140365
+ * but this depends on the filesystem type, the size of the disk and
+ * the version of Windows. So this code assumes the disk is NTFS
+ * and the version of Windows is >= Win2K.
+ */
+ if (total_number_of_bytes < UINT64_C (16) * 1024 * 1024 * 1024 * 1024)
+ f_bsize = 4096;
+ else if (total_number_of_bytes < UINT64_C (32) * 1024 * 1024 * 1024 * 1024)
+ f_bsize = 8192;
+ else if (total_number_of_bytes < UINT64_C (64) * 1024 * 1024 * 1024 * 1024)
+ f_bsize = 16384;
+ else if (total_number_of_bytes < UINT64_C (128) * 1024 * 1024 * 1024 * 1024)
+ f_bsize = 32768;
+ else
+ f_bsize = 65536;
+
+ /* As with stat, -1 indicates a field is not known. */
+ f_frsize = ret->bsize;
+ f_blocks = total_number_of_bytes / ret->bsize;
+ f_bfree = total_number_of_free_bytes / ret->bsize;
+ f_bavail = free_bytes_available / ret->bsize;
+ f_files = -1;
+ f_ffree = -1;
+ f_favail = -1;
+ f_fsid = -1;
+ f_flag = -1;
+ f_namemax = FILENAME_MAX;
+ f_type = -1;
+
+# else /* !WIN32 */
+ /* This replacement function is provided by Gnulib. */
+ struct fs_usage fsu;
+
+ if (get_fs_usage (String_val (pathv), String_val (pathv), &fsu) == -1)
+ unix_error (EIO, (char *) "statvfs: get_fs_usage", pathv);
+
+ /* As with stat, -1 indicates a field is not known. */
+ f_bsize = fsu.fsu_bsize;
+ f_frsize = -1;
+ f_blocks = fsu.fsu_blocks;
+ f_bfree = fsu.fsu_bfree;
+ f_bavail = fsu.fsu_bavail;
+ f_files = fsu.fsu_files;
+ f_free = fsu.fsu_ffree;
+ f_favail = -1;
+ f_fsid = -1;
+ f_flag = -1;
+ f_namemax = -1;
+ f_type = -1;
+
+# endif /* !WIN32 */
+#endif /* !HAVE_FSTATVFS */
+
+ /* Construct the return struct. */
+ rv = caml_alloc (12, 0);
+ v = caml_copy_int64 (f_bsize);
+ Store_field (rv, 0, v);
+ v = caml_copy_int64 (f_frsize);
+ Store_field (rv, 1, v);
+ v = caml_copy_int64 (f_blocks);
+ Store_field (rv, 2, v);
+ v = caml_copy_int64 (f_bfree);
+ Store_field (rv, 3, v);
+ v = caml_copy_int64 (f_bavail);
+ Store_field (rv, 4, v);
+ v = caml_copy_int64 (f_files);
+ Store_field (rv, 5, v);
+ v = caml_copy_int64 (f_ffree);
+ Store_field (rv, 6, v);
+ v = caml_copy_int64 (f_favail);
+ Store_field (rv, 7, v);
+ v = caml_copy_int64 (f_fsid);
+ Store_field (rv, 8, v);
+ v = caml_copy_int64 (f_flag);
+ Store_field (rv, 9, v);
+ v = caml_copy_int64 (f_namemax);
+ Store_field (rv, 10, v);
+ v = caml_copy_int64 (f_type);
+ Store_field (rv, 11, v);
CAMLreturn (rv);
}
diff --git a/common/mlutils/unix_utils.ml b/common/mlutils/unix_utils.ml
index b135bcaee..3eb3ac890 100644
--- a/common/mlutils/unix_utils.ml
+++ b/common/mlutils/unix_utils.ml
@@ -16,6 +16,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*)
+open Std_utils
+
module Dev_t = struct
external makedev : int -> int -> int =
"guestfs_int_mllib_dev_t_makedev" "noalloc"
external major : int -> int = "guestfs_int_mllib_dev_t_major"
"noalloc"
@@ -61,6 +63,22 @@ module Realpath = struct
end
module StatVFS = struct
- external free_space : string -> int64 =
- "guestfs_int_mllib_statvfs_free_space"
+ type statvfs = {
+ f_bsize : int64;
+ f_frsize : int64;
+ f_blocks : int64;
+ f_bfree : int64;
+ f_bavail : int64;
+ f_files : int64;
+ f_ffree : int64;
+ f_favail : int64;
+ f_fsid : int64;
+ f_flag : int64;
+ f_namemax : int64;
+ f_type : int64;
+ }
+ external statvfs : string -> statvfs =
+ "guestfs_int_mllib_statvfs_statvfs"
+
+ let free_space { f_bsize = bsize; f_bavail = bavail } = bsize *^ bavail
end
diff --git a/common/mlutils/unix_utils.mli b/common/mlutils/unix_utils.mli
index f4f8ca578..385791cac 100644
--- a/common/mlutils/unix_utils.mli
+++ b/common/mlutils/unix_utils.mli
@@ -94,7 +94,29 @@ module Realpath : sig
end
module StatVFS : sig
- val free_space : string -> int64
- (** [free_space path] returns the free space available on the
+ type statvfs = {
+ f_bsize : int64; (** Filesystem block size *)
+ f_frsize : int64; (** Fragment size *)
+ f_blocks : int64; (** Size of fs in f_frsize units *)
+ f_bfree : int64; (** Number of free blocks *)
+ f_bavail : int64; (** Number of free blocks for non-root *)
+ f_files : int64; (** Number of inodes *)
+ f_ffree : int64; (** Number of free inodes *)
+ f_favail : int64; (** Number of free inodes for non-root *)
+ f_fsid : int64; (** Filesystem ID *)
+ f_flag : int64; (** Mount flags *)
+ f_namemax : int64; (** Maximum length of filenames *)
+ f_type : int64; (** Type of filesystem (see statfs(2)) *)
+ }
+ val statvfs : string -> statvfs
+ (** This is a combination of [statvfs(3)] and one extra field from
+ [statfs(2)]. The main fields are returned by calling [statvfs(3)]
+ on the given path. The [f_type] field is returned from [statfs(2)].
+
+ In case of non-Linux or non-POSIX, this call is emulated as best
+ we can with missing fields returned as [-1]. *)
+
+ val free_space : statvfs -> int64
+ (** [free_space (statvfs path)] returns the free space available on the
filesystem that contains [path], in bytes. *)
end
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 61cfb5caa..070fe4ddc 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -154,7 +154,6 @@ guestfsd_SOURCES = \
sleuthkit.c \
squashfs.c \
stat.c \
- statvfs.c \
strings.c \
structs-cleanups.c \
structs-cleanups.h \
@@ -274,6 +273,7 @@ SOURCES_MLI = \
optgroups.mli \
parted.mli \
realpath.mli \
+ statvfs.mli \
structs.mli \
sysroot.mli \
utils.mli
@@ -300,6 +300,7 @@ SOURCES_ML = \
parted.ml \
listfs.ml \
realpath.ml \
+ statvfs.ml \
inspect_types.ml \
inspect_utils.ml \
inspect_fs_unix_fstab.ml \
@@ -348,8 +349,10 @@ camldaemon.o: $(OBJECTS)
$(OCAMLFIND) $(BEST) -output-obj -o $@ \
$(OCAMLFLAGS) $(OCAMLPACKAGES) \
-linkpkg \
- mlaugeas.$(MLARCHIVE) mlpcre.$(MLARCHIVE) \
- mlcutils.$(MLARCHIVE) mlstdutils.$(MLARCHIVE) \
+ mlaugeas.$(MLARCHIVE) \
+ mlpcre.$(MLARCHIVE) \
+ mlstdutils.$(MLARCHIVE) \
+ mlcutils.$(MLARCHIVE) \
$(OBJECTS)
# OCaml dependencies.
@@ -399,8 +402,8 @@ endif
OCAMLLINKFLAGS = \
mlpcre.$(MLARCHIVE) \
- mlcutils.$(MLARCHIVE) \
mlstdutils.$(MLARCHIVE) \
+ mlcutils.$(MLARCHIVE) \
mlaugeas.$(MLARCHIVE) \
$(LINK_CUSTOM_OCAMLC_ONLY)
diff --git a/daemon/statvfs.c b/daemon/statvfs.c
deleted file mode 100644
index 987537d1f..000000000
--- a/daemon/statvfs.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* libguestfs - the guestfsd daemon
- * Copyright (C) 2009 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <config.h>
-
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdint.h>
-
-#ifdef HAVE_SYS_STATVFS_H
-#include <sys/statvfs.h>
-#endif
-
-#include <fsusage.h>
-
-#include "guestfs_protocol.h"
-#include "daemon.h"
-#include "actions.h"
-
-guestfs_int_statvfs *
-do_statvfs (const char *path)
-{
-#ifdef HAVE_STATVFS
- int r;
- guestfs_int_statvfs *ret;
- struct statvfs statbuf;
-
- CHROOT_IN;
- r = statvfs (path, &statbuf);
- CHROOT_OUT;
-
- if (r == -1) {
- reply_with_perror ("statvfs");
- return NULL;
- }
-
- ret = malloc (sizeof *ret);
- if (ret == NULL) {
- reply_with_perror ("malloc");
- return NULL;
- }
-
- ret->bsize = statbuf.f_bsize;
- ret->frsize = statbuf.f_frsize;
- ret->blocks = statbuf.f_blocks;
- ret->bfree = statbuf.f_bfree;
- ret->bavail = statbuf.f_bavail;
- ret->files = statbuf.f_files;
- ret->ffree = statbuf.f_ffree;
- ret->favail = statbuf.f_favail;
- ret->fsid = statbuf.f_fsid;
- ret->flag = statbuf.f_flag;
- ret->namemax = statbuf.f_namemax;
-
- return ret;
-
-#else /* !HAVE_STATVFS */
-# if WIN32
-
- CLEANUP_FREE char *disk = NULL;
- guestfs_int_statvfs *ret;
- ULONGLONG free_bytes_available; /* for user - similar to bavail */
- ULONGLONG total_number_of_bytes;
- ULONGLONG total_number_of_free_bytes; /* for everyone - bfree */
-
- disk = sysroot_path (path);
- if (!disk) {
- reply_with_perror ("malloc");
- return NULL;
- }
-
- if (!GetDiskFreeSpaceEx (disk,
- (PULARGE_INTEGER) &free_bytes_available,
- (PULARGE_INTEGER) &total_number_of_bytes,
- (PULARGE_INTEGER) &total_number_of_free_bytes)) {
- reply_with_perror ("GetDiskFreeSpaceEx");
- return NULL;
- }
-
- ret = malloc (sizeof *ret);
- if (ret == NULL) {
- reply_with_perror ("malloc");
- return NULL;
- }
-
- /* XXX I couldn't determine how to get block size. MSDN has a
- * unhelpful hard-coded list here:
- *
http://support.microsoft.com/kb/140365
- * but this depends on the filesystem type, the size of the disk and
- * the version of Windows. So this code assumes the disk is NTFS
- * and the version of Windows is >= Win2K.
- */
- if (total_number_of_bytes < UINT64_C (16) * 1024 * 1024 * 1024 * 1024)
- ret->bsize = 4096;
- else if (total_number_of_bytes < UINT64_C (32) * 1024 * 1024 * 1024 * 1024)
- ret->bsize = 8192;
- else if (total_number_of_bytes < UINT64_C (64) * 1024 * 1024 * 1024 * 1024)
- ret->bsize = 16384;
- else if (total_number_of_bytes < UINT64_C (128) * 1024 * 1024 * 1024 * 1024)
- ret->bsize = 32768;
- else
- ret->bsize = 65536;
-
- /* As with stat, -1 indicates a field is not known. */
- ret->frsize = ret->bsize;
- ret->blocks = total_number_of_bytes / ret->bsize;
- ret->bfree = total_number_of_free_bytes / ret->bsize;
- ret->bavail = free_bytes_available / ret->bsize;
- ret->files = -1;
- ret->ffree = -1;
- ret->favail = -1;
- ret->fsid = -1;
- ret->flag = -1;
- ret->namemax = FILENAME_MAX;
-
- return ret;
-
-# else /* !WIN32 */
-
- CLEANUP_FREE char *disk = NULL;
- int r;
- guestfs_int_statvfs *ret;
- struct fs_usage fsu;
-
- disk = sysroot_path (path);
- if (!disk) {
- reply_with_perror ("malloc");
- return NULL;
- }
-
- r = get_fs_usage (disk, disk, &fsu);
-
- if (r == -1) {
- reply_with_perror ("get_fs_usage: %s", path);
- return NULL;
- }
-
- ret = malloc (sizeof *ret);
- if (ret == NULL) {
- reply_with_perror ("malloc");
- return NULL;
- }
-
- /* As with stat, -1 indicates a field is not known. */
- ret->bsize = fsu.f_bsize;
- ret->frsize = -1;
- ret->blocks = fsu.f_blocks;
- ret->bfree = fsu.f_bfree;
- ret->bavail = fsu.f_bavail;
- ret->files = fsu.f_files;
- ret->ffree = fsu.f_ffree;
- ret->favail = -1;
- ret->fsid = -1;
- ret->flag = -1;
- ret->namemax = -1;
-
- return ret;
-
-# endif /* !WIN32 */
-#endif /* !HAVE_STATVFS */
-}
diff --git a/daemon/statvfs.ml b/daemon/statvfs.ml
new file mode 100644
index 000000000..9e1ad7ec9
--- /dev/null
+++ b/daemon/statvfs.ml
@@ -0,0 +1,43 @@
+(* guestfs-inspection
+ * Copyright (C) 2009-2017 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+open Unix_utils
+
+include Structs
+
+let statvfs path =
+ let chroot = Chroot.create ~name:(Printf.sprintf "statvfs: %s" path) () in
+ let r = Chroot.f chroot Unix_utils.StatVFS.statvfs path in
+
+ (* [r : Unix_utils.StatVFS.statvfs] is superficially similar to
+ * the guestfs [statvfs] structure, but not the same. We have to
+ * copy the fields.
+ *)
+ {
+ bsize = r.f_bsize;
+ frsize = r.f_frsize;
+ blocks = r.f_blocks;
+ bfree = r.f_bfree;
+ bavail = r.f_bavail;
+ files = r.f_files;
+ ffree = r.f_ffree;
+ favail = r.f_favail;
+ fsid = r.f_fsid;
+ flag = r.f_flag;
+ namemax = r.f_namemax;
+ }
diff --git a/daemon/statvfs.mli b/daemon/statvfs.mli
new file mode 100644
index 000000000..163ea9a15
--- /dev/null
+++ b/daemon/statvfs.mli
@@ -0,0 +1,33 @@
+(* guestfs-inspection
+ * Copyright (C) 2009-2017 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+type statvfs = {
+ bsize : int64;
+ frsize : int64;
+ blocks : int64;
+ bfree : int64;
+ bavail : int64;
+ files : int64;
+ ffree : int64;
+ favail : int64;
+ fsid : int64;
+ flag : int64;
+ namemax : int64;
+}
+
+val statvfs : string -> statvfs
diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
index 41bb6c9eb..f3ee61e0d 100644
--- a/docs/C_SOURCE_FILES
+++ b/docs/C_SOURCE_FILES
@@ -166,7 +166,6 @@ daemon/sleep.c
daemon/sleuthkit.c
daemon/squashfs.c
daemon/stat.c
-daemon/statvfs.c
daemon/strings.c
daemon/structs-cleanups.c
daemon/structs-cleanups.h
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 81cb99ea8..604620673 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -2319,6 +2319,7 @@ See also: C<guestfs_sh_lines>" };
{ defaults with
name = "statvfs"; added = (1, 9, 2);
style = RStruct ("statbuf", "statvfs"), [String (Pathname,
"path")], [];
+ impl = OCaml "Statvfs.statvfs";
tests = [
InitISOFS, Always, TestResult (
[["statvfs"; "/"]], "ret->namemax == 255"), []
diff --git a/m4/guestfs_libraries.m4 b/m4/guestfs_libraries.m4
index b8fa1446a..a3b730572 100644
--- a/m4/guestfs_libraries.m4
+++ b/m4/guestfs_libraries.m4
@@ -48,10 +48,12 @@ AC_CHECK_HEADERS([\
sys/inotify.h \
sys/resource.h \
sys/socket.h \
+ sys/statfs.h \
sys/statvfs.h \
sys/time.h \
sys/types.h \
sys/un.h \
+ sys/vfs.h \
sys/wait.h \
windows.h \
sys/xattr.h])
@@ -59,6 +61,8 @@ AC_CHECK_HEADERS([\
dnl Functions.
AC_CHECK_FUNCS([\
be32toh \
+ fstatfs \
+ fstatvfs \
fsync \
futimens \
getxattr \
@@ -80,7 +84,6 @@ AC_CHECK_FUNCS([\
setrlimit \
setxattr \
sigaction \
- statvfs \
sync])
dnl Which header file defines major, minor, makedev.
diff --git a/po/POTFILES b/po/POTFILES
index 40c0708a0..a049d66fe 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -149,7 +149,6 @@ daemon/sleep.c
daemon/sleuthkit.c
daemon/squashfs.c
daemon/stat.c
-daemon/statvfs.c
daemon/strings.c
daemon/structs-cleanups.c
daemon/stubs-0.c
diff --git a/sparsify/copying.ml b/sparsify/copying.ml
index 7d004b550..0c0b27c94 100644
--- a/sparsify/copying.ml
+++ b/sparsify/copying.ml
@@ -99,7 +99,7 @@ let run indisk outdisk check_tmpdir compress convert
virtual_size (human_size virtual_size);
let print_warning () =
- let free_space = StatVFS.free_space tmpdir in
+ let free_space = StatVFS.free_space (StatVFS.statvfs tmpdir) in
let extra_needed = virtual_size -^ free_space in
if extra_needed > 0L then (
warning (f_"\
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 74ba66a3d..f54838e5e 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -272,7 +272,7 @@ and overlay_dir = (open_guestfs ())#get_cachedir ()
* guestfs appliance which is also stored here.
*)
and check_host_free_space () =
- let free_space = StatVFS.free_space overlay_dir in
+ let free_space = StatVFS.free_space (StatVFS.statvfs overlay_dir) in
debug "check_host_free_space: overlay_dir=%s free_space=%Ld"
overlay_dir free_space;
if free_space < 1_073_741_824L then
--
2.13.2