Source-Changes-HG archive

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

[src/trunk]: src/sbin/fsdb add a "saveblks <file>" command that saves the dat...



details:   https://anonhg.NetBSD.org/src/rev/ed4c9a6ac3d5
branches:  trunk
changeset: 825884:ed4c9a6ac3d5
user:      mrg <mrg%NetBSD.org@localhost>
date:      Fri Aug 04 07:19:35 2017 +0000

description:
add a "saveblks <file>" command that saves the data blocks of the current
inode into named file.

diffstat:

 sbin/fsdb/fsdb.8 |  10 ++++-
 sbin/fsdb/fsdb.c |  97 +++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 82 insertions(+), 25 deletions(-)

diffs (263 lines):

diff -r 85abacff8343 -r ed4c9a6ac3d5 sbin/fsdb/fsdb.8
--- a/sbin/fsdb/fsdb.8  Fri Aug 04 07:00:17 2017 +0000
+++ b/sbin/fsdb/fsdb.8  Fri Aug 04 07:19:35 2017 +0000
@@ -1,6 +1,6 @@
-.\"    $NetBSD: fsdb.8,v 1.24 2017/07/03 21:33:41 wiz Exp $
+.\"    $NetBSD: fsdb.8,v 1.25 2017/08/04 07:19:35 mrg Exp $
 .\"
-.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
+.\" Copyright (c) 1996, 2017 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This code is derived from software contributed to The NetBSD Foundation
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd January 3, 2004
+.Dd August 3, 2017
 .Dt FSDB 8
 .Os
 .Sh NAME
@@ -136,6 +136,10 @@
 Note that these are not absolute disk blocks numbers, but offsets from the
 start of the partition.
 .Pp
+.It Cm saveblks Ar filename
+Save the current inode's data into
+.Ar filename .
+.Pp
 .It Cm rm Ar name
 .It Cm del Ar name
 Remove the entry
diff -r 85abacff8343 -r ed4c9a6ac3d5 sbin/fsdb/fsdb.c
--- a/sbin/fsdb/fsdb.c  Fri Aug 04 07:00:17 2017 +0000
+++ b/sbin/fsdb/fsdb.c  Fri Aug 04 07:19:35 2017 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: fsdb.c,v 1.49 2016/07/28 08:24:58 martin Exp $ */
+/*     $NetBSD: fsdb.c,v 1.50 2017/08/04 07:19:35 mrg Exp $    */
 
 /*-
- * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996, 2017 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: fsdb.c,v 1.49 2016/07/28 08:24:58 martin Exp $");
+__RCSID("$NetBSD: fsdb.c,v 1.50 2017/08/04 07:19:35 mrg Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -61,6 +61,13 @@
 #include "fsck.h"
 #include "extern.h"
 
+/* Used to keep state for "saveblks" command.  */
+struct wrinfo {
+       off_t size;
+       off_t written_size;
+       int fd;
+};
+
 __dead static void usage(void);
 static int cmdloop(void);
 static char *prompt(EditLine *);
@@ -69,12 +76,12 @@
 static int chinumfunc(struct inodesc *);
 static int chnamefunc(struct inodesc *);
 static int dotime(char *, int32_t *, int32_t *);
-static void print_blks32(int32_t *buf, int size, uint64_t *blknum);
-static void print_blks64(int64_t *buf, int size, uint64_t *blknum);
+static void print_blks32(int32_t *buf, int size, uint64_t *blknum, struct wrinfo *wrp);
+static void print_blks64(int64_t *buf, int size, uint64_t *blknum, struct wrinfo *wrp);
 static void print_indirblks32(uint32_t blk, int ind_level,
-    uint64_t *blknum);
+    uint64_t *blknum, struct wrinfo *wrp);
 static void print_indirblks64(uint64_t blk, int ind_level,
-    uint64_t *blknum);
+    uint64_t *blknum, struct wrinfo *wrp);
 static int compare_blk32(uint32_t *, uint32_t);
 static int compare_blk64(uint64_t *, uint64_t);
 static int founddatablk(uint64_t);
@@ -191,6 +198,7 @@
        {"linkcount", "Set link count to COUNT", 2, 2, linkcount},
        {"ls", "List current inode as directory", 1, 1, ls},
        {"blks", "List current inode's data blocks", 1, 1, blks},
+       {"saveblks", "Save current inode's data blocks", 2, 2, blks},
        {"findblk", "Find inode owning disk block(s)", 2, 33, findblk},
        {"rm", "Remove NAME from current inode directory", 2, 2, rm},
        {"del", "Remove NAME from current inode directory", 2, 2, rm},
@@ -452,6 +460,18 @@
 {
        uint64_t blkno = 0;
        int i, type;
+       struct wrinfo wrinfo, *wrp = NULL;
+
+       if (strcmp(argv[0], "saveblks") == 0) {
+               wrinfo.fd = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0644);
+               if (wrinfo.fd == -1) {
+                       warn("unable to create file %s", argv[1]);
+                       return 0;
+               }
+               wrinfo.size = DIP(curinode, size);
+               wrinfo.written_size = 0;
+               wrp = &wrinfo;
+       }
        if (!curinode) {
                warnx("no current inode");
                return 0;
@@ -471,18 +491,18 @@
        }
        printf("Direct blocks:\n");
        if (is_ufs2)
-               print_blks64(curinode->dp2.di_db, UFS_NDADDR, &blkno);
+               print_blks64(curinode->dp2.di_db, UFS_NDADDR, &blkno, wrp);
        else
-               print_blks32(curinode->dp1.di_db, UFS_NDADDR, &blkno);
+               print_blks32(curinode->dp1.di_db, UFS_NDADDR, &blkno, wrp);
 
        if (is_ufs2) {
                for (i = 0; i < UFS_NIADDR; i++)
                        print_indirblks64(iswap64(curinode->dp2.di_ib[i]), i,
-                           &blkno);
+                           &blkno, wrp);
        } else {
                for (i = 0; i < UFS_NIADDR; i++)
                        print_indirblks32(iswap32(curinode->dp1.di_ib[i]), i,
-                           &blkno);
+                           &blkno, wrp);
        }
        return 0;
 }
@@ -728,7 +748,7 @@
                                if (founddatablk(iswap64(idblk[i])))
                                        return 1;
                        }
-                       if(idblk[i] != 0)
+                       if (idblk[i] != 0)
                                if (find_indirblks64(iswap64(idblk[i]),
                                    ind_level, wantedblk))
                                return 1;
@@ -738,20 +758,46 @@
        return 0;
 }
 
+static int
+writefileblk(struct wrinfo *wrp, uint64_t blk)
+{
+       char buf[MAXBSIZE];
+       long long size;
+
+       size = wrp->size - wrp->written_size;
+       if (size > sblock->fs_bsize)
+               size = sblock->fs_bsize;
+       if (size > (long long)sizeof buf) {
+               warnx("sblock->fs_bsize > MAX_BSIZE");
+               return -1;
+       }
+
+       if (bread(fsreadfd, buf, FFS_FSBTODB(sblock, blk), size) != 0)
+               return -1;
+       if (write(wrp->fd, buf, size) != size)
+               return -1;
+       wrp->written_size += size;
+       return 0;
+}
+
 
 #define CHARS_PER_LINES 70
 
 static void
-print_blks32(int32_t *buf, int size, uint64_t *blknum)
+print_blks32(int32_t *buf, int size, uint64_t *blknum, struct wrinfo *wrp)
 {
        int chars;
        char prbuf[CHARS_PER_LINES+1];
        int blk;
  
        chars = 0;
-       for(blk = 0; blk < size; blk++, (*blknum)++) {
+       for (blk = 0; blk < size; blk++, (*blknum)++) {
                if (buf[blk] == 0)
                        continue;
+               if (wrp && writefileblk(wrp, iswap32(buf[blk])) != 0) {
+                       warn("unable to write block %d", iswap32(buf[blk]));
+                       return;
+               }
                snprintf(prbuf, CHARS_PER_LINES, "%d ", iswap32(buf[blk]));
                if ((chars + strlen(prbuf)) > CHARS_PER_LINES) {
                        printf("\n");
@@ -766,16 +812,21 @@
 }
 
 static void
-print_blks64(int64_t *buf, int size, uint64_t *blknum)
+print_blks64(int64_t *buf, int size, uint64_t *blknum, struct wrinfo *wrp)
 {
        int chars;
        char prbuf[CHARS_PER_LINES+1];
        int blk;
  
        chars = 0;
-       for(blk = 0; blk < size; blk++, (*blknum)++) {
+       for (blk = 0; blk < size; blk++, (*blknum)++) {
                if (buf[blk] == 0)
                        continue;
+               if (wrp && writefileblk(wrp, iswap64(buf[blk])) != 0) {
+                       warn("unable to write block %lld",
+                            (long long)iswap64(buf[blk]));
+                       return;
+               }
                snprintf(prbuf, CHARS_PER_LINES, "%lld ",
                    (long long)iswap64(buf[blk]));
                if ((chars + strlen(prbuf)) > CHARS_PER_LINES) {
@@ -793,7 +844,7 @@
 #undef CHARS_PER_LINES
 
 static void
-print_indirblks32(uint32_t blk, int ind_level, uint64_t *blknum)
+print_indirblks32(uint32_t blk, int ind_level, uint64_t *blknum, struct wrinfo *wrp)
 {
 #define MAXNINDIR      (MAXBSIZE / sizeof(int32_t))
        const int ptrperblk_shift = sblock->fs_bshift - 2;
@@ -811,17 +862,18 @@
        bread(fsreadfd, (char *)idblk, FFS_FSBTODB(sblock, blk),
            (int)sblock->fs_bsize);
        if (ind_level <= 0) {
-               print_blks32(idblk, ptrperblk, blknum);
+               print_blks32(idblk, ptrperblk, blknum, wrp);
        } else {
                ind_level--;
                for (i = 0; i < ptrperblk; i++)
-                       print_indirblks32(iswap32(idblk[i]), ind_level, blknum);
+                       print_indirblks32(iswap32(idblk[i]), ind_level, blknum,
+                               wrp);
        }
 #undef MAXNINDIR
 }
 
 static void
-print_indirblks64(uint64_t blk, int ind_level, uint64_t *blknum)
+print_indirblks64(uint64_t blk, int ind_level, uint64_t *blknum, struct wrinfo *wrp)
 {
 #define MAXNINDIR      (MAXBSIZE / sizeof(int64_t))
        const int ptrperblk_shift = sblock->fs_bshift - 3;
@@ -839,11 +891,12 @@
        bread(fsreadfd, (char *)idblk, FFS_FSBTODB(sblock, blk),
            (int)sblock->fs_bsize);
        if (ind_level <= 0) {
-               print_blks64(idblk, ptrperblk, blknum);
+               print_blks64(idblk, ptrperblk, blknum, wrp);
        } else {
                ind_level--;
                for (i = 0; i < ptrperblk; i++)
-                       print_indirblks64(iswap64(idblk[i]), ind_level, blknum);
+                       print_indirblks64(iswap64(idblk[i]), ind_level, blknum,
+                               wrp);
        }
 #undef MAXNINDIR
 }



Home | Main Index | Thread Index | Old Index