Sat Oct 30 21:16:08 2010 UTC ()
Add resize_ffs tool to build, change default behaviour to grow filesystem
to device size. Add parameter -s to specify size if user want to shrink
filesystem.

Apply some KNF, remove dead unused code.

Oked by christos@.


(haad)
diff -r1.882 -r1.883 src/distrib/sets/lists/base/mi
diff -r1.1242 -r1.1243 src/distrib/sets/lists/man/mi
diff -r1.116 -r1.117 src/sbin/Makefile
diff -r1.3 -r1.4 src/sbin/resize_ffs/resize_ffs.8
diff -r1.12 -r1.13 src/sbin/resize_ffs/resize_ffs.c

cvs diff -r1.882 -r1.883 src/distrib/sets/lists/base/mi (expand / switch to context diff)
--- src/distrib/sets/lists/base/mi 2010/10/20 09:22:33 1.882
+++ src/distrib/sets/lists/base/mi 2010/10/30 21:16:08 1.883
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.882 2010/10/20 09:22:33 jmmv Exp $
+# $NetBSD: mi,v 1.883 2010/10/30 21:16:08 haad Exp $
 #
 # Note:	Don't delete entries from here - mark them as "obsolete" instead,
 #	unless otherwise stated below.
@@ -295,6 +295,7 @@
 ./sbin/rdump_lfs				base-sysutil-root
 ./sbin/reboot					base-sysutil-root
 ./sbin/resolvconf				base-resolvconf-root
+./sbin/resize_ffs				base-sysutil-root
 ./sbin/resize_lfs				base-sysutil-root
 ./sbin/restore					base-sysutil-root
 ./sbin/rndctl					base-sysutil-root

cvs diff -r1.1242 -r1.1243 src/distrib/sets/lists/man/mi (expand / switch to context diff)
--- src/distrib/sets/lists/man/mi 2010/10/24 08:54:14 1.1242
+++ src/distrib/sets/lists/man/mi 2010/10/30 21:16:08 1.1243
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1242 2010/10/24 08:54:14 jruoho Exp $
+# $NetBSD: mi,v 1.1243 2010/10/30 21:16:08 haad Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -2552,6 +2552,7 @@
 ./usr/share/man/cat8/renice.0			man-sysutil-catman	.cat
 ./usr/share/man/cat8/repquota.0			man-sysutil-catman	.cat
 ./usr/share/man/cat8/rescue.0			man-sysutil-catman	.cat
+./usr/share/man/cat8/resize_ffs.0		man-sysutil-catman      .cat
 ./usr/share/man/cat8/resize_lfs.0		man-sysutil-catman	.cat
 ./usr/share/man/cat8/resolvconf.0		man-resolvconf-catman	.cat
 ./usr/share/man/cat8/restore.0			man-sysutil-catman	.cat
@@ -4991,6 +4992,7 @@
 ./usr/share/man/html8/renice.html		man-sysutil-htmlman	html
 ./usr/share/man/html8/repquota.html		man-sysutil-htmlman	html
 ./usr/share/man/html8/rescue.html		man-sysutil-htmlman	html
+./usr/share/man/html8/resize_ffs.html		man-sysutil-htmlman     html
 ./usr/share/man/html8/resize_lfs.html		man-sysutil-htmlman	html
 ./usr/share/man/html8/resolvconf.html		man-resolvconf-htmlman	html
 ./usr/share/man/html8/restore.html		man-sysutil-htmlman	html
@@ -7706,6 +7708,7 @@
 ./usr/share/man/man8/renice.8			man-sysutil-man		.man
 ./usr/share/man/man8/repquota.8			man-sysutil-man		.man
 ./usr/share/man/man8/rescue.8			man-sysutil-man		.man
+./usr/share/man/man8/resize_ffs.8		man-sysutil-man         .man
 ./usr/share/man/man8/resize_lfs.8		man-sysutil-man		.man
 ./usr/share/man/man8/resolvconf.8		man-resolvconf-man	.man
 ./usr/share/man/man8/restore.8			man-sysutil-man		.man

cvs diff -r1.116 -r1.117 src/sbin/Makefile (expand / switch to context diff)
--- src/sbin/Makefile 2010/03/10 23:13:10 1.116
+++ src/sbin/Makefile 2010/10/30 21:16:07 1.117
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.116 2010/03/10 23:13:10 abs Exp $
+#	$NetBSD: Makefile,v 1.117 2010/10/30 21:16:07 haad Exp $
 #	@(#)Makefile	8.5 (Berkeley) 3/31/94
 
 # Not ported: XNSrouted enpload scsiformat startslip
@@ -16,7 +16,7 @@
 
 # support for various file systems
 SUBDIR+= newfs_ext2fs fsck_ext2fs
-SUBDIR+= newfs fsck_ffs fsdb dump restore clri tunefs
+SUBDIR+= newfs fsck_ffs fsdb dump restore clri tunefs resize_ffs
 SUBDIR+= newfs_lfs fsck_lfs dump_lfs resize_lfs
 SUBDIR+= newfs_msdos fsck_msdos
 SUBDIR+= newfs_sysvbfs

cvs diff -r1.3 -r1.4 src/sbin/resize_ffs/resize_ffs.8 (expand / switch to context diff)
--- src/sbin/resize_ffs/resize_ffs.8 2003/03/10 09:23:23 1.3
+++ src/sbin/resize_ffs/resize_ffs.8 2010/10/30 21:16:07 1.4
@@ -1,4 +1,4 @@
-.\"     $NetBSD: resize_ffs.8,v 1.3 2003/03/10 09:23:23 wiz Exp $
+.\"     $NetBSD: resize_ffs.8,v 1.4 2010/10/30 21:16:07 haad Exp $
 .\"
 .\" As its sole author, I explicitly place this man page in the public
 .\" domain.  Anyone may use it in any way for any purpose (though I would
@@ -16,16 +16,14 @@
 .Nd resize an on-disk file system
 .Sh SYNOPSIS
 .Nm
+.Op Fl y
+.Op Fl s Ar size
 .Ar file-system-raw-device
-.Ar newsize
 .Sh DESCRIPTION
 .Nm
 resizes a file system on disk.
 .Ar file-system-raw-device
 is the name of the raw disk device where the file system resides;
-.Ar newsize
-is the desired new file system size, in sectors.
-(Sectors are almost always 512 bytes, and
 .Nm
 can both grow and shrink file systems.
 When growing, the disk device
@@ -46,6 +44,20 @@
 the file system in a consistent state, but it is probably a good idea to
 check the file system with
 .Xr fsck 8 .
+.Pp
+If there is no
+.Fl s 
+used resize_ffs will grow filesystem to underlyining device size which is get
+from device.
+.Pp
+The options are as foolows:
+.Bl -tag -width indent
+.It Fl y
+option will disable sanity question made by resize_ffs.
+.It Fl s 
+Can be used to specify filesystem size to which we want to resize fs.
+This is only way hot to shrink filesystem now.
+.El
 .Sh WARNING
 .Nm
 should still be considered experimental.  It still needs to be validated
@@ -78,8 +90,23 @@
 known bugs in the program.
 However, you should be aware that just
 because fsck is happy with the file system does not mean it is intact.
+.Sh EXIT STATUS
+.Nm
+exits with
+.Dv 0
+on success.
+Any major problems will cause
+.Nm
+to exit with the non-zero
+.Xr exit 3
+codes, so as to alert any invoking program or script that human
+intervention is required.
 .Sh EXAMPLES
-.Ic resize_ffs Cm /dev/rsd1e 29574
+.Dl resize_ffs Cm /dev/vg00/rlv1
+.Pp 
+will enlarge filesystem on Logical Volume
+.Pa /dev/vg00/lv1
+from Volume Group vg00 to current device size.
 .Sh SEE ALSO
 .Xr fs 5 ,
 .Xr fsck 8 ,
@@ -110,3 +137,5 @@
 .Pp
 Has no intelligence whatever when it comes to allocating blocks to copy
 data into when shrinking.
+.Pp
+Doesn't work with FFSv2 filesystems.

cvs diff -r1.12 -r1.13 src/sbin/resize_ffs/resize_ffs.c (expand / switch to context diff)
--- src/sbin/resize_ffs/resize_ffs.c 2007/12/15 19:44:47 1.12
+++ src/sbin/resize_ffs/resize_ffs.c 2010/10/30 21:16:07 1.13
@@ -1,4 +1,4 @@
-/*	$NetBSD: resize_ffs.c,v 1.12 2007/12/15 19:44:47 perry Exp $	*/
+/*	$NetBSD: resize_ffs.c,v 1.13 2010/10/30 21:16:07 haad Exp $	*/
 /* From sources sent on February 17, 2003 */
 /*-
  * As its sole author, I explicitly place this code in the public
@@ -48,6 +48,10 @@
 #include <unistd.h>
 #include <strings.h>
 #include <err.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
+#include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/param.h>		/* MAXFRAG */
@@ -56,21 +60,8 @@
 #include <ufs/ufs/dinode.h>
 #include <ufs/ufs/ufs_bswap.h>	/* ufs_rw32 */
 
-/* Suppress warnings about unused arguments */
-#if	defined(__GNUC__) &&				\
-	( (__GNUC__ > 2) ||				\
-	  ( (__GNUC__ == 2) &&				\
-	    defined(__GNUC_MINOR__) &&			\
-	    (__GNUC_MINOR__ >= 7) ) )
-#define UNUSED_ARG(x) x __unused
-#define INLINE inline
-#else
-#define UNUSED_ARG(x) x
-#define INLINE			/**/
-#endif
-
 /* new size of filesystem, in sectors */
-static int newsize;
+static uint32_t newsize;
 
 /* fd open onto disk device */
 static int fd;
@@ -156,6 +147,8 @@
 #define NSPB(fs)	((fs)->fs_old_nspf << (fs)->fs_fragshift)
 #define NSPF(fs)	((fs)->fs_old_nspf)
 
+static void usage(void) __dead;
+
 /*
  * See if we need to break up large I/O operations.  This should never
  *  be needed, but under at least one <version,platform> combination,
@@ -195,7 +188,7 @@
 			n = (left > 8192) ? 8192 : left;
 			rv = read(fd, bp, n);
 			if (rv < 0)
-				err(1, "read failed");
+				err(EXIT_FAILURE, "read failed");
 			if (rv != n)
 				errx(1, "read: wanted %d, got %d", n, rv);
 			bp += n;
@@ -205,7 +198,7 @@
 		int rv;
 		rv = read(fd, buf, size);
 		if (rv < 0)
-			err(1, "read failed");
+			err(EXIT_FAILURE, "read failed");
 		if (rv != size)
 			errx(1, "read: wanted %d, got %d", size, rv);
 	}
@@ -219,7 +212,7 @@
 {
 	/* Seek to the correct place. */
 	if (lseek(fd, blkno * DEV_BSIZE, L_SET) < 0)
-		err(1, "lseek failed");
+		err(EXIT_FAILURE, "lseek failed");
 	/* See if we have to break up the transfer... */
 	if (smallio) {
 		const char *bp;	/* pointer into buf */
@@ -232,7 +225,7 @@
 			n = (left > 8192) ? 8192 : left;
 			rv = write(fd, bp, n);
 			if (rv < 0)
-				err(1, "write failed");
+				err(EXIT_FAILURE, "write failed");
 			if (rv != n)
 				errx(1, "write: wanted %d, got %d", n, rv);
 			bp += n;
@@ -242,7 +235,7 @@
 		int rv;
 		rv = write(fd, buf, size);
 		if (rv < 0)
-			err(1, "write failed");
+			err(EXIT_FAILURE, "write failed");
 		if (rv != size)
 			errx(1, "write: wanted %d, got %d", size, rv);
 	}
@@ -264,7 +257,7 @@
 	rv = malloc(nb);
 	if (rv)
 		return (rv);
-	err(1, "Can't allocate %lu bytes for %s",
+	err(EXIT_FAILURE, "Can't allocate %lu bytes for %s",
 	    (unsigned long int) nb, tag);
 }
 /*
@@ -278,7 +271,7 @@
 	rv = realloc(blk, nb);
 	if (rv)
 		return (rv);
-	err(1, "Can't re-allocate %lu bytes for %s",
+	err(EXIT_FAILURE, "Can't re-allocate %lu bytes for %s",
 	    (unsigned long int) nb, tag);
 }
 /*
@@ -296,7 +289,7 @@
 	rv = mmap(0, nb, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
 	if (rv != MAP_FAILED)
 		return (rv);
-	err(1, "Can't map %lu bytes for %s",
+	err(EXIT_FAILURE, "Can't map %lu bytes for %s",
 	    (unsigned long int) nb, tag);
 }
 /*
@@ -381,7 +374,7 @@
 /*
  * Test whether bit #bit is set in the bitmap pointed to by bitvec.
  */
-INLINE static int
+static int
 bit_is_set(unsigned char *bitvec, int bit)
 {
 	return (bitvec[bit >> 3] & (1 << (bit & 7)));
@@ -389,7 +382,7 @@
 /*
  * Test whether bit #bit is clear in the bitmap pointed to by bitvec.
  */
-INLINE static int
+static int
 bit_is_clr(unsigned char *bitvec, int bit)
 {
 	return (!bit_is_set(bitvec, bit));
@@ -402,7 +395,7 @@
  *  iff _all_ the bits are set; it is not just the complement of
  *  blk_is_clr on the same arguments (unless blkfrags==1).
  */
-INLINE static int
+static int
 blk_is_set(unsigned char *bitvec, int blkbase, int blkfrags)
 {
 	unsigned int mask;
@@ -416,7 +409,7 @@
  *  the bits are clear; it is not just the complement of blk_is_set on
  *  the same arguments (unless blkfrags==1).
  */
-INLINE static int
+static int
 blk_is_clr(unsigned char *bitvec, int blkbase, int blkfrags)
 {
 	unsigned int mask;
@@ -890,8 +883,10 @@
 	/* Did we actually not grow?  (This can happen if newsize is less than
 	 * a frag larger than the old size - unlikely, but no excuse to
 	 * misbehave if it happens.) */
-	if (newsb->fs_size == oldsb->fs_size)
+	if (newsb->fs_size == oldsb->fs_size) {
+		printf("New fs size %"PRIu64" = odl fs size %"PRIu64", not growing.\n", newsb->fs_size, oldsb->fs_size);
 		return;
+	}
 	/* Check that the new last sector (frag, actually) is writable.  Since
 	 * it's at least one frag larger than it used to be, we know we aren't
 	 * overwriting anything important by this.  (The choice of sbbuf as
@@ -965,7 +960,7 @@
  *  over either the old or the new filesystem's set of inodes.
  */
 static void
-     map_inodes(void (*fn) (struct ufs1_dinode * di, unsigned int, void *arg), int ncg, void *cbarg) {
+map_inodes(void (*fn) (struct ufs1_dinode * di, unsigned int, void *arg), int ncg, void *cbarg) {
 	int i;
 	int ni;
 
@@ -1821,24 +1816,98 @@
 		writeat(fsbtodb(newsb, cgsblock(newsb, i)), newsb, SBLOCKSIZE);
 	}
 }
+
+static uint32_t
+get_dev_size(char *dev_name)
+{
+	struct dkwedge_info dkw;
+	struct partition *pp;
+	struct disklabel lp;
+	size_t ptn;
+	
+	/* Get info about partition/wedge */
+	if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == -1) {
+		if (ioctl(fd, DIOCGDINFO, &lp) == -1)
+			return 0;
+
+		ptn = strchr(dev_name, '\0')[-1] - 'a';
+		if (ptn >= lp.d_npartitions)
+			return 0;
+
+		pp = &lp.d_partitions[ptn];
+		return pp->p_size;
+	}
+
+	return dkw.dkw_size;
+}
+
 /*
  * main().
  */
-int main(int, char **);
 int
-main(int ac, char **av)
+main(int argc, char **argv)
 {
+	int ch;
+	int ExpertFlag;
+	int SFlag;
 	size_t i;
-	if (ac != 3) {
-		fprintf(stderr, "usage: %s filesystem new-size\n",
-		    getprogname());
-		exit(1);
+
+	char *device;
+	char reply[5];
+	
+	newsize = 0;
+	ExpertFlag = 0;
+	SFlag = 0;
+	
+	while ((ch = getopt(argc, argv, "s:y")) != -1) {
+		switch (ch) {
+		case 's':
+			SFlag = 1;
+			newsize = (size_t)strtoul(optarg, NULL, 10);
+			if(newsize < 1) {
+				usage();
+			}
+			break;
+		case 'y':
+			ExpertFlag = 1;
+			break;
+		case '?':
+			/* FALLTHROUGH */
+		default:
+			usage();
+		}
 	}
-	fd = open(av[1], O_RDWR, 0);
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 1) {
+		usage();
+	}
+
+	device = *argv;
+
+	if (ExpertFlag == 0) {
+		printf("It's required to manually run fsck on filesystem device "
+		    "before you can resize it\n\n"
+		    " Did you run fsck on your disk (Yes/No) ? ");
+		fgets(reply, (int)sizeof(reply), stdin);
+		if (strcasecmp(reply, "Yes\n")) {
+			printf("\n Nothing done \n");
+			exit(EXIT_SUCCESS);
+		}
+	}
+	
+	fd = open(device, O_RDWR, 0);
 	if (fd < 0)
-		err(1, "Cannot open `%s'", av[1]);
+		err(EXIT_FAILURE, "Cannot open `%s'", device);
 	checksmallio();
-	newsize = atoi(av[2]);
+
+	if (SFlag == 0) {
+		newsize = get_dev_size(device);
+		if (newsize == 0)
+			err(EXIT_FAILURE, "Cannot resize filesystem, newsize not known.");
+	}
+	
 	oldsb = (struct fs *) & sbbuf;
 	newsb = (struct fs *) (SBLOCKSIZE + (char *) &sbbuf);
 	for (where = search[i = 0]; search[i] != -1; where = search[++i]) {
@@ -1848,16 +1917,16 @@
 		if (where == SBLOCK_UFS2)
 			continue;
 		if (oldsb->fs_old_flags & FS_FLAGS_UPDATED)
-			err(1, "Cannot resize ffsv2 format suberblock!");
+			err(EXIT_FAILURE, "Cannot resize ffsv2 format suberblock!");
 	}
 	if (where == (off_t)-1)
-		errx(1, "Bad magic number");
+		errx(EXIT_FAILURE, "Bad magic number");
 	oldsb->fs_qbmask = ~(int64_t) oldsb->fs_bmask;
 	oldsb->fs_qfmask = ~(int64_t) oldsb->fs_fmask;
 	if (oldsb->fs_ipg % INOPB(oldsb)) {
-		printf("ipg[%d] %% INOPB[%d] != 0\n", (int) oldsb->fs_ipg,
+		(void)fprintf(stderr, "ipg[%d] %% INOPB[%d] != 0\n", (int) oldsb->fs_ipg,
 		    (int) INOPB(oldsb));
-		exit(1);
+		exit(EXIT_FAILURE);
 	}
 	/* The superblock is bigger than struct fs (there are trailing tables,
 	 * of non-fixed size); make sure we copy the whole thing.  SBLOCKSIZE may
@@ -1872,5 +1941,13 @@
 	}
 	flush_cgs();
 	write_sbs();
-	exit(0);
+	return 0;
+}
+
+static void
+usage(void)
+{
+
+	(void)fprintf(stderr, "usage: %s [-y] [-s size] device\n", getprogname());
+	exit(EXIT_FAILURE);
 }