Author: ngie
Date: Fri Apr 14 19:41:48 2017
New Revision: 316938
URL: https://svnweb.freebsd.org/changeset/base/316938

Log:
  savecore: fix space calculation with respect to `minfree` in check_space(..)
  
  - Use strtoll(3) instead of atoi(3), because atoi(3) limits the
    representable data to INT_MAX. Check the values received from
    strtoll(3), trimming trailing whitespace off the end to maintain
    POLA.
  - Use `KiB` instead of `kB` when describing free space, total space,
    etc. I am now fully aware of `KiB` being the IEC standard for 1024
    bytes and `kB` being the IEC standard for 1000 bytes.
  - Store available number of KiB in `available` so it can be more
    easily queried and compared to ensure that there are enough KiB to
    store the dump image on disk.
  - Print out the reserved space on disk, per `minfree`, so end-users
    can troubleshoot why check_space(..) is reporting that there isn't
    enough free space.
  
  MFC after:    7 weeks
  Reviewed by:  Anton Rang <r...@acm.com> (earlier diff), cem (earlier diff)
  Tested with:  positive/negative cases (see review); make tinderbox
  Sponsored by: Dell EMC Isilon
  Differential Revision:        D10379

Modified:
  head/sbin/savecore/savecore.c

Modified: head/sbin/savecore/savecore.c
==============================================================================
--- head/sbin/savecore/savecore.c       Fri Apr 14 19:18:50 2017        
(r316937)
+++ head/sbin/savecore/savecore.c       Fri Apr 14 19:41:48 2017        
(r316938)
@@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kerneldump.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <fstab.h>
@@ -278,7 +279,7 @@ static int
 check_space(const char *savedir, off_t dumpsize, int bounds)
 {
        FILE *fp;
-       off_t minfree, spacefree, totfree, needed;
+       off_t available, minfree, spacefree, totfree, needed;
        struct statfs fsbuf;
        char buf[100];
 
@@ -294,19 +295,37 @@ check_space(const char *savedir, off_t d
        else {
                if (fgets(buf, sizeof(buf), fp) == NULL)
                        minfree = 0;
-               else
-                       minfree = atoi(buf);
+               else {
+                       char *endp;
+
+                       errno = 0;
+                       minfree = strtoll(buf, &endp, 10);
+                       if (minfree == 0 && errno != 0)
+                               minfree = -1;
+                       else {
+                               while (*endp != '\0' && isspace(*endp))
+                                       endp++;
+                               if (*endp != '\0' || minfree < 0)
+                                       minfree = -1;
+                       }
+                       if (minfree < 0)
+                               syslog(LOG_WARNING,
+                                   "`minfree` didn't contain a valid size "
+                                   "(`%s`). Defaulting to 0", buf);
+               }
                (void)fclose(fp);
        }
 
+       available = minfree > 0 ? spacefree - minfree : totfree;
        needed = dumpsize / 1024 + 2;   /* 2 for info file */
        needed -= saved_dump_size(bounds);
-       if ((minfree > 0 ? spacefree : totfree) - needed < minfree) {
+       if (available < needed) {
                syslog(LOG_WARNING,
-                   "no dump: not enough free space on device (%lldkB "
-                   "available; need at least %lldkB)",
-                   (long long)(minfree > 0 ? spacefree : totfree),
-                   (long long)needed);
+                   "no dump: not enough free space on device (need at least "
+                   "%jdKiB for dump; %jdKiB available; %jdKiB reserved)",
+                   (intmax_t)needed,
+                   (intmax_t)available + minfree,
+                   (intmax_t)minfree);
                return (0);
        }
        if (spacefree - needed < 0)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to