@@ -37,7 +37,7 @@ static void metadump_help(void);
static const cmdinfo_t metadump_cmd =
{ "metadump", NULL, metadump_f, 0, -1, 0,
- N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] filename"),
+ N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] [-v 1|2] filename"),
N_("dump metadata to a file"), metadump_help };
struct metadump_ops {
@@ -74,6 +74,7 @@ static struct metadump {
bool zero_stale_data;
bool progress_since_warning;
bool dirty_log;
+ bool external_log;
bool stdout_metadump;
xfs_ino_t cur_ino;
/* Metadump file */
@@ -107,6 +108,7 @@ metadump_help(void)
" -g -- Display dump progress\n"
" -m -- Specify max extent size in blocks to copy (default = %d blocks)\n"
" -o -- Don't obfuscate names and extended attributes\n"
+" -v -- Metadump version to be used\n"
" -w -- Show warnings of bad metadata information\n"
"\n"), DEFAULT_MAX_EXT_SIZE);
}
@@ -2909,8 +2911,20 @@ copy_log(void)
print_progress("Copying log");
push_cur();
- set_cur(&typtab[TYP_LOG], XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
- mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
+ if (metadump.external_log) {
+ ASSERT(mp->m_sb.sb_logstart == 0);
+ set_log_cur(&typtab[TYP_LOG],
+ XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
+ mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
+ NULL);
+ } else {
+ ASSERT(mp->m_sb.sb_logstart != 0);
+ set_cur(&typtab[TYP_LOG],
+ XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
+ mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
+ NULL);
+ }
+
if (iocur_top->data == NULL) {
pop_cur();
print_warning("cannot read log");
@@ -3071,6 +3085,8 @@ init_metadump_v2(void)
compat_flags |= XFS_MD2_INCOMPAT_FULLBLOCKS;
if (metadump.dirty_log)
compat_flags |= XFS_MD2_INCOMPAT_DIRTYLOG;
+ if (metadump.external_log)
+ compat_flags |= XFS_MD2_INCOMPAT_EXTERNALLOG;
xmh.xmh_compat_flags = cpu_to_be32(compat_flags);
@@ -3131,6 +3147,7 @@ metadump_f(
int outfd = -1;
int ret;
char *p;
+ bool version_opt_set = false;
exitcode = 1;
@@ -3142,6 +3159,7 @@ metadump_f(
metadump.obfuscate = true;
metadump.zero_stale_data = true;
metadump.dirty_log = false;
+ metadump.external_log = false;
if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
print_warning("bad superblock magic number %x, giving up",
@@ -3159,7 +3177,7 @@ metadump_f(
return 0;
}
- while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
+ while ((c = getopt(argc, argv, "aegm:ov:w")) != EOF) {
switch (c) {
case 'a':
metadump.zero_stale_data = false;
@@ -3183,6 +3201,17 @@ metadump_f(
case 'o':
metadump.obfuscate = false;
break;
+ case 'v':
+ metadump.version = (int)strtol(optarg, &p, 0);
+ if (*p != '\0' ||
+ (metadump.version != 1 &&
+ metadump.version != 2)) {
+ print_warning("bad metadump version: %s",
+ optarg);
+ return 0;
+ }
+ version_opt_set = true;
+ break;
case 'w':
metadump.show_warnings = true;
break;
@@ -3197,12 +3226,42 @@ metadump_f(
return 0;
}
- /* If we'll copy the log, see if the log is dirty */
- if (mp->m_sb.sb_logstart) {
+ if (mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
+ metadump.external_log = true;
+
+ if (metadump.external_log && !version_opt_set)
+ metadump.version = 2;
+
+ if (metadump.version == 2 && mp->m_sb.sb_logstart == 0 &&
+ !metadump.external_log) {
+ print_warning("external log device not loaded, use -l");
+ return -ENODEV;
+ }
+
+ /*
+ * If we'll copy the log, see if the log is dirty.
+ *
+ * Metadump v1 does not support dumping the contents of an external
+ * log. Hence we skip the dirty log check.
+ */
+ if (!(metadump.version == 1 && metadump.external_log)) {
push_cur();
- set_cur(&typtab[TYP_LOG],
- XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
- mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
+ if (metadump.external_log) {
+ ASSERT(mp->m_sb.sb_logstart == 0);
+ set_log_cur(&typtab[TYP_LOG],
+ XFS_FSB_TO_DADDR(mp,
+ mp->m_sb.sb_logstart),
+ mp->m_sb.sb_logblocks * blkbb,
+ DB_RING_IGN, NULL);
+ } else {
+ ASSERT(mp->m_sb.sb_logstart != 0);
+ set_cur(&typtab[TYP_LOG],
+ XFS_FSB_TO_DADDR(mp,
+ mp->m_sb.sb_logstart),
+ mp->m_sb.sb_logblocks * blkbb,
+ DB_RING_IGN, NULL);
+ }
+
if (iocur_top->data) { /* best effort */
struct xlog log;
@@ -3278,8 +3337,8 @@ metadump_f(
if (!exitcode)
exitcode = !copy_sb_inodes();
- /* copy log if it's internal */
- if ((mp->m_sb.sb_logstart != 0) && !exitcode)
+ /* copy log */
+ if (!exitcode && !(metadump.version == 1 && metadump.external_log))
exitcode = !copy_log();
/* write the remaining index */
@@ -8,7 +8,7 @@ OPTS=" "
DBOPTS=" "
USAGE="Usage: xfs_metadump [-aefFogwV] [-m max_extents] [-l logdev] source target"
-while getopts "aefgl:m:owFV" c
+while getopts "aefgl:m:owFv:V" c
do
case $c in
a) OPTS=$OPTS"-a ";;
@@ -20,6 +20,7 @@ do
f) DBOPTS=$DBOPTS" -f";;
l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
F) DBOPTS=$DBOPTS" -F";;
+ v) OPTS=$OPTS"-v "$OPTARG" ";;
V) xfs_db -p xfs_metadump -V
status=$?
exit $status
@@ -11,6 +11,9 @@ xfs_metadump \- copy XFS filesystem metadata to a file
] [
.B \-l
.I logdev
+] [
+.B \-v
+.I version
]
.I source
.I target
@@ -74,6 +77,12 @@ metadata such as filenames is not considered sensitive. If obfuscation
is required on a metadump with a dirty log, please inform the recipient
of the metadump image about this situation.
.PP
+The contents of an external log device can be dumped only when using the v2
+format.
+Metadump in v2 format can be generated by passing the "-v 2" option.
+Metadump in v2 format is generated by default if the filesystem has an
+external log and the metadump version to use is not explicitly mentioned.
+.PP
.B xfs_metadump
should not be used for any purposes other than for debugging and reporting
filesystem problems. The most common usage scenario for this tool is when
@@ -134,6 +143,11 @@ this value. The default size is 2097151 blocks.
.B \-o
Disables obfuscation of file names and extended attributes.
.TP
+.B \-v
+The format of the metadump file to be produced.
+Valid values are 1 and 2.
+The default metadump format is 1.
+.TP
.B \-w
Prints warnings of inconsistent metadata encountered to stderr. Bad metadata
is still copied.
The new option allows the user to explicitly specify the version of metadump to use. However, we will default to using the v1 format. Signed-off-by: Chandan Babu R <chandan.babu@oracle.com> --- db/metadump.c | 81 +++++++++++++++++++++++++++++++++++------ db/xfs_metadump.sh | 3 +- man/man8/xfs_metadump.8 | 14 +++++++ 3 files changed, 86 insertions(+), 12 deletions(-)