From 4f4eca7e513e6fdd0f482e2a338840c92c36b9c8 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 8 Nov 2023 13:37:12 +0300 Subject: [PATCH] imports CS xfsdump-3.1.8-7.el8 remove unnecessary patches --- ...ootdir-due-to-xfsdump-bulkstat-misus.patch | 286 ++++++++++++++++++ ...x-on-media-inventory-media-unpacking.patch | 149 +++++++++ ...-on-media-inventory-stream-unpacking.patch | 204 +++++++++++++ ...ix-on-media-inventory-stream-packing.patch | 91 ++++++ ...e-untangle-inventory-unpacking-logic.patch | 47 +++ ...st-x-rather-than-assert-for-false-ro.patch | 57 ++++ SPECS/xfsdump.spec | 26 +- 7 files changed, 859 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0003-for-next-xfsrestore-fix-rootdir-due-to-xfsdump-bulkstat-misus.patch create mode 100644 SOURCES/0005-v3.1.12-xfsrestore-fix-on-media-inventory-media-unpacking.patch create mode 100644 SOURCES/0006-v3.1.12-xfsrestore-fix-on-media-inventory-stream-unpacking.patch create mode 100644 SOURCES/0007-v3.1.12-xfsdump-fix-on-media-inventory-stream-packing.patch create mode 100644 SOURCES/0008-v3.1.12-xfsrestore-untangle-inventory-unpacking-logic.patch create mode 100644 SOURCES/0009-v3.1.13-xfsrestore-suggest-x-rather-than-assert-for-false-ro.patch diff --git a/SOURCES/0003-for-next-xfsrestore-fix-rootdir-due-to-xfsdump-bulkstat-misus.patch b/SOURCES/0003-for-next-xfsrestore-fix-rootdir-due-to-xfsdump-bulkstat-misus.patch new file mode 100644 index 0000000..cc0cde6 --- /dev/null +++ b/SOURCES/0003-for-next-xfsrestore-fix-rootdir-due-to-xfsdump-bulkstat-misus.patch @@ -0,0 +1,286 @@ +From d7cba7410710cd3ec2c2d9fafd4d93437097f473 Mon Sep 17 00:00:00 2001 +From: Gao Xiang +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 +Signed-off-by: Gao Xiang +Signed-off-by: Hironori Shiina +Reviwed-by: Eric Sandeen +Signed-off-by: Carlos Maiolino +Signed-off-by: Pavel Reichl +--- + 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(_(""), 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 + #include + #include +@@ -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 + diff --git a/SOURCES/0005-v3.1.12-xfsrestore-fix-on-media-inventory-media-unpacking.patch b/SOURCES/0005-v3.1.12-xfsrestore-fix-on-media-inventory-media-unpacking.patch new file mode 100644 index 0000000..6061d0f --- /dev/null +++ b/SOURCES/0005-v3.1.12-xfsrestore-fix-on-media-inventory-media-unpacking.patch @@ -0,0 +1,149 @@ +From 06dd184d3a689dcb33a50b6e3576e48055e48133 Mon Sep 17 00:00:00 2001 +From: Donald Douwsma +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 +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +Signed-off-by: Pavel Reichl +--- + 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 + diff --git a/SOURCES/0006-v3.1.12-xfsrestore-fix-on-media-inventory-stream-unpacking.patch b/SOURCES/0006-v3.1.12-xfsrestore-fix-on-media-inventory-stream-unpacking.patch new file mode 100644 index 0000000..9de894d --- /dev/null +++ b/SOURCES/0006-v3.1.12-xfsrestore-fix-on-media-inventory-stream-unpacking.patch @@ -0,0 +1,204 @@ +From 65034077ef03c434c09c88d38c4c58ec442cf3c1 Mon Sep 17 00:00:00 2001 +From: Donald Douwsma +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 +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +Signed-off-by: Pavel Reichl +--- + 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 + diff --git a/SOURCES/0007-v3.1.12-xfsdump-fix-on-media-inventory-stream-packing.patch b/SOURCES/0007-v3.1.12-xfsdump-fix-on-media-inventory-stream-packing.patch new file mode 100644 index 0000000..013e5bd --- /dev/null +++ b/SOURCES/0007-v3.1.12-xfsdump-fix-on-media-inventory-stream-packing.patch @@ -0,0 +1,91 @@ +From 7b843fdbbe47ed36117fc0e1fb95e4288f3a9c83 Mon Sep 17 00:00:00 2001 +From: Donald Douwsma +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 +Suggested-by: Darrick J. Wong +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +Signed-off-by: Pavel Reichl +--- + 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 + diff --git a/SOURCES/0008-v3.1.12-xfsrestore-untangle-inventory-unpacking-logic.patch b/SOURCES/0008-v3.1.12-xfsrestore-untangle-inventory-unpacking-logic.patch new file mode 100644 index 0000000..8f33d9b --- /dev/null +++ b/SOURCES/0008-v3.1.12-xfsrestore-untangle-inventory-unpacking-logic.patch @@ -0,0 +1,47 @@ +From aaaa57f32a605e4ebd2e4230fe036afc009ae0a0 Mon Sep 17 00:00:00 2001 +From: Donald Douwsma +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 +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +Signed-off-by: Pavel Reichl +--- + 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 + diff --git a/SOURCES/0009-v3.1.13-xfsrestore-suggest-x-rather-than-assert-for-false-ro.patch b/SOURCES/0009-v3.1.13-xfsrestore-suggest-x-rather-than-assert-for-false-ro.patch new file mode 100644 index 0000000..ebd318c --- /dev/null +++ b/SOURCES/0009-v3.1.13-xfsrestore-suggest-x-rather-than-assert-for-false-ro.patch @@ -0,0 +1,57 @@ +From 8e97f9c2b3c362fa6dd872d72594713c713479bc Mon Sep 17 00:00:00 2001 +From: Donald Douwsma +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 +Reviewed-by: Darrick J. Wong +Reviewed-by: Carlos Maiolino +Signed-off-by: Carlos Maiolino +Signed-off-by: Pavel Reichl +--- + 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 + diff --git a/SPECS/xfsdump.spec b/SPECS/xfsdump.spec index 0d2287b..17555ed 100644 --- a/SPECS/xfsdump.spec +++ b/SPECS/xfsdump.spec @@ -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 - 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 - 3.1.8-6 +- xfsdump: restoring inventory prevents non-directory files being restored from tape +- related: bz#2166554 + +* Mon Jun 19 2023 Pavel Reichl - 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 3.1.8-4 - Fix bind mount vs root inode problems (#2020494)