@@ -49,6 +49,8 @@ extern void push_cur_and_set_type(void);
extern void write_cur(void);
extern void set_cur(const struct typ *type, xfs_daddr_t blknum,
int len, int ring_add, bbmap_t *bbmap);
+extern void set_log_cur(const struct typ *type, xfs_daddr_t blknum,
+ int len, int ring_add, bbmap_t *bbmap);
extern void ring_add(void);
extern void set_iocur_type(const struct typ *type);
extern void xfs_dummy_verify(struct xfs_buf *bp);
@@ -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);
}
@@ -2907,8 +2909,9 @@ 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);
+ 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);
if (iocur_top->data == NULL) {
pop_cur();
print_warning("cannot read log");
@@ -3069,6 +3072,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);
@@ -3129,6 +3134,7 @@ metadump_f(
int outfd = -1;
int ret;
char *p;
+ bool version_opt_set = false;
exitcode = 1;
@@ -3140,6 +3146,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",
@@ -3157,7 +3164,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;
@@ -3181,6 +3188,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;
@@ -3195,10 +3213,27 @@ 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],
+ 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);
if (iocur_top->data) { /* best effort */
@@ -3276,8 +3311,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.