From: Glen Overby Date: Thu, 6 May 2004 01:09:46 +0000 (+0000) Subject: Merge logprint dump and copy operations. X-Git-Tag: v2.7.0~102 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=873b7c853a9bdbaf4da74da2a16d3b3ac5914b1a;p=thirdparty%2Fxfsprogs-dev.git Merge logprint dump and copy operations. --- diff --git a/doc/CHANGES b/doc/CHANGES index 72383c687..2cfc4bb12 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,5 +1,11 @@ +[cvs] + - Allow logprint to copy a log to a file (-C) and to dump + a log from beginning to end showing ondisk log record (-d). + - Fix logprint handling of -f option - shouldn't be doing + the UUID check in that case, since we don't have the SB. + xfsprogs-2.6.13 (03 May 2004) - - zero out more at beginning and end of device at mkfs time + - Zero out more at beginning and end of device at mkfs time (get all old MD superblocks at the end, for mount by label). xfsprogs-2.6.12 (30 April 2004) diff --git a/include/libxlog.h b/include/libxlog.h index a5b067851..0eaf9279d 100644 --- a/include/libxlog.h +++ b/include/libxlog.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -122,19 +122,13 @@ typedef union { #define kmem_realloc(ptr, len, old, foo) realloc(ptr, len) /* exports */ -extern int print_record_header; extern int print_exit; +extern int print_skip_uuid; +extern int print_record_header; /* libxfs parameters */ extern libxfs_init_t x; -extern void xfs_log_print_trans(xlog_t *log, - int print_block_start); - -extern void xfs_log_print( xlog_t *log, - int fd, - int print_block_start); - extern int xlog_find_zeroed(xlog_t *log, xfs_daddr_t *blk_no); extern int xlog_find_cycle_start(xlog_t *log, xfs_buf_t *bp, xfs_daddr_t first_blk, xfs_daddr_t *last_blk, uint cycle); @@ -148,10 +142,6 @@ extern void xlog_recover_print_logitem(xlog_recover_item_t *item); extern void xlog_recover_print_trans_head(xlog_recover_t *tr); extern int xlog_print_find_oldest(xlog_t *log, xfs_daddr_t *last_blk); -extern void print_xlog_op_line(void); -extern void print_xlog_record_line(void); -extern void print_stars(void); - /* for transactional view */ extern void xlog_recover_print_trans_head(xlog_recover_t *tr); diff --git a/libxlog/util.c b/libxlog/util.c index 66a65803d..b2b574164 100644 --- a/libxlog/util.c +++ b/libxlog/util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2001,2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -33,6 +33,7 @@ #include int print_exit; +int print_skip_uuid; int print_record_header; libxfs_init_t x; @@ -41,6 +42,7 @@ header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head) { char uu_log[64], uu_sb[64]; + if (print_skip_uuid) return 0; if (!uuid_compare(mp->m_sb.sb_uuid, head->h_fs_uuid)) return 0; uuid_unparse(mp->m_sb.sb_uuid, uu_sb); diff --git a/logprint/Makefile b/logprint/Makefile index 2a6e35b6e..fdcdc3c50 100644 --- a/logprint/Makefile +++ b/logprint/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (c) 2000-2001,2004 Silicon Graphics, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of version 2 of the GNU General Public License as @@ -36,7 +36,10 @@ include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_logprint HFILES = logprint.h -CFILES = log_print_trans.c log_print_all.c log_misc.c logprint.c +CFILES = logprint.c \ + log_copy.c log_dump.c log_misc.c \ + log_print_all.c log_print_trans.c + LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) LLDFLAGS = -static diff --git a/logprint/log_copy.c b/logprint/log_copy.c new file mode 100644 index 000000000..374bbb52e --- /dev/null +++ b/logprint/log_copy.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include "logprint.h" + +/* + * Extract a log and write it out to a file + */ + +void +xfs_log_copy( + xlog_t *log, + int fd, + char *filename) +{ + int ofd, r; + xfs_daddr_t blkno; + char buf[XLOG_HEADER_SIZE]; + + if ((ofd = open(filename, O_CREAT|O_EXCL|O_RDWR|O_TRUNC, 0666)) == -1) { + perror("open"); + exit(1); + } + + xlog_print_lseek(log, fd, 0, SEEK_SET); + for (blkno = 0; blkno < log->l_logBBsize; blkno++) { + r = read(fd, buf, sizeof(buf)); + if (r < 0) { + fprintf(stderr, "%s: read error (%lld): %s\n", + __FUNCTION__, (long long)blkno, + strerror(errno)); + continue; + } else if (r == 0) { + printf("%s: physical end of log at %lld\n", + __FUNCTION__, (long long)blkno); + break; + } else if (r != sizeof(buf)) { + fprintf(stderr, "%s: short read? (%lld)\n", + __FUNCTION__, (long long)blkno); + continue; + } + + r = write(ofd, buf, sizeof(buf)); + if (r < 0) { + fprintf(stderr, "%s: write error (%lld): %s\n", + __FUNCTION__, (long long)blkno, + strerror(errno)); + break; + } else if (r != sizeof(buf)) { + fprintf(stderr, "%s: short write? (%lld)\n", + __FUNCTION__, (long long)blkno); + continue; + } + } + + close(ofd); +} diff --git a/logprint/log_dump.c b/logprint/log_dump.c new file mode 100644 index 000000000..cd48b2581 --- /dev/null +++ b/logprint/log_dump.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include "logprint.h" + +/* + * Dump log blocks, not data + */ + +void +xfs_log_dump( + xlog_t *log, + int fd, + int print_block_start) +{ + int r; + uint last_cycle = -1; + xfs_daddr_t blkno, dupblkno; + xlog_rec_header_t *hdr; + char buf[XLOG_HEADER_SIZE]; + + dupblkno = 0; + hdr = (xlog_rec_header_t *)buf; + xlog_print_lseek(log, fd, 0, SEEK_SET); + for (blkno = 0; blkno < log->l_logBBsize; blkno++) { + r = read(fd, buf, sizeof(buf)); + if (r < 0) { + fprintf(stderr, "%s: read error (%lld): %s\n", + __FUNCTION__, (long long)blkno, + strerror(errno)); + continue; + } else if (r == 0) { + printf("%s: physical end of log at %lld\n", + __FUNCTION__, (long long)blkno); + break; + } + + if (CYCLE_LSN(buf, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM && + !print_no_data) { + printf( + "%6lld HEADER Cycle %d tail %d:%06d len %6d ops %d\n", + (long long)blkno, + INT_GET(hdr->h_cycle, ARCH_CONVERT), + CYCLE_LSN(hdr->h_tail_lsn, ARCH_CONVERT), + BLOCK_LSN(hdr->h_tail_lsn, ARCH_CONVERT), + INT_GET(hdr->h_len, ARCH_CONVERT), + INT_GET(hdr->h_num_logops, ARCH_CONVERT)); + } + + if (GET_CYCLE(buf, ARCH_CONVERT) != last_cycle) { + printf( + "[%05lld - %05lld] Cycle 0x%08x New Cycle 0x%08x\n", + (long long)dupblkno, (long long)blkno, + last_cycle, GET_CYCLE(buf, ARCH_CONVERT)); + last_cycle = GET_CYCLE(buf, ARCH_CONVERT); + dupblkno = blkno; + } + } +} diff --git a/logprint/logprint.c b/logprint/logprint.c index 7cda29b71..3aae61ef9 100644 --- a/logprint/logprint.c +++ b/logprint/logprint.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -34,18 +34,21 @@ #include #include +#define OP_PRINT 0 +#define OP_PRINT_TRANS 1 +#define OP_DUMP 2 +#define OP_COPY 3 + int print_data; int print_only_data; int print_inode; int print_quota; int print_buffer; -int print_transactions; int print_overwrite; int print_no_data; int print_no_print; int print_exit = 1; /* -e is now default. specify -c to override */ - -xfs_mount_t mp; +int print_operation = OP_PRINT; void usage(void) @@ -53,6 +56,8 @@ usage(void) fprintf(stderr, "Usage: %s [options...] \n\n\ Options:\n\ -c try to continue if error found in log\n\ + -C copy the log from the filesystem to filename\n\ + -d dump the log in log-record format\n\ -f specified device is actually a file\n\ -l filename of external log\n\ -n don't try and interpret log data\n\ @@ -70,7 +75,7 @@ Options:\n\ } int -logstat(libxfs_init_t *x) +logstat(xfs_mount_t *mp) { int fd; char buf[BBSIZE]; @@ -80,9 +85,9 @@ logstat(libxfs_init_t *x) * filesystem. We need this to get the length of the * log. Otherwise we end up seeking forever. -- mkp */ - if ((fd = open(x->dname, O_RDONLY)) == -1) { + if ((fd = open(x.dname, O_RDONLY)) == -1) { fprintf(stderr, " Can't open device %s: %s\n", - x->dname, strerror(errno)); + x.dname, strerror(errno)); exit(1); } lseek64(fd, 0, SEEK_SET); @@ -92,17 +97,17 @@ logstat(libxfs_init_t *x) } close (fd); - if (!x->disfile) { + if (!x.disfile) { /* * Conjure up a mount structure */ - libxfs_xlate_sb(buf, &(mp.m_sb), 1, ARCH_CONVERT, XFS_SB_ALL_BITS); - sb = &(mp.m_sb); - mp.m_blkbb_log = sb->sb_blocklog - BBSHIFT; + libxfs_xlate_sb(buf, &(mp->m_sb), 1, ARCH_CONVERT, XFS_SB_ALL_BITS); + sb = &(mp->m_sb); + mp->m_blkbb_log = sb->sb_blocklog - BBSHIFT; - x->logBBsize = XFS_FSB_TO_BB(&mp, sb->sb_logblocks); - x->logBBstart = XFS_FSB_TO_DADDR(&mp, sb->sb_logstart); - if (!x->logname && sb->sb_logstart == 0) { + x.logBBsize = XFS_FSB_TO_BB(mp, sb->sb_logblocks); + x.logBBstart = XFS_FSB_TO_DADDR(mp, sb->sb_logstart); + if (!x.logname && sb->sb_logstart == 0) { fprintf(stderr, " external log device not specified\n\n"); usage(); /*NOTREACHED*/ @@ -110,21 +115,21 @@ logstat(libxfs_init_t *x) } else { struct stat s; - stat(x->dname, &s); - x->logBBsize = s.st_size >> 9; - x->logBBstart = 0; + stat(x.dname, &s); + x.logBBsize = s.st_size >> 9; + x.logBBstart = 0; } - if (x->logname && *x->logname) { /* External log */ - if ((fd = open(x->logname, O_RDONLY)) == -1) { + if (x.logname && *x.logname) { /* External log */ + if ((fd = open(x.logname, O_RDONLY)) == -1) { fprintf(stderr, "Can't open file %s: %s\n", - x->logname, strerror(errno)); + x.logname, strerror(errno)); exit(1); } close(fd); } else { /* Internal log */ - x->logdev = x->ddev; + x.logdev = x.ddev; } return 0; @@ -136,77 +141,72 @@ main(int argc, char **argv) int print_start = -1; int c; int logfd; + char *copy_file = NULL; xlog_t log = {0}; + xfs_mount_t mount; progname = basename(argv[0]); - while ((c = getopt(argc, argv, "befl:iqnors:tDVvc")) != EOF) { + while ((c = getopt(argc, argv, "bC:cdefl:iqnors:tDVv")) != EOF) { switch (c) { - case 'D': { + case 'D': print_only_data++; print_data++; break; - } - case 'b': { + case 'b': print_buffer++; break; - } - case 'f': { - x.disfile = 1; - break; - } - case 'l': { - x.logname = optarg; - x.lisfile = 1; - break; - } - case 'c': { + case 'c': /* default is to stop on error. * -c turns this off. */ - print_exit=0; + print_exit = 0; break; - } - case 'e': { + case 'e': /* -e is now default */ print_exit++; break; - } - case 'i': { + case 'C': + print_operation = OP_COPY; + copy_file = optarg; + break; + case 'd': + print_operation = OP_DUMP; + break; + case 'f': + print_skip_uuid++; + x.disfile = 1; + break; + case 'l': + x.logname = optarg; + x.lisfile = 1; + break; + case 'i': print_inode++; break; - } - case 'q': { + case 'q': print_quota++; break; - } - case 'n': { + case 'n': print_no_data++; break; - } - case 'o': { + case 'o': print_data++; break; - } - case 's': { + case 's': print_start = atoi(optarg); break; - } - case 't': { - print_transactions++; + case 't': + print_operation = OP_PRINT_TRANS; break; - } - case 'V': { - printf("%s version %s\n", progname, VERSION); - exit(0); - } - case 'v': { + case 'v': print_overwrite++; break; - } - case '?': { + case 'V': + printf("%s version %s\n", progname, VERSION); + exit(0); + case '?': usage(); - } } } @@ -226,9 +226,9 @@ main(int argc, char **argv) if (!libxfs_init(&x)) exit(1); - logstat(&x); + logstat(&mount); - logfd=(x.logfd<0)?(x.dfd):(x.logfd); + logfd = (x.logfd < 0) ? x.dfd : x.logfd; printf(" data device: 0x%llx\n", (unsigned long long)x.ddev); @@ -243,17 +243,25 @@ main(int argc, char **argv) ASSERT(x.logBBsize <= INT_MAX); - /* init log structure */ - log.l_dev = x.logdev; + log.l_dev = x.logdev; log.l_logsize = BBTOB(x.logBBsize); log.l_logBBstart = x.logBBstart; log.l_logBBsize = x.logBBsize; - log.l_mp = ∓ + log.l_mp = &mount; - if (print_transactions) + switch (print_operation) { + case OP_PRINT: xfs_log_print_trans(&log, print_start); - else + break; + case OP_PRINT_TRANS: xfs_log_print(&log, logfd, print_start); - + break; + case OP_DUMP: + xfs_log_dump(&log, logfd, print_start); + break; + case OP_COPY: + xfs_log_copy(&log, logfd, copy_file); + break; + } exit(0); } diff --git a/logprint/logprint.h b/logprint/logprint.h index 0c971699c..0138b5e3c 100644 --- a/logprint/logprint.h +++ b/logprint/logprint.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2001,2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -48,4 +48,15 @@ extern int print_no_print; /* exports */ extern char *trans_type[]; +extern void xlog_print_lseek(xlog_t *, int, xfs_daddr_t, int); + +extern void xfs_log_copy(xlog_t *, int, char *); +extern void xfs_log_dump(xlog_t *, int, int); +extern void xfs_log_print(xlog_t *, int, int); +extern void xfs_log_print_trans(xlog_t *, int); + +extern void print_xlog_record_line(void); +extern void print_xlog_op_line(void); +extern void print_stars(void); + #endif /* LOGPRINT_H */ diff --git a/man/man8/xfs_logprint.8 b/man/man8/xfs_logprint.8 index a915044f5..24fbe90bf 100644 --- a/man/man8/xfs_logprint.8 +++ b/man/man8/xfs_logprint.8 @@ -45,9 +45,16 @@ Common options are: Extract and print buffer information. Only used in transactional view. .TP +\f3\-C\f1 \f2filename\f1 +Copy the log from the filesystem to the file \f2filename\f1. +The log itself is not printed. +.TP +\f3\-d\f1 +Dump the log from front to end, printing where each log record is located +on disk. +.TP \f3\-D\f1 -Don't decode anything; -just print data. +Do not decode anything; just print data. .TP \f3\-e\f1 Exit when an error is found in the log. @@ -73,8 +80,7 @@ Extract and print quota information. Only used in transactional view. .TP \f3\-n\f1 -Don't try and interpret log data; -just interpret log header information. +Do not try and interpret log data; just interpret log header information. .TP \f3\-o\f1 Also print buffer data in hex.