cmogstored dev/user discussion/issues/patches/etc
 help / color / mirror / code / Atom feed
From: Eric Wong <e@80x24.org>
To: cmogstored-public@yhbt.net
Subject: [RFC] dev.c: emit usage for devices with unknown mount point
Date: Mon, 20 Jul 2020 08:51:19 +0000	[thread overview]
Message-ID: <20200720085119.11067-1-e@80x24.org> (raw)

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;

                 reply	other threads:[~2020-07-20  8:51 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://yhbt.net/cmogstored/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200720085119.11067-1-e@80x24.org \
    --to=e@80x24.org \
    --cc=cmogstored-public@yhbt.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://yhbt.net/cmogstored.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).