]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Make disk free space reporting consistent with Linux 'df' command.
authorOliver Kurth <okurth@vmware.com>
Mon, 23 Oct 2017 21:21:22 +0000 (14:21 -0700)
committerOliver Kurth <okurth@vmware.com>
Mon, 23 Oct 2017 21:21:22 +0000 (14:21 -0700)
On Linux, statfs syscall reports free space in two fields.
From http://man7.org/linux/man-pages/man2/statfs.2.html:
1. f_bfree => Free blocks in filesystem
2. f_bavail => Free blocks available to unprivileged user

For file systems that maintain reserved space for system
activities f_bfree > f_bavail because f_bfree includes the
reserved space in the file system. The reserved space is
typically 5% for 'ext4' file systems. Newer distros like
RHEL 7.x use 'xfs' by default and report same value for
both the fields.

The Linux 'df' command uses f_bavail in its reporting.
Tools reports, conditionally, f_bfree for root and f_bavail
for non-root.  However, since vmtoolsd runs as root, Tools
always reports f_bfree, which is more free space than 'df'
would report (depending on amount of reserved space).

In order to be consistent with Linux 'df' command,
report f_bavail as the disk free space by default. This does
change the behavior a little bit in that Tools will report less
disk free space than before, the difference being the same as
the reserved space on the file system, typically 5%. This
should be OK in general because it makes the space reporting
a bit conservative. If this change in behavior is not desired
for some use cases, the old behavior can be restored by setting
the following newly added configuration in this change:

[guestinfo]
diskinfo-include-reserved=true

The existing callers that are outside the guestInfo plugin
will continue to include reserved space in their space
accounting as before.

Also fixed a few minor stuff/touchups in vmtoolsConfig.c.

open-vm-tools/lib/hgfsServer/hgfsServer.c
open-vm-tools/lib/include/conf.h
open-vm-tools/lib/include/vmware/tools/utils.h
open-vm-tools/lib/include/wiper.h
open-vm-tools/lib/wiper/wiperPosix.c
open-vm-tools/libvmtools/vmtoolsConfig.c
open-vm-tools/services/plugins/guestInfo/diskInfo.c
open-vm-tools/services/plugins/guestInfo/diskInfoPosix.c
open-vm-tools/services/plugins/guestInfo/guestInfoInt.h
open-vm-tools/services/plugins/guestInfo/guestInfoServer.c

index 88c533cfcdb6e8702da83c1f84ee4261220fa730..b942653e393fbfa3886f251117570a3ec08ca1e3 100644 (file)
@@ -5417,7 +5417,7 @@ HgfsServerStatFs(const char *pathName, // IN: Path we're interested in
 
    /* Now call the wiper lib to get space information. */
    Str_Strcpy(p.mountPoint, pathName, sizeof p.mountPoint);
-   wiperError = WiperSinglePartition_GetSpace(&p, freeBytes, totalBytes);
+   wiperError = WiperSinglePartition_GetSpace(&p, NULL, freeBytes, totalBytes);
    if (strlen(wiperError) > 0) {
       LOG(4, ("%s: error using wiper lib: %s\n", __FUNCTION__, wiperError));
 
index d6da7e339f2f2f059a67d7de2d7cf15fb57a670c..5f3f701a7f69269d300226810669d07fc9a6eb0e 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2002-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2002-2017 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -16,7 +16,6 @@
  *
  *********************************************************/
 
-
 /*
  * conf.h --
  *
 #define CONFGROUPNAME_GUESTINFO "guestinfo"
 
 /**
- * Lets users disable just the perf monitor.
+ * Lets user disable just the perf monitor.
  */
 #define CONFNAME_GUESTINFO_DISABLEPERFMON "disable-perf-mon"
 
 /**
- * Lets users disable just DiskInfo.
+ * Lets user disable just DiskInfo.
  *
  * If thinking of deprecating this, please read bug 535343 first.
  */
 
 #define CONFNAME_GUESTINFO_EXCLUDENICS "exclude-nics"
 
+/**
+ * Lets user include reserved space in diskInfo space metrics on Linux.
+ *
+ * @param boolean Set to true to include reserved space.
+ */
+#define CONFNAME_DISKINFO_INCLUDERESERVED "diskinfo-include-reserved"
+
 /*
  * END GuestInfo goodies.
  ******************************************************************************
index b5968a432098499186c98c613882445ea3a8ae91..c0bfd3e215d28613ba0479bd1c4cf5215fe23b5c 100644 (file)
@@ -129,19 +129,19 @@ gboolean
 VMTools_ConfigGetBoolean(GKeyFile *config,
                          const gchar *section,
                          const gchar *key,
-                         gboolean defValue);
+                         const gboolean defValue);
 
 gint
 VMTools_ConfigGetInteger(GKeyFile *config,
                          const gchar *section,
                          const gchar *key,
-                         gint defValue);
+                         const gint defValue);
 
 gchar *
 VMTools_ConfigGetString(GKeyFile *config,
                         const gchar *section,
                         const gchar *key,
-                        gchar *defValue);
+                        const gchar *defValue);
 
 #if defined(G_PLATFORM_WIN32)
 
index 6eafb69cd0455c391234af146ccc1c3b34613cc7..d16972d6d4539dc3b5840d9a5da60609a5673faa 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2004-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2017 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -105,8 +105,9 @@ void WiperSinglePartition_Close(WiperPartition *);
 Bool Wiper_IsWipeSupported(const WiperPartition *);
 
 unsigned char *WiperSinglePartition_GetSpace(const WiperPartition *p,
-                              uint64 *free,
-                              uint64 *total);
+                                             uint64 *avail,
+                                             uint64 *free,
+                                             uint64 *total);
 
 /* External definition of the wiper state */
 struct Wiper_State;
index 8300dba0a931c971e539e4418de5c907a0c8d8ad..9dcc38733b837913ce9a62a14e95df5bcc99490c 100644 (file)
@@ -568,9 +568,10 @@ WiperSinglePartition_Open(const char *mountPoint)      // IN
  */
 
 unsigned char *
-WiperSinglePartition_GetSpace(const WiperPartition *p,  // IN
-                              uint64 *free,       // OUT
-                              uint64 *total)      // OUT
+WiperSinglePartition_GetSpace(const WiperPartition *p, // IN
+                              uint64 *avail,           // OUT/OPT
+                              uint64 *free,            // OUT/OPT
+                              uint64 *total)           // OUT
 {
 #ifdef sun
    struct statvfs statfsbuf;
@@ -595,11 +596,32 @@ WiperSinglePartition_GetSpace(const WiperPartition *p,  // IN
    blockSize = statfsbuf.f_bsize;
 #endif
 
-   if (geteuid()== 0) {
-      *free = (uint64)statfsbuf.f_bfree * blockSize;
-   } else {
-      *free = (uint64)statfsbuf.f_bavail * blockSize;
+   if (avail) {
+      /*
+       * Free blocks available to non-superuser users.
+       * This excludes reserved blocks. Mostly applicable
+       * to 'ext' file systems. Newer file systems like
+       * 'xfs' report same value for f_bavail and f_bfree.
+       */
+      *avail = (uint64)statfsbuf.f_bavail * blockSize;
+   }
+
+   if (free) {
+      if (geteuid()== 0) {
+         /*
+          * Free blocks in the file system. This includes
+          * the reserved blocks too.
+          */
+         *free = (uint64)statfsbuf.f_bfree * blockSize;
+      } else {
+         /*
+          * Free blocks available to non-superuser users.
+          * This excludes reserved blocks.
+          */
+         *free = (uint64)statfsbuf.f_bavail * blockSize;
+      }
    }
+
    *total = (uint64)statfsbuf.f_blocks * blockSize;
 
    return "";
@@ -757,7 +779,7 @@ WiperGetSpace(WiperState *state,  // IN
               uint64 *total)      // OUT
 {
    ASSERT(state);
-   return WiperSinglePartition_GetSpace(state->p, free, total);
+   return WiperSinglePartition_GetSpace(state->p, NULL, free, total);
 }
 
 
index 874580703995fb175eea065cb8d7aab2920f2a75..c41e3dc751cb381d68abd3df5a2d9790b851b953 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2008-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2008-2017 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -538,6 +538,7 @@ exit:
  *
  * @param[in]  config   Config file to read the key from.
  * @param[in]  section  Section to look for in the config file.
+ * @param[in]  key      Key to look for in the section.
  * @param[in]  defValue Default value if the key is not found or error.
  *
  * @return value of the key if value was read successfully, else defValue.
@@ -547,7 +548,7 @@ gboolean
 VMTools_ConfigGetBoolean(GKeyFile *config,
                          const gchar *section,
                          const gchar *key,
-                         gboolean defValue)
+                         const gboolean defValue)
 {
    GError *err = NULL;
    gboolean value;
@@ -580,6 +581,7 @@ VMTools_ConfigGetBoolean(GKeyFile *config,
  *
  * @param[in]  config   Config file to read the key from.
  * @param[in]  section  Section to look for in the config file.
+ * @param[in]  key      Key to look for in the section.
  * @param[in]  defValue Default value if the key is not found or error.
  *
  * @return value of the key if value was read successfully, else defValue.
@@ -589,7 +591,7 @@ gint
 VMTools_ConfigGetInteger(GKeyFile *config,
                          const gchar *section,
                          const gchar *key,
-                         gint defValue)
+                         const gint defValue)
 {
    GError *err = NULL;
    gint value;
@@ -619,6 +621,7 @@ VMTools_ConfigGetInteger(GKeyFile *config,
  *
  * @param[in]  config   Config file to read the key from.
  * @param[in]  section  Section to look for in the config file.
+ * @param[in]  key      Key to look for in the section.
  * @param[in]  defValue Default value if the key is not found or error.
  *
  * @return value of the key if value was read successfully, else a copy
@@ -630,7 +633,7 @@ gchar *
 VMTools_ConfigGetString(GKeyFile *config,
                         const gchar *section,
                         const gchar *key,
-                        gchar *defValue)
+                        const gchar *defValue)
 {
    GError *err = NULL;
    gchar *value;
index 35dd682fadc4dd0801f4570d2d08b2e3b767e89f..7b236881e6be40758e2324556841df8e336bea47 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2014-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2014-2017 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -78,7 +78,7 @@ GuestInfo_FreeDiskInfo(GuestDiskInfo *di)
  */
 
 GuestDiskInfo *
-GuestInfoGetDiskInfoWiper(void)
+GuestInfoGetDiskInfoWiper(Bool includeReserved)  // IN
 {
    WiperPartition_List pl;
    DblLnkLst_Links *curr;
@@ -105,11 +105,16 @@ GuestInfoGetDiskInfoWiper(void)
          PPartitionEntry newPartitionList;
          PPartitionEntry partEntry;
          unsigned char *error;
-
-         error = WiperSinglePartition_GetSpace(part, &freeBytes, &totalBytes);
+         if (includeReserved) {
+            error = WiperSinglePartition_GetSpace(part, NULL,
+                                                  &freeBytes, &totalBytes);
+         } else {
+            error = WiperSinglePartition_GetSpace(part, &freeBytes,
+                                                  NULL, &totalBytes);
+         }
          if (strlen(error)) {
-            g_warning("GetDiskInfo: ERROR: could not get space for partition %s: %s\n",
-                    part->mountPoint, error);
+            g_warning("GetDiskInfo: ERROR: could not get space info for "
+                      "partition %s: %s\n", part->mountPoint, error);
             goto out;
          }
 
index dc23e6bf9055fd2cbcce1515d6ee20fdd6ab07aa..625c9883053cb61f0167337b1092dbaad1685fb6 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2014-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2014-2017 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -22,6 +22,7 @@
  * Contains POSIX-specific bits of gettting disk information.
  */
 
+#include "conf.h"
 #include "util.h"
 #include "vmware.h"
 #include "guestInfoInt.h"
  */
 
 GuestDiskInfo *
-GuestInfo_GetDiskInfo(void)
+GuestInfo_GetDiskInfo(const ToolsAppCtx *ctx)
 {
-   return GuestInfoGetDiskInfoWiper();
+   gboolean includeReserved;
+
+   /*
+    * In order to be consistent with the way 'df' reports
+    * disk free space, we don't include the reserved space
+    * while reporting the disk free space by default.
+    */
+   includeReserved = VMTools_ConfigGetBoolean(ctx->config,
+                                              CONFGROUPNAME_GUESTINFO,
+                                              CONFNAME_DISKINFO_INCLUDERESERVED,
+                                              FALSE);
+   if (includeReserved) {
+      g_debug("Including reserved space in diskInfo stats.\n");
+   } else {
+      g_debug("Excluding reserved space from diskInfo stats.\n");
+   }
+
+   return GuestInfoGetDiskInfoWiper(includeReserved);
 }
index 87443e297effee6f3612d6a95d8f2eb77a6f81ea..ad51119eb572a9ee0d66462510423595e50c3eb7 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2008-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2008-2017 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -42,10 +42,10 @@ gboolean
 GuestInfo_StatProviderPoll(gpointer data);
 
 GuestDiskInfo *
-GuestInfoGetDiskInfoWiper(void);
+GuestInfoGetDiskInfoWiper(Bool includeReserved);
 
 GuestDiskInfo *
-GuestInfo_GetDiskInfo(void);
+GuestInfo_GetDiskInfo(const ToolsAppCtx *ctx);
 
 void
 GuestInfo_FreeDiskInfo(GuestDiskInfo *di);
index 49cab26df37ae3038bcdc2566b3cd64102664089..9b421fd502495c88336f70d5beb6d1b2b591f099 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 1998-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -418,7 +418,7 @@ GuestInfoGather(gpointer data)
       g_key_file_get_boolean(ctx->config, CONFGROUPNAME_GUESTINFO,
                              CONFNAME_GUESTINFO_DISABLEQUERYDISKINFO, NULL);
    if (!disableQueryDiskInfo) {
-      if ((diskInfo = GuestInfo_GetDiskInfo()) == NULL) {
+      if ((diskInfo = GuestInfo_GetDiskInfo(ctx)) == NULL) {
          g_warning("Failed to get disk info.\n");
       } else {
          if (GuestInfoUpdateVmdb(ctx, INFO_DISK_FREE_SPACE, diskInfo, 0)) {