imports CS xfsdump-3.1.8-7.el8 remove unnecessary patches

This commit is contained in:
eabdullin 2023-11-08 13:37:12 +03:00
parent 1e143e12ab
commit 4f4eca7e51
7 changed files with 859 additions and 1 deletions

View File

@ -0,0 +1,286 @@
From d7cba7410710cd3ec2c2d9fafd4d93437097f473 Mon Sep 17 00:00:00 2001
From: Gao Xiang <hsiangkao@redhat.com>
Date: Wed, 28 Sep 2022 15:10:52 -0400
Subject: [PATCH] xfsrestore: fix rootdir due to xfsdump bulkstat misuse
If rootino is wrong and misspecified to a subdir inode #,
the following assertion could be triggered:
assert(ino != persp->p_rootino || hardh == persp->p_rooth);
This patch adds a '-x' option (another awkward thing is that
the codebase doesn't support long options) to address
problamatic images by searching for the real dir, the reason
that I don't enable it by default is that I'm not very confident
with the xfsrestore codebase and xfsdump bulkstat issue will
also be fixed immediately as well, so this function might be
optional and only useful for pre-exist corrupted dumps.
In details, my understanding of the original logic is
1) xfsrestore will create a rootdir node_t (p_rooth);
2) it will build the tree hierarchy from inomap and adopt
the parent if needed (so inodes whose parent ino hasn't
detected will be in the orphan dir, p_orphh);
3) during this period, if ino == rootino and
hardh != persp->p_rooth (IOWs, another node_t with
the same ino # is created), that'd be definitely wrong.
So the proposal fix is that
- considering the xfsdump root ino # is a subdir inode, it'll
trigger ino == rootino && hardh != persp->p_rooth condition;
- so we log this node_t as persp->p_rooth rather than the
initial rootdir node_t created in 1);
- we also know that this node is actually a subdir, and after
the whole inomap is scanned (IOWs, the tree is built),
the real root dir will have the orphan dir parent p_orphh;
- therefore, we walk up by the parent until some node_t has
the p_orphh, so that's it.
Cc: Donald Douwsma <ddouwsma@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
Signed-off-by: Hironori Shiina <shiina.hironori@fujitsu.com>
Reviwed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
common/main.c | 1 +
man/man8/xfsrestore.8 | 14 +++++++++
restore/content.c | 7 +++++
restore/getopt.h | 4 +--
restore/tree.c | 72 ++++++++++++++++++++++++++++++++++++++++---
restore/tree.h | 2 ++
6 files changed, 94 insertions(+), 6 deletions(-)
diff --git a/common/main.c b/common/main.c
index 1db07d4..6141ffb 100644
--- a/common/main.c
+++ b/common/main.c
@@ -984,6 +984,7 @@
ULO(_("(contents only)"), GETOPT_TOC );
ULO(_("<verbosity {silent, verbose, trace}>"), GETOPT_VERBOSITY );
ULO(_("(use small tree window)"), GETOPT_SMALLWINDOW );
+ ULO(_("(try to fix rootdir due to xfsdump issue)"),GETOPT_FIXROOTDIR);
ULO(_("(don't restore extended file attributes)"),GETOPT_NOEXTATTR );
ULO(_("(restore root dir owner/permissions)"), GETOPT_ROOTPERM );
ULO(_("(restore DMAPI event settings)"), GETOPT_SETDM );
diff --git a/man/man8/xfsrestore.8 b/man/man8/xfsrestore.8
index 60e4309..df7dde0 100644
--- a/man/man8/xfsrestore.8
+++ b/man/man8/xfsrestore.8
@@ -240,6 +240,20 @@ but does not create or modify any files or directories.
It may be desirable to set the verbosity level to \f3silent\f1
when using this option.
.TP 5
+.B \-x
+This option may be useful to fix an issue which the files are restored
+to orphanage directory because of xfsdump (v3.1.7 - v3.1.9) problem.
+A normal dump cannot be restored with this option. This option works
+only for a corrupted dump.
+If a dump is created by problematic xfsdump (v3.1.7 - v3.1.9), you
+should see the contents of the dump with \f3\-t\f1 option before
+restoring. Then, if a file is placed to the orphanage directory, you need to
+use this \f3\-x\f1 option to restore the dump. Otherwise, you can restore
+the dump without this option.
+
+In the cumulative mode, this option is required only for a base (level 0)
+dump. You no longer need this option for level 1+ dumps.
+.TP 5
\f3\-v\f1 \f2verbosity\f1
.\" set inter-paragraph distance to 0
.PD 0
diff --git a/restore/content.c b/restore/content.c
index 8bb5fa4..488ae20 100644
--- a/restore/content.c
+++ b/restore/content.c
@@ -861,6 +861,7 @@ static int quotafilecheck(char *type, char *dstdir, char *quotafile);
bool_t content_media_change_needed;
bool_t restore_rootdir_permissions;
+bool_t need_fixrootdir;
char *media_change_alert_program = NULL;
size_t perssz;
@@ -964,6 +964,7 @@
firststsensepr = firststsenseprvalpr = BOOL_FALSE;
stsz = 0;
interpr = BOOL_FALSE;
+ need_fixrootdir = BOOL_FALSE;
restore_rootdir_permissions = BOOL_FALSE;
optind = 1;
opterr = 0;
@@ -1186,6 +1188,9 @@ content_init(int argc, char *argv[], size64_t vmsz)
case GETOPT_FMT2COMPAT:
tranp->t_truncategenpr = BOOL_TRUE;
break;
+ case GETOPT_FIXROOTDIR:
+ need_fixrootdir = BOOL_TRUE;
+ break;
}
}
@@ -3129,6 +3134,8 @@ applydirdump(drive_t *drivep,
return rv;
}
+ if (need_fixrootdir)
+ tree_fixroot();
persp->s.dirdonepr = BOOL_TRUE;
}
diff --git a/restore/getopt.h b/restore/getopt.h
index b5bc004..b0c0c7d 100644
--- a/restore/getopt.h
+++ b/restore/getopt.h
@@ -26,7 +26,7 @@
* purpose is to contain that command string.
*/
-#define GETOPT_CMDSTRING "a:b:c:def:himn:op:qrs:tv:wABCDEFG:H:I:JKL:M:NO:PQRS:TUVWX:Y:"
+#define GETOPT_CMDSTRING "a:b:c:def:himn:op:qrs:tv:wxABCDEFG:H:I:JKL:M:NO:PQRS:TUVWX:Y:"
#define GETOPT_WORKSPACE 'a' /* workspace dir (content.c) */
#define GETOPT_BLOCKSIZE 'b' /* blocksize for rmt */
@@ -51,7 +51,7 @@
/* 'u' */
#define GETOPT_VERBOSITY 'v' /* verbosity level (0 to 4 ) */
#define GETOPT_SMALLWINDOW 'w' /* use a small window for dir entries */
-/* 'x' */
+#define GETOPT_FIXROOTDIR 'x' /* try to fix rootdir due to bulkstat misuse */
/* 'y' */
/* 'z' */
#define GETOPT_NOEXTATTR 'A' /* do not restore ext. file attr. */
diff --git a/restore/tree.c b/restore/tree.c
index 5429b74..bfa07fe 100644
--- a/restore/tree.c
+++ b/restore/tree.c
@@ -15,7 +15,6 @@
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
@@ -262,6 +261,7 @@ extern void usage(void);
extern size_t pgsz;
extern size_t pgmask;
extern bool_t restore_rootdir_permissions;
+extern bool_t need_fixrootdir;
/* forward declarations of locally defined static functions ******************/
@@ -331,9 +331,45 @@
static char *persname = PERS_NAME;
static char *orphname = ORPH_NAME;
static xfs_ino_t orphino = ORPH_INO;
-
+static nh_t orig_rooth = NH_NULL;
/* definition of locally defined global functions ****************************/
+
+void
+tree_fixroot(void)
+{
+ nh_t rooth = persp->p_rooth;
+ xfs_ino_t rootino;
+
+ while (1) {
+ nh_t parh;
+ node_t *rootp = Node_map(rooth);
+
+ rootino = rootp->n_ino;
+ parh = rootp->n_parh;
+ Node_unmap(rooth, &rootp);
+
+ if (parh == rooth ||
+ /*
+ * since all new node (including non-parent)
+ * would be adopted into orphh
+ */
+ parh == persp->p_orphh ||
+ parh == NH_NULL)
+ break;
+ rooth = parh;
+ }
+
+ if (rooth != persp->p_rooth) {
+ persp->p_rooth = rooth;
+ persp->p_rootino = rootino;
+ disown(rooth);
+ adopt(persp->p_rooth, persp->p_orphh, NH_NULL);
+
+ mlog(MLOG_NORMAL, _("fix root # to %llu (bind mount?)\n"),
+ rootino);
+ }
+}
/* ARGSUSED */
bool_t
@@ -754,7 +790,8 @@
/* lookup head of hardlink list
*/
hardh = link_hardh( ino, gen );
- assert( ino != persp->p_rootino || hardh == persp->p_rooth );
+ if (need_fixrootdir == BOOL_FALSE)
+ assert( ino != persp->p_rootino || hardh == persp->p_rooth );
/* already present
*/
@@ -1156,6 +1156,13 @@
ino,
gen );
}
+ /* found the fake rootino from subdir, need fix p_rooth. */
+ if (need_fixrootdir == BOOL_TRUE &&
+ persp->p_rootino == ino && hardh != persp->p_rooth) {
+ mlog(MLOG_NORMAL,
+ _("found fake rootino #%llu, will fix.\n"), ino);
+ persp->p_rooth = hardh;
+ }
return RV_OK;
}
@@ -3841,7 +3885,26 @@
static nh_t
link_hardh( xfs_ino_t ino, gen_t gen )
{
- return hash_find( ino, gen );
+ nh_t tmp = hash_find(ino, gen);
+
+ /*
+ * XXX (another workaround): the simply way is that don't reuse node_t
+ * with gen = 0 created in tree_init(). Otherwise, it could cause
+ * xfsrestore: tree.c:1003: tree_addent: Assertion
+ * `hardp->n_nrh != NRH_NULL' failed.
+ * and that node_t is a dir node but the fake rootino could be a non-dir
+ * plus reusing it could cause potential loop in tree hierarchy.
+ */
+ if (need_fixrootdir == BOOL_TRUE &&
+ ino == persp->p_rootino && gen == 0 &&
+ orig_rooth == NH_NULL) {
+ mlog(MLOG_NORMAL,
+_("link out fake rootino %llu with gen=0 created in tree_init()\n"), ino);
+ link_out(tmp);
+ orig_rooth = tmp;
+ return NH_NULL;
+ }
+ return tmp;
}
/* returns following node in hard link list
diff --git a/restore/tree.h b/restore/tree.h
index bf66e3d..f5bd4ff 100644
--- a/restore/tree.h
+++ b/restore/tree.h
@@ -18,6 +18,8 @@
#ifndef TREE_H
#define TREE_H
+void tree_fixroot(void);
+
/* tree_init - creates a new tree abstraction.
*/
extern bool_t tree_init( char *hkdir,
--
2.41.0

View File

@ -0,0 +1,149 @@
From 06dd184d3a689dcb33a50b6e3576e48055e48133 Mon Sep 17 00:00:00 2001
From: Donald Douwsma <ddouwsma@redhat.com>
Date: Fri, 14 Oct 2022 18:58:44 +1100
Subject: [PATCH 1/4] xfsrestore: fix on-media inventory media unpacking
When xfsrestore reads the inventory from tape media it fails to convert
media file records from bigendian. If the xfsdump inventory is not
available xfsrestore will write this invalid record to the on-line
inventory.
[root@rhel8 ~]# xfsdump -L Test1 -M "" -f /dev/st0 /boot > /dev/null
[root@rhel8 ~]# xfsdump -L Test2 -M "" -f /dev/st0 /boot > /dev/null
[root@rhel8 ~]# rm -rf /var/lib/xfsdump/inventory/
[root@rhel8 ~]# mt -f /dev/nst0 asf 2
[root@rhel8 ~]# xfsrestore -f /dev/nst0 -L Test2 /tmp/test2
xfsrestore: using scsi tape (drive_scsitape) strategy
xfsrestore: version 3.1.8 (dump format 3.0) - type ^C for status and control
xfsrestore: searching media for dump
xfsrestore: preparing drive
xfsrestore: examining media file 3
xfsrestore: found dump matching specified label:
xfsrestore: hostname: rhel8
xfsrestore: mount point: /boot
xfsrestore: volume: /dev/sda1
xfsrestore: session time: Tue Sep 27 16:05:28 2022
xfsrestore: level: 0
xfsrestore: session label: "Test2"
xfsrestore: media label: ""
xfsrestore: file system id: 26dd5aa0-b901-4cf5-9b68-0c5753cb3ab8
xfsrestore: session id: 62402423-7ae0-49ed-8ecb-9e5bc7642b91
xfsrestore: media id: 47ba45ca-3417-4006-ab10-3dc6419b83e2
xfsrestore: incorporating on-media session inventory into online inventory
xfsrestore: /var/lib/xfsdump/inventory created
xfsrestore: using on-media session inventory
xfsrestore: searching media for directory dump
xfsrestore: rewinding
xfsrestore: examining media file 0
xfsrestore: inventory session uuid (62402423-7ae0-49ed-8ecb-9e5bc7642b91) does not match the media header's session uuid (1771d9e8-a1ba-4e87-a61e-f6be97e41b45)
xfsrestore: examining media file 1
xfsrestore: inventory session uuid (62402423-7ae0-49ed-8ecb-9e5bc7642b91) does not match the media header's session uuid (1771d9e8-a1ba-4e87-a61e-f6be97e41b45)
xfsrestore: examining media file 2
xfsrestore: reading directories
xfsrestore: 9 directories and 320 entries processed
xfsrestore: directory post-processing
xfsrestore: restore complete: 0 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore: stream 0 /dev/nst0 OK (success)
xfsrestore: Restore Status: SUCCESS
[root@rhel8 ~]# xfsdump -I
file system 0:
fs id: 26dd5aa0-b901-4cf5-9b68-0c5753cb3ab8
session 0:
mount point: rhel8:/boot
device: rhel8:/dev/sda1
time: Tue Sep 27 16:05:28 2022
session label: "Test2"
session id: 62402423-7ae0-49ed-8ecb-9e5bc7642b91
level: 0
resumed: NO
subtree: NO
streams: 1
stream 0:
pathname: /dev/st0
start: ino 133 offset 0
end: ino 1572997 offset 0
interrupted: YES
media files: 1
media file 0:
mfile index: 33554432
mfile type: data
mfile size: 211187836911616
mfile start: ino 9583660007044415488 offset 0
mfile end: ino 9583686395323482112 offset 0
media label: ""
media id: 47ba45ca-3417-4006-ab10-3dc6419b83e2
xfsdump: Dump Status: SUCCESS
[root@rhel8 ~]#
[root@rhel8 ~]# ls /tmp/test2
efi grub2 loader
The invalid start and end inode information cause xfsrestore to consider
that non-directory files do not reside in the current media and will
fail to restore them.
The behaviour of an initial restore may succeed if the position of the
tape is such that the data file is encountered before the inventory
file, or if there is only one dump session on tape, xfsrestore is
somewhat inconsistent in this regard. Subsequent restores will use the
invalid on-line inventory and fail to restore files.
Fix this by correctly unpacking the inventory data.
Signed-off-by: Donald Douwsma <ddouwsma@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
inventory/inv_stobj.c | 27 +++++++--------------------
1 file changed, 7 insertions(+), 20 deletions(-)
diff --git a/inventory/inv_stobj.c b/inventory/inv_stobj.c
index e2e8767..cdf3300 100644
--- a/inventory/inv_stobj.c
+++ b/inventory/inv_stobj.c
@@ -1008,7 +1008,7 @@
size_t bufsz,
invt_sessinfo_t *s )
{
- uint i;
+ uint i, j;
char *tmpbuf;
char *p = (char *)bufp;
@@ -1087,26 +1087,13 @@
/* all the media files */
s->mfiles = (invt_mediafile_t *)p;
-
-#ifdef INVT_DELETION
- {
- int tmpfd = open( "moids", O_RDWR | O_CREAT, S_IRUSR|S_IWUSR );
- uint j;
- invt_mediafile_t *mmf = s->mfiles;
- for (i=0; i< s->ses->s_cur_nstreams; i++ ) {
- for (j=0; j< s->strms[ i ].st_nmediafiles;
- j++, mmf++ )
- xlate_invt_mediafile((invt_mediafile_t *)mmf, (invt_mediafile_t *)tmpbuf, 1);
- bcopy(tmpbuf, mmf, sizeof(invt_mediafile_t));
- put_invtrecord( tmpfd, &mmf->mf_moid,
- sizeof( uuid_t ), 0, SEEK_END, 0 );
- }
- close( tmpfd );
- }
-#endif
for ( i = 0; i < s->ses->s_cur_nstreams; i++ ) {
- p += (size_t) ( s->strms[ i ].st_nmediafiles )
- * sizeof( invt_mediafile_t );
+ for(j = 0; j < s->strms[i].st_nmediafiles; j++) {
+ xlate_invt_mediafile((invt_mediafile_t *)p,
+ (invt_mediafile_t *)tmpbuf, 1);
+ bcopy(tmpbuf, p, sizeof(invt_mediafile_t));
+ p += sizeof(invt_mediafile_t);
+ }
}
/* sanity check the size of the buffer given to us vs. the size it
--
2.41.0

View File

@ -0,0 +1,204 @@
From 65034077ef03c434c09c88d38c4c58ec442cf3c1 Mon Sep 17 00:00:00 2001
From: Donald Douwsma <ddouwsma@redhat.com>
Date: Fri, 14 Oct 2022 18:58:45 +1100
Subject: [PATCH 2/4] xfsrestore: fix on-media inventory stream unpacking
xfsdump can create multiple streams, when restoring the online inventory
with multiple streams we fail to process these and assert when the
inventory buffer is not fully decoded.
[root@rhel8 ~]# xfsdump -L "Test1" -f /dev/nst0 -M tape1 -f /dev/nst1 -M tape2 /boot
xfsdump: using scsi tape (drive_scsitape) strategy
xfsdump: using scsi tape (drive_scsitape) strategy
xfsdump: version 3.1.8 (dump format 3.0) - type ^C for status and control
xfsdump: level 0 dump of rhel8:/boot
xfsdump: dump date: Thu Oct 6 13:50:45 2022
xfsdump: session id: aa25fa48-4493-45c7-9027-61e53e486445
xfsdump: session label: "Test1"
xfsdump: ino map phase 1: constructing initial dump list
xfsdump: ino map phase 2: skipping (no pruning necessary)
xfsdump: ino map phase 3: identifying stream starting points
xfsdump: stream 0: ino 133 offset 0 to ino 28839 offset 0
xfsdump: stream 1: ino 28839 offset 0 to end
xfsdump: ino map construction complete
xfsdump: estimated dump size: 328720704 bytes
xfsdump: estimated dump size per stream: 164375728 bytes
xfsdump: /var/lib/xfsdump/inventory created
xfsdump: drive 0: preparing drive
xfsdump: drive 1: preparing drive
xfsdump: drive 1: creating dump session media file 0 (media 0, file 0)
xfsdump: drive 1: dumping ino map
xfsdump: drive 1: dumping non-directory files
xfsdump: drive 0: creating dump session media file 0 (media 0, file 0)
xfsdump: drive 0: dumping ino map
xfsdump: drive 0: dumping directories
xfsdump: drive 0: dumping non-directory files
xfsdump: drive 1: ending media file
xfsdump: drive 1: media file size 166723584 bytes
xfsdump: drive 1: waiting for synchronized session inventory dump
xfsdump: drive 0: ending media file
xfsdump: drive 0: media file size 165675008 bytes
xfsdump: drive 0: waiting for synchronized session inventory dump
xfsdump: drive 0: dumping session inventory
xfsdump: drive 0: beginning inventory media file
xfsdump: drive 0: media file 1 (media 0, file 1)
xfsdump: drive 0: ending inventory media file
xfsdump: drive 0: inventory media file size 2097152 bytes
xfsdump: drive 0: writing stream terminator
xfsdump: drive 0: beginning media stream terminator
xfsdump: drive 0: media file 2 (media 0, file 2)
xfsdump: drive 0: ending media stream terminator
xfsdump: drive 0: media stream terminator size 1048576 bytes
xfsdump: drive 1: dumping session inventory
xfsdump: drive 1: beginning inventory media file
xfsdump: drive 1: media file 1 (media 0, file 1)
xfsdump: drive 1: ending inventory media file
xfsdump: drive 1: inventory media file size 2097152 bytes
xfsdump: drive 1: writing stream terminator
xfsdump: drive 1: beginning media stream terminator
xfsdump: drive 1: media file 2 (media 0, file 2)
xfsdump: drive 1: ending media stream terminator
xfsdump: drive 1: media stream terminator size 1048576 bytes
xfsdump: dump size (non-dir files) : 328189016 bytes
xfsdump: dump complete: 4 seconds elapsed
xfsdump: Dump Summary:
xfsdump: stream 0 /dev/nst0 OK (success)
xfsdump: stream 1 /dev/nst1 OK (success)
xfsdump: Dump Status: SUCCESS
[root@rhel8 ~]# xfsdump -I
file system 0:
fs id: 26dd5aa0-b901-4cf5-9b68-0c5753cb3ab8
session 0:
mount point: rhel8:/boot
device: rhel8:/dev/sda1
time: Thu Oct 6 13:50:45 2022
session label: "Test1"
session id: aa25fa48-4493-45c7-9027-61e53e486445
level: 0
resumed: NO
subtree: NO
streams: 2
stream 0:
pathname: /dev/nst0
start: ino 133 offset 0
end: ino 28839 offset 0
interrupted: NO
media files: 2
media file 0:
mfile index: 0
mfile type: data
mfile size: 165675008
mfile start: ino 133 offset 0
mfile end: ino 28839 offset 0
media label: "tape1"
media id: adb31f2a-f026-4597-a20a-326f28ecbaf1
media file 1:
mfile index: 1
mfile type: inventory
mfile size: 2097152
media label: "tape1"
media id: adb31f2a-f026-4597-a20a-326f28ecbaf1
stream 1:
pathname: /dev/nst1
start: ino 28839 offset 0
end: ino 1572997 offset 0
interrupted: NO
media files: 2
media file 0:
mfile index: 0
mfile type: data
mfile size: 166723584
mfile start: ino 28839 offset 0
mfile end: ino 1572997 offset 0
media label: "tape2"
media id: 22224f02-b6c7-47d5-ad61-a61ba071c8a8
media file 1:
mfile index: 1
mfile type: inventory
mfile size: 2097152
media label: "tape2"
media id: 22224f02-b6c7-47d5-ad61-a61ba071c8a8
xfsdump: Dump Status: SUCCESS
[root@rhel8 ~]# mv /var/lib/xfsdump/inventory /var/lib/xfsdump/inventory_two_sessions
[root@rhel8 ~]# xfsdump -I
xfsdump: Dump Status: SUCCESS
[root@rhel8 ~]# xfsrestore -L Test1 -f /dev/nst0 /tmp/test1/
xfsrestore: using scsi tape (drive_scsitape) strategy
xfsrestore: version 3.1.8 (dump format 3.0) - type ^C for status and control
xfsrestore: searching media for dump
xfsrestore: preparing drive
xfsrestore: examining media file 2
xfsrestore: found dump matching specified label:
xfsrestore: hostname: rhel8
xfsrestore: mount point: /boot
xfsrestore: volume: /dev/sda1
xfsrestore: session time: Thu Oct 6 13:50:45 2022
xfsrestore: level: 0
xfsrestore: session label: "Test1"
xfsrestore: media label: "tape1"
xfsrestore: file system id: 26dd5aa0-b901-4cf5-9b68-0c5753cb3ab8
xfsrestore: session id: aa25fa48-4493-45c7-9027-61e53e486445
xfsrestore: media id: adb31f2a-f026-4597-a20a-326f28ecbaf1
xfsrestore: searching media for directory dump
xfsrestore: rewinding
xfsrestore: examining media file 0
xfsrestore: reading directories
xfsrestore: 9 directories and 320 entries processed
xfsrestore: directory post-processing
xfsrestore: restoring non-directory files
xfsrestore: examining media file 1
xfsrestore: inv_stobj.c:1119: stobj_unpack_sessinfo: Assertion `(size_t) ( p - (char *) bufp ) == bufsz' failed.
Aborted (core dumped)
Make sure we unpack multiple streams when restoring the online
inventory from media.
Signed-off-by: Donald Douwsma <ddouwsma@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
inventory/inv_stobj.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/inventory/inv_stobj.c b/inventory/inv_stobj.c
index cdf3300..42b86dc 100644
--- a/inventory/inv_stobj.c
+++ b/inventory/inv_stobj.c
@@ -1065,25 +1065,26 @@
return BOOL_FALSE;
}
+ /* get the seshdr and then, the remainder of the session */
xlate_invt_seshdr((invt_seshdr_t *)p, (invt_seshdr_t *)tmpbuf, 1);
bcopy(tmpbuf, p, sizeof(invt_seshdr_t));
-
- /* get the seshdr and then, the remainder of the session */
s->seshdr = (invt_seshdr_t *)p;
s->seshdr->sh_sess_off = -1;
p += sizeof( invt_seshdr_t );
-
xlate_invt_session((invt_session_t *)p, (invt_session_t *)tmpbuf, 1);
bcopy (tmpbuf, p, sizeof(invt_session_t));
s->ses = (invt_session_t *)p;
p += sizeof( invt_session_t );
/* the array of all the streams belonging to this session */
- xlate_invt_stream((invt_stream_t *)p, (invt_stream_t *)tmpbuf, 1);
- bcopy(tmpbuf, p, sizeof(invt_stream_t));
s->strms = (invt_stream_t *)p;
- p += s->ses->s_cur_nstreams * sizeof( invt_stream_t );
+ for (i = 0; i < s->ses->s_cur_nstreams; i++) {
+ xlate_invt_stream((invt_stream_t *)p,
+ (invt_stream_t *)tmpbuf, 1);
+ bcopy(tmpbuf, p, sizeof(invt_stream_t));
+ p += sizeof(invt_stream_t);
+ }
/* all the media files */
s->mfiles = (invt_mediafile_t *)p;
--
2.41.0

View File

@ -0,0 +1,91 @@
From 7b843fdbbe47ed36117fc0e1fb95e4288f3a9c83 Mon Sep 17 00:00:00 2001
From: Donald Douwsma <ddouwsma@redhat.com>
Date: Fri, 14 Oct 2022 18:58:46 +1100
Subject: [PATCH 3/4] xfsdump: fix on-media inventory stream packing
With the on-media inventory now being restored for multiple streams we
can see that the restored streams both claim to be for /dev/nst0.
[root@rhel8 xfsdump-dev]# xfsdump -L "Test" -f /dev/nst0 -M tape1 -f /dev/nst1 -M tape2 /boot
...
[root@rhel8 ~]# rm -rf /var/lib/xfsdump/inventory
[root@rhel8 xfsdump-dev]# restore/xfsrestore -L Test -f /dev/nst0 -f /dev/nst1 /tmp/test
restore/xfsrestore: using scsi tape (drive_scsitape) strategy
restore/xfsrestore: using scsi tape (drive_scsitape) strategy
restore/xfsrestore: version 3.1.10 (dump format 3.0) - type ^C for status and control
...
restore/xfsrestore: Restore Summary:
restore/xfsrestore: stream 0 /dev/nst0 OK (success)
restore/xfsrestore: stream 1 /dev/nst1 ALREADY_DONE (another stream completed the operation)
restore/xfsrestore: Restore Status: SUCCESS
[root@rhel8 xfsdump-dev]# xfsdump -I
file system 0:
fs id: 26dd5aa0-b901-4cf5-9b68-0c5753cb3ab8
session 0:
mount point: rhel8:/boot
device: rhel8:/dev/sda1
time: Fri Oct 14 18:31:40 2022
session label: "Test"
session id: 96538a3d-2af8-4a79-8865-afec6e3e55f4
level: 0
resumed: NO
subtree: NO
streams: 2
stream 0:
pathname: /dev/nst0
start: ino 133 offset 0
end: ino 28839 offset 0
interrupted: YES
media files: 1
media file 0:
mfile index: 0
mfile type: data
mfile size: 165675008
mfile start: ino 133 offset 0
mfile end: ino 28839 offset 0
media label: "tape1"
media id: 8a9d0ced-61f6-4332-a0c1-f1e38641c4e6
stream 1:
pathname: /dev/nst0
start: ino 133 offset 0
end: ino 28839 offset 0
interrupted: YES
media files: 1
media file 0:
mfile index: 0
mfile type: data
mfile size: 166723584
mfile start: ino 28839 offset 0
mfile end: ino 1572997 offset 0
media label: "tape2"
media id: 7d569377-6bfb-4c02-b299-4dbe753bb048
xfsdump: Dump Status: SUCCESS
[root@rhel8 xfsdump-dev]#
Fix this by indexing the stream being packed for the on-media inventory.
Signed-off-by: Donald Douwsma <ddouwsma@redhat.com>
Suggested-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
inventory/inv_stobj.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/inventory/inv_stobj.c b/inventory/inv_stobj.c
index 42b86dc..d6aedf2 100644
--- a/inventory/inv_stobj.c
+++ b/inventory/inv_stobj.c
@@ -798,7 +798,7 @@
sesbuf += sizeof( invt_session_t );
for ( i = 0; i < ses->s_cur_nstreams; i++ ) {
- xlate_invt_stream( strms, (invt_stream_t *)sesbuf, 1 );
+ xlate_invt_stream(&strms[i], (invt_stream_t *)sesbuf, 1);
sesbuf += sizeof( invt_stream_t );
}
--
2.41.0

View File

@ -0,0 +1,47 @@
From aaaa57f32a605e4ebd2e4230fe036afc009ae0a0 Mon Sep 17 00:00:00 2001
From: Donald Douwsma <ddouwsma@redhat.com>
Date: Fri, 14 Oct 2022 18:58:47 +1100
Subject: [PATCH 4/4] xfsrestore: untangle inventory unpacking logic
stobj_unpack_sessinfo returns bool_t, fix logic in pi_addfile so errors
can be properly reported.
Signed-off-by: Donald Douwsma <ddouwsma@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
restore/content.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/restore/content.c b/restore/content.c
index b19bb90..8bb5fa4 100644
--- a/restore/content.c
+++ b/restore/content.c
@@ -5467,18 +5467,14 @@
/* ask inventory to convert buffer into session
* desc.
*/
- sessp = 0;
- if ( ! buflen ) {
- ok = BOOL_FALSE;
- } else {
- /* extract the session information from the buffer */
- if ( stobj_unpack_sessinfo( bufp, buflen, &sessinfo )<0 ) {
- ok = BOOL_FALSE;
- } else {
+ ok = BOOL_FALSE;
+ /* extract the session information from the buffer */
+ if (buflen &&
+ stobj_unpack_sessinfo(bufp, buflen, &sessinfo)) {
stobj_convert_sessinfo(&sessp, &sessinfo);
ok = BOOL_TRUE;
- }
}
+
if ( ! ok || ! sessp ) {
mlog( MLOG_DEBUG | MLOG_WARNING | MLOG_MEDIA, _(
"on-media session "
--
2.41.0

View File

@ -0,0 +1,57 @@
From 8e97f9c2b3c362fa6dd872d72594713c713479bc Mon Sep 17 00:00:00 2001
From: Donald Douwsma <ddouwsma@redhat.com>
Date: Thu, 24 Aug 2023 12:07:04 +1000
Subject: [PATCH] xfsrestore: suggest -x rather than assert for false roots
If we're going to have a fix for false root problems its a good idea to
let people know that there's a way to recover, error out with a useful
message that mentions the `-x` option rather than just assert.
Before
xfsrestore: searching media for directory dump
xfsrestore: reading directories
xfsrestore: tree.c:757: tree_begindir: Assertion `ino != persp->p_rootino || hardh == persp->p_rooth' failed.
Aborted
After
xfsrestore: ERROR: tree.c:791: tree_begindir: Assertion `ino != persp->p_rootino || hardh == persp->p_rooth` failed.
xfsrestore: ERROR: False root detected. Recovery may be possible using the `-x` option
Aborted
Fixes: d7cba7410710 ("xfsrestore: fix rootdir due to xfsdump bulkstat misuse")
Signed-off-by: Donald Douwsma <ddouwsma@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
restore/tree.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/restore/tree.c b/restore/tree.c
index bfa07fe..6f3180f 100644
--- a/restore/tree.c
+++ b/restore/tree.c
@@ -783,8 +783,15 @@ tree_begindir( filehdr_t *fhdrp, dah_t *dahp )
/* lookup head of hardlink list
*/
hardh = link_hardh( ino, gen );
- if (need_fixrootdir == BOOL_FALSE)
- assert( ino != persp->p_rootino || hardh == persp->p_rooth );
+ if (need_fixrootdir == BOOL_FALSE &&
+ !(ino != persp->p_rootino || hardh == persp->p_rooth)) {
+ mlog(MLOG_ERROR | MLOG_TREE,
+"%s:%d: %s: Assertion `ino != persp->p_rootino || hardh == persp->p_rooth` failed.\n",
+ __FILE__, __LINE__, __func__);
+ mlog(MLOG_ERROR | MLOG_TREE, _(
+"False root detected. Recovery may be possible using the `-x` option\n"));
+ return NH_NULL;
+ }
/* already present
*/
--
2.41.0

View File

@ -1,7 +1,7 @@
Summary: Administrative utilities for the XFS filesystem
Name: xfsdump
Version: 3.1.8
Release: 4%{?dist}
Release: 5%{?dist}
# Licensing based on generic "GNU GENERAL PUBLIC LICENSE"
# in source, with no mention of version.
License: GPL+
@ -10,6 +10,12 @@ URL: http://oss.sgi.com/projects/xfs/
Source0: http://kernel.org/pub/linux/utils/fs/xfs/%{name}/%{name}-%{version}.tar.xz
Patch0: 0001-xfsdump-Revert-xfsdump-handle-bind-mount-targets.patch
Patch1: 0002-xfsdump-intercept-bind-mount-targets.patch
Patch2: 0003-for-next-xfsrestore-fix-rootdir-due-to-xfsdump-bulkstat-misus.patch
Patch4: 0005-v3.1.12-xfsrestore-fix-on-media-inventory-media-unpacking.patch
Patch5: 0006-v3.1.12-xfsrestore-fix-on-media-inventory-stream-unpacking.patch
Patch6: 0007-v3.1.12-xfsdump-fix-on-media-inventory-stream-packing.patch
Patch7: 0008-v3.1.12-xfsrestore-untangle-inventory-unpacking-logic.patch
Patch8: 0009-v3.1.13-xfsrestore-suggest-x-rather-than-assert-for-false-ro.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: libtool, gettext, gawk
BuildRequires: xfsprogs-devel, libuuid-devel, libattr-devel ncurses-devel
@ -36,6 +42,12 @@ subtrees may be restored from full or partial backups.
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%build
%configure
@ -69,6 +81,18 @@ rm -rf $RPM_BUILD_ROOT
%{_sharedstatedir}/xfsdump/inventory
%changelog
* Thu Oct 05 2023 Pavel Reichl <preichl@redhat.com> - 3.1.8-7
- xfsdump/xfsrestore: suggest recovery for false roots may be possible using -x
- Related: RHEL-11883
* Tue Jun 20 2023 Pavel Reichl <preichl@redhat.com> - 3.1.8-6
- xfsdump: restoring inventory prevents non-directory files being restored from tape
- related: bz#2166554
* Mon Jun 19 2023 Pavel Reichl <preichl@redhat.com> - 3.1.8-5
- xfsrestore: Files from the backup go to orphanage dir because of xfsdump issue
- related: bz#2055289
* Fri Feb 11 2022 Eric Sandeen <sandeen@redhat.com> 3.1.8-4
- Fix bind mount vs root inode problems (#2020494)