about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2020-07-20 03:36:48 +0000
committerEric Wong <e@80x24.org>2020-08-09 03:12:31 +0000
commitfc2f3298da5ad3496ff2ae7c1f6b5b5c4327decd (patch)
tree6e3bde8f3a5d994b94d2b9c0403f3c640b255e4e
parentd7626e6cd2e71ab3587d3facc561187d8f94afa4 (diff)
downloadcmogstored-fc2f3298da5ad3496ff2ae7c1f6b5b5c4327decd.tar.gz
LUKS + btrfs on Linux gives an .st_rdev value of `0', so we
can't reliably figure out what the "device:" field in
/devXX/usage should be without parsing /proc/partitions.

Since MogileFS::Worker::Monitor only cares about the "used:" and
"total:" fields, we'll just emit "(?)" in the device field.  The
effort of parsing /proc/partitions to correctly display a field
that our only known consumer won't use is a waste of our time.
-rw-r--r--cmogstored.h1
-rw-r--r--dev.c91
2 files changed, 47 insertions, 45 deletions
diff --git a/cmogstored.h b/cmogstored.h
index 081ffbf..35ddc73 100644
--- a/cmogstored.h
+++ b/cmogstored.h
@@ -108,6 +108,7 @@ struct mog_ioq {
 struct mog_wbuf;
 struct mog_dev {
         dev_t st_dev;
+        unsigned no_me_warned : 1;
         uint32_t devid;
         pthread_mutex_t usage_lock; /* protects usage_txt */
         unsigned usage_len;
diff --git a/dev.c b/dev.c
index b149619..c120736 100644
--- a/dev.c
+++ b/dev.c
@@ -33,6 +33,7 @@ static struct mog_dev *mog_dev_new(struct mog_svc *svc, uint32_t mog_devid)
         dev->st_dev = sb.st_dev;
         mog_ioq_init(&dev->fsckq, svc, 1);
         mog_ioq_init(&dev->ioq, svc, svc->thr_per_dev);
+        dev->no_me_warned = 0;
         dev->usage_txt = 0;
         dev->usage_len = 0;
         dev->usage_mtime = 0;
@@ -122,6 +123,15 @@ emit_usage(struct mog_dev *dev, struct mog_svc *svc, int fd, struct statvfs *v)
         long long now = (long long)time(NULL);
         long double mb = v->f_frsize / (long double)1024.0;
         const struct mount_entry *me;
+        char *usage_txt;
+        static const char usage_fmt[] =
+                "available: %llu\n"
+                "device: %s\n"
+                "disk: %s/dev%u\n"
+                "time: %lld\n"
+                "total: %llu\n"
+                "use: %u%%\n"
+                "used: %llu\n";
 
         available *= mb;
         total *= mb;
@@ -131,53 +141,44 @@ emit_usage(struct mog_dev *dev, struct mog_svc *svc, int fd, struct statvfs *v)
                 use = 100;
 
         me = mog_mnt_acquire(dev->st_dev);
-        if (me) {
-                char *usage_txt;
-                static const char usage_fmt[] =
-                        "available: %llu\n"
-                        "device: %s\n"
-                        "disk: %s/dev%u\n"
-                        "time: %lld\n"
-                        "total: %llu\n"
-                        "use: %u%%\n"
-                        "used: %llu\n";
-
-                errno = 0;
-                rc = asprintf(&usage_txt, usage_fmt,
-                             available, me->me_devname, svc->docroot,
-                             (unsigned)dev->devid, now, total, use, used);
-                if (rc > 0) {
-                        char *old_usage;
-
-                        CHECK(int, 0, pthread_mutex_lock(&dev->usage_lock));
-                        old_usage = dev->usage_txt;
-                        dev->usage_txt = usage_txt;
-                        dev->usage_len = rc;
-                        dev->usage_mtime = (time_t)now;
-                        CHECK(int, 0, pthread_mutex_unlock(&dev->usage_lock));
-
-                        free(old_usage);
-                        if (fd >= 0) {
-                                ssize_t w = write(fd, usage_txt, rc);
-
-                                if (w >= 0 && w != rc)
-                                        errno = ENOSPC;
-                                else if (w < 0)
-                                        rc = -1;
-                        }
-                }
-
-                PRESERVE_ERRNO( mog_mnt_release(me) );
-                if (rc < 0 || errno == ENOSPC) {
-                        PRESERVE_ERRNO(do {
-                                syslog(LOG_ERR, "write(%s/dev%u/usage): %m",
-                                       svc->docroot, (unsigned)dev->devid);
-                        } while (0));
-                }
-        } else {
+        if (!me && !dev->no_me_warned) {
                 syslog(LOG_ERR, "mount entry not found for %s/dev%u",
                        svc->docroot, (unsigned)dev->devid);
-                errno = ENODEV;
+                dev->no_me_warned = 1;
+        }
+        errno = 0;
+        rc = asprintf(&usage_txt, usage_fmt, available,
+                        /* device:, MogileFS::Worker::Monitor doesn't care: */
+                        me ? me->me_devname : "(?)",
+                        svc->docroot,
+                        (unsigned)dev->devid, now, total, use, used);
+        if (rc > 0) {
+                char *old_usage;
+
+                CHECK(int, 0, pthread_mutex_lock(&dev->usage_lock));
+                old_usage = dev->usage_txt;
+                dev->usage_txt = usage_txt;
+                dev->usage_len = rc;
+                dev->usage_mtime = (time_t)now;
+                CHECK(int, 0, pthread_mutex_unlock(&dev->usage_lock));
+
+                free(old_usage);
+                if (fd >= 0) {
+                        ssize_t w = write(fd, usage_txt, rc);
+
+                        if (w >= 0 && w != rc)
+                                errno = ENOSPC;
+                        else if (w < 0)
+                                rc = -1;
+                }
+        }
+        if (me)
+                PRESERVE_ERRNO( mog_mnt_release(me) );
+        if (rc < 0 || errno == ENOSPC) {
+                PRESERVE_ERRNO(do {
+                        syslog(LOG_ERR, "write(%s/dev%u/usage): %m",
+                               svc->docroot, (unsigned)dev->devid);
+                } while (0));
         }
 
         return rc;