From fc2f3298da5ad3496ff2ae7c1f6b5b5c4327decd Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 20 Jul 2020 03:36:48 +0000 Subject: dev.c: emit usage for devices with unknown mount point 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. --- cmogstored.h | 1 + dev.c | 91 ++++++++++++++++++++++++++++++------------------------------ 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; -- cgit v1.2.3-24-ge0c7