Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/resize_ffs Preliminary version of resize_ffs, based on ...



details:   https://anonhg.NetBSD.org/src/rev/d7376801b152
branches:  trunk
changeset: 543265:d7376801b152
user:      jtk <jtk%NetBSD.org@localhost>
date:      Fri Feb 21 04:08:54 2003 +0000

description:
Preliminary version of resize_ffs, based on der Mouse's fsresize tool.
I didn't have time to clean it up completely before my legal status
w.r.t. open source projects goes into limbo for a while.  Other
developers are encouraged to play with the tool and get it into
release-worthy shape.

TODO list (see TODO file)

* verify it builds on -current, put it into release lists/etc. and src/sbin/Makefile
  (built & tested on 1.6.1)
* make it ask questions before doing any work (confirm)
* create regression test suite (see discussions on tech-kern and
  developers) and fix any bugs
* verify conversion to ANSI C didn't break anything
* port to UFS2

diffstat:

 sbin/resize_ffs/Makefile     |     6 +
 sbin/resize_ffs/TODO         |    15 +
 sbin/resize_ffs/resize_ffs.8 |   105 ++
 sbin/resize_ffs/resize_ffs.c |  1883 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 2009 insertions(+), 0 deletions(-)

diffs (truncated from 2025 to 300 lines):

diff -r 317d3dd9437c -r d7376801b152 sbin/resize_ffs/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/resize_ffs/Makefile  Fri Feb 21 04:08:54 2003 +0000
@@ -0,0 +1,6 @@
+#      $NetBSD: Makefile,v 1.1 2003/02/21 04:08:54 jtk Exp $
+
+PROG=resize_ffs
+MAN=resize_ffs.8
+
+.include <bsd.prog.mk>
diff -r 317d3dd9437c -r d7376801b152 sbin/resize_ffs/TODO
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/resize_ffs/TODO      Fri Feb 21 04:08:54 2003 +0000
@@ -0,0 +1,15 @@
+Preliminary version of resize_ffs, based on der Mouse's fsresize tool.
+I didn't have time to clean it up completely before my legal status
+w.r.t. open source projects goes into limbo for a while.  Other
+developers are encouraged to play with the tool and get it into
+release-worthy shape.
+
+TODO list (see TODO file)
+
+* verify it builds on -current, put it into release lists/etc. and src/sbin/Makefile
+  (built & tested on 1.6.1)
+* make it ask questions before doing any work (confirm)
+* create regression test suite (see discussions on tech-kern and
+  developers) and fix any bugs
+* verify conversion to ANSI C didn't break anything
+* port to UFS2
diff -r 317d3dd9437c -r d7376801b152 sbin/resize_ffs/resize_ffs.8
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/resize_ffs/resize_ffs.8      Fri Feb 21 04:08:54 2003 +0000
@@ -0,0 +1,105 @@
+.\"     $NetBSD: resize_ffs.8,v 1.1 2003/02/21 04:08:55 jtk 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
+.\" appreciate credit where it is due).
+.\"
+.\" /~\ The ASCII                           der Mouse
+.\" \ / Ribbon Campaign
+.\"  X  Against HTML               mouse%rodents.montreal.qc.ca@localhost
+.\" / \ Email!           7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B
+.Dd February 20, 2003
+.Dt RESIZE_FFS 8
+.Sh NAME
+.Nm resize_ffs
+.Nd resize an on-disk filesystem
+.Sh SYNOPSIS
+.Nm
+.Ar filesystem-raw-device
+.Ar newsize
+.Sh DESCRIPTION
+.Nm
+resizes a filesystem on disk.
+.Ar filesystem
+is the name of the raw disk device where the filesystem resides;
+.Ar newsize
+is the desired new filesystem size, in sectors.  (Sectors are almost
+always 512 bytes, and
+.Nm
+can both grow and shrink filesystems.  When growing, the disk device
+must of course be large enough to contain the new filesystem;
+.Nm
+simply extends the filesystem data structures into the new space.  When
+shrinking,
+.Nm
+assumes this.  It will not work correctly for filesystems with other
+sector sizes.)
+.Nm
+has to copy anything that currently resides in the space being shrunk
+away; there must be enough space free on the filesystem for this to
+succeed.  If there isn't,
+.Nm
+will complain and exit; when this happens, it attempts to always leave
+the filesystem in a consistent state, but it is probably a good idea to
+check the filesystem with
+.Xr fsck 8 .
+.Pp
+.Sh WARNING
+.Nm
+should still be considered experimental.  It still needs to be validated
+with a rigorous regression test suite.
+
+.Em Interrupting
+.Nm
+.Em "may leave your file system in an inconsistent state and require a"
+.Em "restore from backup."
+It attempts to write in the proper order to avoid problems, but as it is
+still considered experimental, you should take great care when using it.
+.Pp
+When
+.Nm
+is applied to a consistent filesystem, it should always produce a
+consistent filesystem; if the filesystem is not consistent to start
+with,
+.Nm
+may misbehave, anything from dumping core to completely curdling the
+data.  It's probably wise to
+.Xr fsck 8
+the filesystem before and after, just to be safe.
+.\" Remove this when (if) fsck gets fixed.
+.Pp
+There is a bug somewhere in fsck; it does not check certain data
+structures enough.  A past version of this program had a bug that
+produced corrupted rotation layout summary tables, which would panic
+the kernel.  This bug is believed fixed, and there are currently no
+known bugs in the program.  However, you should be aware that just
+because fsck is happy with the filesystem does not mean it is intact.
+.Sh EXAMPLES
+.Nm
+.Li /dev/rsd1e 29574
+.Sh SEE ALSO
+.Xr fs 5 ,
+.Xr newfs 8 ,
+.Xr fsck 8
+.Sh AUTHOR
+.Li der Mouse <mouse%rodents.montreal.qc.ca@localhost>
+.Pp
+A big bug-finding kudos goes to John Kohl for finding the rotational
+layout bug referred
+to in the WARNING section above.
+.Sh BUGS
+Has not been tested and probably won't work on opposite-endian file
+systems.
+.Pp
+Can fail to shrink a filesystem when there actually is enough space,
+because it does not distinguish between a block allocated as a block
+and a block fully occupied by two or more frags.  This is unlikely to
+occur in practice; except for pathological cases, it can happen only
+when the new size is extremely close to the minimum possible.
+.Pp
+Has no intelligence whatever when it comes to allocating blocks to copy
+data into when shrinking.
+.Sh HISTORY
+The
+.Nm
+command first appeared in
+.Nx 2.0 .
diff -r 317d3dd9437c -r d7376801b152 sbin/resize_ffs/resize_ffs.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sbin/resize_ffs/resize_ffs.c      Fri Feb 21 04:08:54 2003 +0000
@@ -0,0 +1,1883 @@
+/*     $NetBSD: resize_ffs.c,v 1.1 2003/02/21 04:08:55 jtk Exp $       */
+/* From sources sent on February 17, 2003 */
+/*-
+ * As its sole author, I explicitly place this code in the public
+ *  domain.  Anyone may use it for any purpose (though I would
+ *  appreciate credit where it is due).
+ *
+ *                                     der Mouse
+ *
+ *                            mouse%rodents.montreal.qc.ca@localhost
+ *                  7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B
+ */
+/*
+ * ffs_resize:
+ *
+ * Resize a filesystem.  Is capable of both growing and shrinking.
+ *
+ * Usage: fsresize filesystem newsize
+ *
+ * Example: fsresize /dev/rsd1e 29574
+ *
+ * newsize is in DEV_BSIZE units (ie, disk sectors, usually 512 bytes
+ *  each).
+ *
+ * Note: this currently requires gcc to build, since it is written
+ *  depending on gcc-specific features, notably nested function
+ *  definitions (which in at least a few cases depend on the lexical
+ *  scoping gcc provides, so they can't be trivially moved outside).
+ *
+ * It will not do anything useful with filesystems in other than
+ *  host-native byte order.  This really should be fixed (it's largely
+ *  a historical accident; the original version of this program is
+ *  older than bi-endian support in FFS).
+ *
+ * Many thanks go to John Kohl <jtk%netbsd.org@localhost> for finding bugs: the
+ *  one responsible for the "realloccgblk: can't find blk in cyl"
+ *  problem and a more minor one which left fs_dsize wrong when
+ *  shrinking.  (These actually indicate bugs in fsck too - it should
+ *  have caught and fixed them.)
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/param.h>         /* MAXFRAG */
+#include <ufs/ufs/dinode.h>    /* ufs_daddr_t */
+#include <ufs/ffs/fs.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/ufs_bswap.h> /* ufs_rw32 */
+
+extern const char *__progname;
+
+/* Patchup for systems that don't yet have __progname */
+#ifdef NO_PROGNAME
+const char *__progname;
+int main(int, char **);
+int main_(int, char **);
+int
+main(int ac, char **av)
+#define main main_
+{
+       __progname = av[0];
+       return (main(ac, av));
+}
+#endif
+
+/* Suppress warnings about unused arguments */
+#if    defined(__GNUC__) &&                            \
+       ( (__GNUC__ > 2) ||                             \
+         ( (__GNUC__ == 2) &&                          \
+           defined(__GNUC_MINOR__) &&                  \
+           (__GNUC_MINOR__ >= 7) ) )
+#define UNUSED_ARG(x) x __attribute__((__unused__))
+#define INLINE inline
+#else
+#define UNUSED_ARG(x) x
+#define INLINE                 /**/
+#endif
+
+/* new size of filesystem, in sectors */
+static int newsize;
+
+/* fd open onto disk device */
+static int fd;
+
+/* must we break up big I/O operations - see checksmallio() */
+static int smallio;
+
+/* size of a cg, in bytes, rounded up to a frag boundary */
+static int cgblksz;
+
+/* Superblocks. */
+static struct fs *oldsb;       /* before we started */
+static struct fs *newsb;       /* copy to work with */
+/* Buffer to hold the above.  Make sure it's aligned correctly. */
+static char sbbuf[2 * SBSIZE] __attribute__((__aligned__(__alignof__(struct fs))));
+
+/* a cg's worth of brand new squeaky-clean inodes */
+static struct dinode *zinodes;
+
+/* pointers to the in-core cgs, read off disk and possibly modified */
+static struct cg **cgs;
+
+/* pointer to csum array - the stuff pointed to on-disk by fs_csaddr */
+static struct csum *csums;
+
+/* per-cg flags, indexed by cg number */
+static unsigned char *cgflags;
+#define CGF_DIRTY   0x01       /* needs to be written to disk */
+#define CGF_BLKMAPS 0x02       /* block bitmaps need rebuilding */
+#define CGF_INOMAPS 0x04       /* inode bitmaps need rebuilding */
+
+/* when shrinking, these two arrays record how we want blocks to move.  */
+/*  if blkmove[i] is j, the frag that started out as frag #i should end         */
+/*  up as frag #j.  inomove[i]=j means, similarly, that the inode that  */
+/*  started out as inode i should end up as inode j.                    */
+static unsigned int *blkmove;
+static unsigned int *inomove;
+
+/* in-core copies of all inodes in the fs, indexed by inumber */
+static struct dinode *inodes;
+
+/* per-inode flags, indexed by inumber */
+static unsigned char *iflags;
+#define IF_DIRTY  0x01         /* needs to be written to disk */
+#define IF_BDIRTY 0x02         /* like DIRTY, but is set on first inode in a
+                                * block of inodes, and applies to the whole
+                                * block. */
+
+/*
+ * See if we need to break up large I/O operations.  This should never
+ *  be needed, but under at least one <version,platform> combination,
+ *  large enough disk transfers to the raw device hang.  So if we're
+ *  talking to a character special device, play it safe; in this case,
+ *  readat() and writeat() break everything up into pieces no larger
+ *  than 8K, doing multiple syscalls for larger operations.
+ */
+static void
+checksmallio(void)
+{
+       struct stat stb;
+
+       fstat(fd, &stb);
+       smallio = ((stb.st_mode & S_IFMT) == S_IFCHR);
+}
+/*
+ * Read size bytes starting at blkno into buf.  blkno is in DEV_BSIZE
+ *  units, ie, after fsbtodb(); size is in bytes.
+ */
+static void
+readat(off_t blkno, void *buf, int size)



Home | Main Index | Thread Index | Old Index