Module Name:    src
Committed By:   martin
Date:           Mon Sep  2 16:16:57 UTC 2019

Modified Files:
        src/lib/libutil [netbsd-9]: getdiskrawname.c
        src/libexec/lfs_cleanerd [netbsd-9]: lfs_cleanerd.8 lfs_cleanerd.c
        src/sbin/resize_lfs [netbsd-9]: resize_lfs.c
        src/tests/fs/common [netbsd-9]: fstest_lfs.c
        src/usr.sbin/puffs/rump_lfs [netbsd-9]: rump_lfs.c

Log Message:
Pull up following revision(s) (requested by brad in ticket #110):

        libexec/lfs_cleanerd/lfs_cleanerd.c: revision 1.59
        libexec/lfs_cleanerd/lfs_cleanerd.8: revision 1.19
        sbin/resize_lfs/resize_lfs.c: revision 1.15
        usr.sbin/puffs/rump_lfs/rump_lfs.c: revision 1.19
        libexec/lfs_cleanerd/lfs_cleanerd.c: revision 1.60
        lib/libutil/getdiskrawname.c: revision 1.6
        tests/fs/common/fstest_lfs.c: revision 1.7

Use getdiskrawname to find the device name.
Reviewed by Christos

 -

Teach getdiskrawname and getdiskcookedname about zvols.
Reviewed by Christos

 -

Add support for passing the raw device name separate from the
filesystem.  This is useful in the case where the cleaner is compiled
into code, such as rump_lfs and the ATF tests.  This helps to fix
bin/54488

 -

The cleaner is compiled into rump_lfs and executed as a thread.  Pass
in the raw device using the new -J option.  This avoids the use of
getdiskrawname which is not particularly rump safe in this context and
insures that the rump container device is used for cleaning, not the
outer device.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.5.18.1 src/lib/libutil/getdiskrawname.c
cvs rdiff -u -r1.18 -r1.18.48.1 src/libexec/lfs_cleanerd/lfs_cleanerd.8
cvs rdiff -u -r1.58 -r1.58.18.1 src/libexec/lfs_cleanerd/lfs_cleanerd.c
cvs rdiff -u -r1.14 -r1.14.18.1 src/sbin/resize_lfs/resize_lfs.c
cvs rdiff -u -r1.6 -r1.6.2.1 src/tests/fs/common/fstest_lfs.c
cvs rdiff -u -r1.18 -r1.18.18.1 src/usr.sbin/puffs/rump_lfs/rump_lfs.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libutil/getdiskrawname.c
diff -u src/lib/libutil/getdiskrawname.c:1.5 src/lib/libutil/getdiskrawname.c:1.5.18.1
--- src/lib/libutil/getdiskrawname.c:1.5	Wed Sep 17 23:54:42 2014
+++ src/lib/libutil/getdiskrawname.c	Mon Sep  2 16:16:56 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: getdiskrawname.c,v 1.5 2014/09/17 23:54:42 christos Exp $	*/
+/*	$NetBSD: getdiskrawname.c,v 1.5.18.1 2019/09/02 16:16:56 martin Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: getdiskrawname.c,v 1.5 2014/09/17 23:54:42 christos Exp $");
+__RCSID("$NetBSD: getdiskrawname.c,v 1.5.18.1 2019/09/02 16:16:56 martin Exp $");
 
 #include <sys/stat.h>
 
@@ -70,10 +70,74 @@ resolve_link(char *buf, size_t bufsiz, c
 	return buf;
 }
 
+/*
+ * zvol device names look like:
+ * /dev/zvol/dsk/pool_name/.../volume_name
+ * /dev/zvol/rdsk/pool_name/.../volume_name
+ *
+ * ZFS pools can be divided nearly to infinity
+ *
+ * This allows for 16 pool names, which one would hope would be enough
+ */
+#define DISKMAXPARTS 20
+static int
+calc_zvol_name(char *buf, size_t bufsiz, const char *name, const char *raw)
+{
+	char copyname[PATH_MAX];
+	char *names[DISKMAXPARTS];
+	char *last, *p;
+	size_t i = 0;
+
+	strlcpy(copyname, name, sizeof(copyname));
+	for (p = strtok_r(copyname, "/", &last); p;
+	     p = strtok_r(NULL, "/", &last)) {
+		if (i >= DISKMAXPARTS) {
+			errno =  ENOSPC;
+			return -1;
+		}
+		names[i++] = p;
+	}
+
+	if (i < 4) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	snprintf(buf, bufsiz, "/dev/zvol/%sdsk", raw);
+	for (size_t j = 3; j < i; j++) {
+		strlcat(buf, "/", bufsiz);
+		strlcat(buf, names[j], bufsiz);
+	}
+	return 0;
+}
+
+static int
+calc_name(char *buf, size_t bufsiz, const char *name, const char *raw)
+{
+	int skip = 1;
+
+	if (strncmp("/dev/zvol/", name, 10) == 0)
+		return calc_zvol_name(buf, bufsiz, name, raw);
+
+	const char *dp = strrchr(name, '/');
+	if (!*raw && ((dp != NULL && dp[1] != 'r')
+		|| (dp == NULL && name[0] != 'r'))) {
+		errno = EINVAL;
+		return -1;
+	}
+	if (raw[0] != 'r')
+		skip = 2;
+	if (dp != NULL)
+		snprintf(buf, bufsiz, "%.*s/%s%s", (int)(dp - name),
+		    name, raw, dp + skip);
+	else
+		snprintf(buf, bufsiz, "%s%s", raw, name);
+	return 0;
+}
+
 const char *
 getdiskrawname(char *buf, size_t bufsiz, const char *name)
 {
-	const char *dp;
 	struct stat st;
 	char dest[PATH_MAX];
 
@@ -82,8 +146,6 @@ getdiskrawname(char *buf, size_t bufsiz,
 		return NULL;
 	}
 
-	dp = strrchr(name, '/');
-
 	if (stat(name, &st) == -1)
 		return NULL;
 
@@ -92,10 +154,8 @@ getdiskrawname(char *buf, size_t bufsiz,
 		return NULL;
 	}
 
-	if (dp != NULL)
-		(void)snprintf(buf, bufsiz, "%.*s/r%s", (int)(dp - name), name, dp + 1);
-	else
-		(void)snprintf(buf, bufsiz, "r%s", name);
+	if (calc_name(buf, bufsiz, name, "r") == -1)
+		return NULL;
 
 	return buf;
 }
@@ -103,7 +163,6 @@ getdiskrawname(char *buf, size_t bufsiz,
 const char *
 getdiskcookedname(char *buf, size_t bufsiz, const char *name)
 {
-	const char *dp;
 	struct stat st;
 	char dest[PATH_MAX];
 
@@ -112,13 +171,6 @@ getdiskcookedname(char *buf, size_t bufs
 		return NULL;
 	}
 
-	dp = strrchr(name, '/');
-
-	if ((dp != NULL && dp[1] != 'r') || (dp == NULL && name[0] != 'r')) {
-		errno = EINVAL;
-		return NULL;
-	}
-
 	if (stat(name, &st) == -1)
 		return NULL;
 
@@ -127,10 +179,8 @@ getdiskcookedname(char *buf, size_t bufs
 		return NULL;
 	}
 
-	if (dp != NULL)
-		(void)snprintf(buf, bufsiz, "%.*s/%s", (int)(dp - name), name, dp + 2);
-	else
-		(void)snprintf(buf, bufsiz, "%s", name + 1);
+	if (calc_name(buf, bufsiz, name, "") == -1)
+		return NULL;
 
 	return buf;
 }

Index: src/libexec/lfs_cleanerd/lfs_cleanerd.8
diff -u src/libexec/lfs_cleanerd/lfs_cleanerd.8:1.18 src/libexec/lfs_cleanerd/lfs_cleanerd.8:1.18.48.1
--- src/libexec/lfs_cleanerd/lfs_cleanerd.8:1.18	Thu Aug  6 21:18:54 2009
+++ src/libexec/lfs_cleanerd/lfs_cleanerd.8	Mon Sep  2 16:16:56 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: lfs_cleanerd.8,v 1.18 2009/08/06 21:18:54 wiz Exp $
+.\"	$NetBSD: lfs_cleanerd.8,v 1.18.48.1 2019/09/02 16:16:56 martin Exp $
 .\"
 .\" Copyright (c) 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -39,9 +39,11 @@
 .Nm
 .Op Fl bcDdfmqs
 .Op Fl i Ar segment-number
+.Op Fl J Ar raw-device
 .Op Fl l Ar load-threshhold
 .Op Fl n Ar number-of-segments
 .Op Fl r Ar report-frequency
+.Op Fl S Ar semaphore-address
 .Op Fl t Ar timeout
 .Pa node
 .Sh DESCRIPTION
@@ -94,6 +96,12 @@ Invalidate the segment with segment numb
 This option is used by
 .Xr resize_lfs 8 ,
 and should not be specified on the command line.
+.It Fl J Ar raw device
+Specify the raw device that the cleaner is to work against rather than
+trying to figure it out from the mount point.  This is mostly useful
+when the cleaner is compiled into
+.Xr rump_lfs 8 ,
+and the ATF test framework.
 .It Fl l Ar load-threshhold
 Clean more aggressively when the system load is below the given threshhold.
 The default threshhold is 0.2.
@@ -112,6 +120,13 @@ Quit after cleaning once.
 Give an efficiency report after every
 .Ar report-frequency
 times through the main loop.
+.It Fl S Ar semaphore address
+When the cleaner code is compiled into
+.Xr rump_lfs 8 ,
+and the ATF frame work, this option allows for a synchronization
+semaphore to be specified.  This option is not available in the
+stand alone
+.Xr lfs_cleanerd 8 .
 .It Fl s
 When cleaning the file system,
 send only a few blocks through lfs_markv at a time.
@@ -132,7 +147,8 @@ to a low value.
 .Xr lfs_bmapv 2 ,
 .Xr lfs_markv 2 ,
 .Xr lfs_segwait 2 ,
-.Xr mount_lfs 8
+.Xr mount_lfs 8 ,
+.Xr rump_lfs 8 .
 .Sh HISTORY
 The
 .Nm

Index: src/libexec/lfs_cleanerd/lfs_cleanerd.c
diff -u src/libexec/lfs_cleanerd/lfs_cleanerd.c:1.58 src/libexec/lfs_cleanerd/lfs_cleanerd.c:1.58.18.1
--- src/libexec/lfs_cleanerd/lfs_cleanerd.c:1.58	Fri Mar 18 10:10:21 2016
+++ src/libexec/lfs_cleanerd/lfs_cleanerd.c	Mon Sep  2 16:16:56 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_cleanerd.c,v 1.58 2016/03/18 10:10:21 mrg Exp $	 */
+/* $NetBSD: lfs_cleanerd.c,v 1.58.18.1 2019/09/02 16:16:56 martin Exp $	 */
 
 /*-
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -76,6 +76,7 @@ int segwait_timeout;	/* Time to wait in 
 int do_quit;		/* Quit after one cleaning loop */
 int do_coalesce;	/* Coalesce filesystem */
 int do_small;		/* Use small writes through markv */
+char *do_asdevice;      /* Use this as the raw device */
 char *copylog_filename; /* File to use for fs debugging analysis */
 int inval_segment;	/* Segment to invalidate */
 int stat_report;	/* Report statistics for this period of cycles */
@@ -165,7 +166,7 @@ init_unmounted_fs(struct clfs *fs, char 
 {
 	struct lfs *disc_fs;
 	int i;
-	
+
 	fs->clfs_dev = fsname;
 	if ((fs->clfs_devfd = kops.ko_open(fs->clfs_dev, O_RDWR)) < 0) {
 		syslog(LOG_ERR, "couldn't open device %s read/write",
@@ -213,27 +214,36 @@ init_fs(struct clfs *fs, char *fsname)
 	int rootfd;
 	int i;
 	void *sbuf;
-	char *bn;
+	size_t mlen;
 
-	/*
-	 * Get the raw device from the block device.
-	 * XXX this is ugly.  Is there a way to discover the raw device
-	 * XXX for a given mount point?
-	 */
-	if (kops.ko_statvfs(fsname, &sf, ST_WAIT) < 0)
-		return -1;
-	fs->clfs_dev = malloc(strlen(sf.f_mntfromname) + 2);
-	if (fs->clfs_dev == NULL) {
-		syslog(LOG_ERR, "couldn't malloc device name string: %m");
-		return -1;
+	if (do_asdevice != NULL) {
+		fs->clfs_dev = strndup(do_asdevice,strlen(do_asdevice) + 2);
+		if (fs->clfs_dev == NULL) {
+			syslog(LOG_ERR, "couldn't malloc device name string: %m");
+			return -1;
+		}
+	} else {
+		/*
+		 * Get the raw device from the block device.
+		 * XXX this is ugly.  Is there a way to discover the raw device
+		 * XXX for a given mount point?
+		 */
+		if (kops.ko_statvfs(fsname, &sf, ST_WAIT) < 0)
+			return -1;
+		mlen = strlen(sf.f_mntfromname) + 2;
+		fs->clfs_dev = malloc(mlen);
+		if (fs->clfs_dev == NULL) {
+			syslog(LOG_ERR, "couldn't malloc device name string: %m");
+			return -1;
+		}
+		if (getdiskrawname(fs->clfs_dev, mlen, sf.f_mntfromname) == NULL) {
+			syslog(LOG_ERR, "couldn't convert '%s' to raw name: %m",
+			    sf.f_mntfromname);
+			return -1;
+		}
 	}
-	bn = strrchr(sf.f_mntfromname, '/');
-	bn = bn ? bn+1 : sf.f_mntfromname;
-	strlcpy(fs->clfs_dev, sf.f_mntfromname, bn - sf.f_mntfromname + 1);
-	strcat(fs->clfs_dev, "r");
-	strcat(fs->clfs_dev, bn);
 	if ((fs->clfs_devfd = kops.ko_open(fs->clfs_dev, O_RDONLY, 0)) < 0) {
-		syslog(LOG_ERR, "couldn't open device %s for reading",
+		syslog(LOG_ERR, "couldn't open device %s for reading: %m",
 			fs->clfs_dev);
 		return -1;
 	}
@@ -1439,7 +1449,7 @@ sig_exit(int sig)
 static void
 usage(void)
 {
-	errx(1, "usage: lfs_cleanerd [-bcdfmqs] [-i segnum] [-l load] "
+	fprintf(stderr, "usage: lfs_cleanerd [-bcdfmqsJ] [-i segnum] [-l load] "
 	     "[-n nsegs] [-r report_freq] [-t timeout] fs_name ...");
 }
 
@@ -1478,11 +1488,12 @@ lfs_cleaner_main(int argc, char **argv)
 	inval_segment	= -1;
 	copylog_filename = NULL;
 	nodetach        = 0;
+	do_asdevice     = NULL;
 
 	/*
 	 * Parse command-line arguments
 	 */
-	while ((opt = getopt(argc, argv, "bC:cdDfi:l:mn:qr:sS:t:")) != -1) {
+	while ((opt = getopt(argc, argv, "bC:cdDfi:J:l:mn:qr:sS:t:")) != -1) {
 		switch (opt) {
 		    case 'b':	/* Use bytes written, not segments read */
 			    use_bytes = 1;
@@ -1531,6 +1542,9 @@ lfs_cleaner_main(int argc, char **argv)
 		    case 't':	/* timeout */
 			    segwait_timeout = atoi(optarg);
 			    break;
+		    case 'J': /* do as a device */
+			    do_asdevice = optarg;
+			    break;
 		    default:
 			    usage();
 			    /* NOTREACHED */

Index: src/sbin/resize_lfs/resize_lfs.c
diff -u src/sbin/resize_lfs/resize_lfs.c:1.14 src/sbin/resize_lfs/resize_lfs.c:1.14.18.1
--- src/sbin/resize_lfs/resize_lfs.c:1.14	Sun Aug  2 18:18:09 2015
+++ src/sbin/resize_lfs/resize_lfs.c	Mon Sep  2 16:16:56 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: resize_lfs.c,v 1.14 2015/08/02 18:18:09 dholland Exp $	*/
+/*	$NetBSD: resize_lfs.c,v 1.14.18.1 2019/09/02 16:16:56 martin Exp $	*/
 /*-
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -47,6 +47,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <util.h>
 
 #include "partutil.h"
 
@@ -98,7 +99,8 @@ main(int argc, char **argv)
 		err(1, "%s", fsname);
 	rdevlen = strlen(vfs.f_mntfromname) + 2;
 	rdev = malloc(rdevlen);
-	snprintf(rdev, rdevlen, "/dev/r%s", vfs.f_mntfromname + 5);
+	if (getdiskrawname(rdev, rdevlen, vfs.f_mntfromname) == NULL)
+		err(1, "Could not convert '%s' to raw name", vfs.f_mntfromname);
 	devfd = open(rdev, O_RDONLY);
 	if (devfd < 0)
 		err(1, "open raw device");

Index: src/tests/fs/common/fstest_lfs.c
diff -u src/tests/fs/common/fstest_lfs.c:1.6 src/tests/fs/common/fstest_lfs.c:1.6.2.1
--- src/tests/fs/common/fstest_lfs.c:1.6	Sun Jan 20 14:50:58 2019
+++ src/tests/fs/common/fstest_lfs.c	Mon Sep  2 16:16:57 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: fstest_lfs.c,v 1.6 2019/01/20 14:50:58 gson Exp $	*/
+/*	$NetBSD: fstest_lfs.c,v 1.6.2.1 2019/09/02 16:16:57 martin Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -125,7 +125,7 @@ cleaner(void *arg)
 {
 	char thepath[MAXPATHLEN];
 	struct lfstestargs *args = arg;
-	const char *the_argv[7];
+	const char *the_argv[9];
 	char buf[64];
 
 	rump_pub_lwproc_newlwp(rump_sys_getpid());
@@ -139,14 +139,16 @@ cleaner(void *arg)
 	the_argv[1] = "-D"; /* don't fork() & detach */
 	the_argv[2] = "-S";
 	the_argv[3] = buf;
-	the_argv[4] = args->ta_mntpath;
-	the_argv[5] = NULL;
+	the_argv[4] = "-J";
+	the_argv[5] = thepath;
+	the_argv[6] = args->ta_mntpath;
+	the_argv[7] = NULL;
 
 	/* xxxatf */
 	optind = 1;
 	opterr = 1;
 
-	lfs_cleaner_main(5, __UNCONST(the_argv));
+	lfs_cleaner_main(7, __UNCONST(the_argv));
 
 	rump_pub_lwproc_releaselwp();
 

Index: src/usr.sbin/puffs/rump_lfs/rump_lfs.c
diff -u src/usr.sbin/puffs/rump_lfs/rump_lfs.c:1.18 src/usr.sbin/puffs/rump_lfs/rump_lfs.c:1.18.18.1
--- src/usr.sbin/puffs/rump_lfs/rump_lfs.c:1.18	Sun Aug  2 18:11:57 2015
+++ src/usr.sbin/puffs/rump_lfs/rump_lfs.c	Mon Sep  2 16:16:56 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: rump_lfs.c,v 1.18 2015/08/02 18:11:57 dholland Exp $	*/
+/*	$NetBSD: rump_lfs.c,v 1.18.18.1 2019/09/02 16:16:56 martin Exp $	*/
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -43,16 +43,20 @@
 
 #include "mount_lfs.h"
 
+#define RUMPRAWDEVICE "/dev/rrumpy0"
+
 static void *
 cleaner(void *arg)
 {
-	const char *the_argv[7];
+	const char *the_argv[9];
 
 	the_argv[0] = "megamaid";
 	the_argv[1] = "-D"; /* don't fork() & detach */
-	the_argv[2] = arg;
+	the_argv[2] = "-J"; /* treat arg as a device */
+	the_argv[3] = RUMPRAWDEVICE;
+	the_argv[4] = arg;
 
-	lfs_cleaner_main(3, __UNCONST(the_argv));
+	lfs_cleaner_main(5, __UNCONST(the_argv));
 
 	return NULL;
 }
@@ -93,7 +97,7 @@ main(int argc, char *argv[])
 	 * XXX: this particular piece inspired by the cleaner code.
 	 * obviously FIXXXME along with the cleaner.
 	 */
-	sprintf(rawdev, "/dev/r%s", canon_dev+5);
+	strlcpy(rawdev, RUMPRAWDEVICE, MAXPATHLEN);
 	rump_pub_etfs_register(rawdev, canon_dev, RUMP_ETFS_CHR);
 
 	/*

Reply via email to