From 1d17e1fc2af9dfe5104b30faa28db2c747d3a1d0 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Fri, 21 Jun 2024 16:46:11 +0100 Subject: [PATCH] * Fri Jun 21 2024 Andrew Price - 3.5.1-2 - gfs2_edit: truncate to filesystem size at end of restoremeta() Resolves: RHEL-26661 - Update tests/testsuite --- ...ilesystem_size_at_end_of_restoremeta.patch | 111 ++++++++++++++ gfs2-utils.spec | 8 +- tests/testsuite | 138 +++++++++++++++--- 3 files changed, 235 insertions(+), 22 deletions(-) create mode 100644 RHEL-26661-gfs2_edit_truncate_to_filesystem_size_at_end_of_restoremeta.patch diff --git a/RHEL-26661-gfs2_edit_truncate_to_filesystem_size_at_end_of_restoremeta.patch b/RHEL-26661-gfs2_edit_truncate_to_filesystem_size_at_end_of_restoremeta.patch new file mode 100644 index 0000000..c3700a5 --- /dev/null +++ b/RHEL-26661-gfs2_edit_truncate_to_filesystem_size_at_end_of_restoremeta.patch @@ -0,0 +1,111 @@ +commit f837169ab53dc915e10bdb480eaeb5bbb52c0c09 +Author: Paul Evans +Date: Wed Mar 6 12:28:16 2024 +0000 + + gfs2_edit: truncate to filesystem size at end of restoremeta() + + Truncate to metadata header's filesystem size at the end of restore if + a header is present. + + Resolves: RHEL-26661 + + Signed-off-by: Paul Evans + +diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c +index 4ee76be0..f5448974 100644 +--- a/gfs2/edit/savemeta.c ++++ b/gfs2/edit/savemeta.c +@@ -1327,9 +1327,8 @@ static void restoremeta_usage(void) + fprintf(stderr, "gfs2_edit restoremeta \n"); + } + +-static int restore_init(const char *path, struct metafd *mfd, int printonly) ++static int restore_init(const char *path, struct metafd *mfd, struct savemeta *sm, int printonly) + { +- struct savemeta sm = {0}; + struct gfs2_sb rsb; + uint16_t sb_siglen; + char *end; +@@ -1357,7 +1356,7 @@ static int restore_init(const char *path, struct metafd *mfd, int printonly) + return -1; + } + bp = restore_buf; +- ret = parse_header(bp, &sm); ++ ret = parse_header(bp, sm); + if (ret == 0) { + bp = restore_buf + sizeof(struct savemeta_header); + restore_off = sizeof(struct savemeta_header); +@@ -1383,10 +1382,10 @@ static int restore_init(const char *path, struct metafd *mfd, int printonly) + if (ret != 0) + return ret; + +- if (sm.sm_fs_bytes > 0) { +- sbd.fssize = sm.sm_fs_bytes / sbd.sd_bsize; ++ if (sm->sm_fs_bytes > 0) { ++ sbd.fssize = sm->sm_fs_bytes / sbd.sd_bsize; + printf("Saved file system size is %"PRIu64" blocks, %.2fGB\n", +- sbd.fssize, sm.sm_fs_bytes / ((float)(1 << 30))); ++ sbd.fssize, sm->sm_fs_bytes / ((float)(1 << 30))); + } + printf("Block size is %uB\n", sbd.sd_bsize); + printf("This is gfs%c metadata.\n", sbd.gfs1 ? '1': '2'); +@@ -1406,6 +1405,8 @@ static int restore_init(const char *path, struct metafd *mfd, int printonly) + void restoremeta(const char *in_fn, const char *out_device, uint64_t printonly) + { + struct metafd mfd = {0}; ++ struct savemeta sm = {0}; ++ struct stat st; + int error; + + termlines = 0; +@@ -1430,7 +1431,7 @@ void restoremeta(const char *in_fn, const char *out_device, uint64_t printonly) + optional block no */ + printonly = check_keywords(out_device); + +- error = restore_init(in_fn, &mfd, printonly); ++ error = restore_init(in_fn, &mfd, &sm, printonly); + if (error != 0) + exit(error); + +@@ -1440,6 +1441,23 @@ void restoremeta(const char *in_fn, const char *out_device, uint64_t printonly) + } + + error = restore_data(sbd.device_fd, &mfd, printonly); ++ ++ /* When there is a metadata header available, truncate to filesystem ++ size if our device_fd is a regular file */ ++ if (!printonly) { ++ if (fstat(sbd.device_fd, &st) == -1) { ++ fprintf(stderr, "Failed to stat %s: %s\n", out_device, strerror(errno)); ++ error = errno; ++ } ++ ++ if (sm.sm_fs_bytes > 0 && S_ISREG(st.st_mode)) { ++ if (ftruncate(sbd.device_fd, sm.sm_fs_bytes) != 0) { ++ fprintf(stderr, "Failed to truncate: %s, %s\n", out_device, strerror(errno)); ++ error = errno; ++ } ++ } ++ } ++ + printf("File %s %s %s.\n", in_fn, + (printonly ? "print" : "restore"), + (error ? "error" : "successful")); +diff --git a/tests/edit.at b/tests/edit.at +index d6795218..29835df0 100644 +--- a/tests/edit.at ++++ b/tests/edit.at +@@ -61,3 +61,13 @@ AT_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT], 0, [ignore], [ignore]) + AT_CHECK([gfs2_edit savemeta -z0 $GFS_TGT /dev/null], 0, [ignore], [ignore]) + AT_CHECK([gfs2_edit savemeta $GFS_TGT /dev/null], 0, [ignore], [ignore]) + AT_CLEANUP ++ ++AT_SETUP([Truncate on restoremeta]) ++AT_KEYWORDS(gfs2_edit edit) ++GFS_TGT_REGEN ++AT_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT], 0, [ignore], [ignore]) ++AT_CHECK([gfs2_edit savemeta $GFS_TGT test.meta], 0, [ignore], [ignore]) ++AT_CHECK([truncate -s 10K test.file], 0, [ignore], [ignore]) ++AT_CHECK([gfs2_edit restoremeta test.meta test.file], 0, [ignore], [ignore]) ++AT_CHECK([fsck.gfs2 -n test.file], 0, [ignore], [ignore]) ++AT_CLEANUP diff --git a/gfs2-utils.spec b/gfs2-utils.spec index ec1e884..12d79f0 100644 --- a/gfs2-utils.spec +++ b/gfs2-utils.spec @@ -1,6 +1,6 @@ Name: gfs2-utils Version: 3.5.1 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv2+ and LGPLv2+ Summary: Utilities for managing the global file system (GFS2) %ifnarch %{arm} @@ -21,6 +21,7 @@ BuildRequires: bzip2-devel BuildRequires: make Source: https://releases.pagure.org/gfs2-utils/gfs2-utils-%{version}.tar.gz URL: https://pagure.io/gfs2-utils +Patch0: RHEL-26661-gfs2_edit_truncate_to_filesystem_size_at_end_of_restoremeta.patch %prep %autosetup -p1 @@ -63,6 +64,11 @@ modifying, and correcting inconsistencies in GFS2 file systems. %{_prefix}/lib/udev/rules.d/82-gfs2-withdraw.rules %changelog +* Fri Jun 21 2024 Andrew Price - 3.5.1-2 +- gfs2_edit: truncate to filesystem size at end of restoremeta() + Resolves: RHEL-26661 +- Update tests/testsuite + * Tue Apr 11 2023 Andrew Price - 3.5.1-1 - New upstream release - Drop patches diff --git a/tests/testsuite b/tests/testsuite index d466fa9..a2fc4a5 100755 --- a/tests/testsuite +++ b/tests/testsuite @@ -652,9 +652,10 @@ at_help_all="1;mkfs.at:4;Locking protocol validation;mkfs.gfs2 mkfs; 40;edit.at:37;Save/restoremeta, 4 journals;gfs2_edit edit; 41;edit.at:47;Save/restoremeta, min. block size, 4 journals;gfs2_edit edit; 42;edit.at:57;Save metadata to /dev/null;gfs2_edit edit; -43;tune.at:4;Format version;tunegfs2 tune; -44;tune.at:20;Handle bad fs;tunegfs2 tune; -45;tune.at:28;Expected output;tunegfs2 tune; +43;edit.at:65;Truncate on restoremeta;gfs2_edit edit; +44;tune.at:4;Format version;tunegfs2 tune; +45;tune.at:20;Handle bad fs;tunegfs2 tune; +46;tune.at:28;Expected output;tunegfs2 tune; " # List of the all the test groups. at_groups_all=`printf "%s\n" "$at_help_all" | sed 's/;.*//'` @@ -668,7 +669,7 @@ at_fn_validate_ranges () for at_grp do eval at_value=\$$at_grp - if test $at_value -lt 1 || test $at_value -gt 45; then + if test $at_value -lt 1 || test $at_value -gt 46; then printf "%s\n" "invalid test group: $at_value" >&2 exit 1 fi @@ -998,7 +999,7 @@ fi # List of tests. if $at_list_p; then cat <<_ATEOF || at_write_fail=1 -gfs2-utils 3.5.0 test suite test groups: +gfs2-utils 3.5.1 test suite test groups: NUM: FILE-NAME:LINE TEST-GROUP-NAME KEYWORDS @@ -1039,7 +1040,7 @@ _ATEOF exit $at_write_fail fi if $at_version_p; then - printf "%s\n" "$as_me (gfs2-utils 3.5.0)" && + printf "%s\n" "$as_me (gfs2-utils 3.5.1)" && cat <<\_ATEOF || at_write_fail=1 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1066,7 +1067,7 @@ at_banner_text_2="fsck.gfs2 tests" # Category starts at test group 37. at_banner_text_3="gfs2_edit tests" # Banner 4. tune.at:2 -# Category starts at test group 43. +# Category starts at test group 44. at_banner_text_4="tunegfs2 tests" # Take any -C into account. @@ -1236,11 +1237,11 @@ exec 5>>"$at_suite_log" # Banners and logs. printf "%s\n" "## ---------------------------- ## -## gfs2-utils 3.5.0 test suite. ## +## gfs2-utils 3.5.1 test suite. ## ## ---------------------------- ##" { printf "%s\n" "## ---------------------------- ## -## gfs2-utils 3.5.0 test suite. ## +## gfs2-utils 3.5.1 test suite. ## ## ---------------------------- ##" echo @@ -2100,7 +2101,7 @@ _ASBOX printf "%s\n" "Please send $at_msg and all information you think might help: To: - Subject: [gfs2-utils 3.5.0] $as_me: $at_msg1$at_msg2 + Subject: [gfs2-utils 3.5.1] $as_me: $at_msg1$at_msg2 You may investigate any problem if you feel able to do so, in which case the test suite provides a good starting point. Its output may @@ -6225,14 +6226,109 @@ $at_traceon; } read at_status <"$at_status_file" #AT_STOP_42 #AT_START_43 -at_fn_group_banner 43 'tune.at:4' \ - "Format version" " " 4 +at_fn_group_banner 43 'edit.at:65' \ + "Truncate on restoremeta" " " 3 at_xfail=no ( printf "%s\n" "43. $at_setup_line: testing $at_desc ..." $at_traceon +{ set +x +printf "%s\n" "$at_srcdir/edit.at:67: rm -f \$GFS_TGT && truncate -s \${GFS_TGT_SZ}G \${GFS_TGT}" +at_fn_check_prepare_notrace 'a ${...} parameter expansion' "edit.at:67" +( $at_check_trace; rm -f $GFS_TGT && truncate -s ${GFS_TGT_SZ}G ${GFS_TGT} +) >>"$at_stdout" 2>>"$at_stderr" 5>&- +at_status=$? at_failed=false +$at_check_filter +echo stderr:; cat "$at_stderr" +echo stdout:; cat "$at_stdout" +at_fn_check_skip $at_status "$at_srcdir/edit.at:67" +$at_failed && at_fn_log_failure +$at_traceon; } + +printf "%s\n" "edit.at:67" >"$at_check_line_file" +(test ! -f ${GFS_TGT}) \ + && at_fn_check_skip 77 "$at_srcdir/edit.at:67" +{ set +x +printf "%s\n" "$at_srcdir/edit.at:68: \$GFS_MKFS -p lock_nolock \$GFS_TGT" +at_fn_check_prepare_dynamic "$GFS_MKFS -p lock_nolock $GFS_TGT" "edit.at:68" +( $at_check_trace; $GFS_MKFS -p lock_nolock $GFS_TGT +) >>"$at_stdout" 2>>"$at_stderr" 5>&- +at_status=$? at_failed=false +$at_check_filter +echo stderr:; cat "$at_stderr" +echo stdout:; cat "$at_stdout" +at_fn_check_status 0 $at_status "$at_srcdir/edit.at:68" +$at_failed && at_fn_log_failure +$at_traceon; } + +{ set +x +printf "%s\n" "$at_srcdir/edit.at:69: gfs2_edit savemeta \$GFS_TGT test.meta" +at_fn_check_prepare_dynamic "gfs2_edit savemeta $GFS_TGT test.meta" "edit.at:69" +( $at_check_trace; gfs2_edit savemeta $GFS_TGT test.meta +) >>"$at_stdout" 2>>"$at_stderr" 5>&- +at_status=$? at_failed=false +$at_check_filter +echo stderr:; cat "$at_stderr" +echo stdout:; cat "$at_stdout" +at_fn_check_status 0 $at_status "$at_srcdir/edit.at:69" +$at_failed && at_fn_log_failure +$at_traceon; } + +{ set +x +printf "%s\n" "$at_srcdir/edit.at:70: truncate -s 10K test.file" +at_fn_check_prepare_trace "edit.at:70" +( $at_check_trace; truncate -s 10K test.file +) >>"$at_stdout" 2>>"$at_stderr" 5>&- +at_status=$? at_failed=false +$at_check_filter +echo stderr:; cat "$at_stderr" +echo stdout:; cat "$at_stdout" +at_fn_check_status 0 $at_status "$at_srcdir/edit.at:70" +$at_failed && at_fn_log_failure +$at_traceon; } + +{ set +x +printf "%s\n" "$at_srcdir/edit.at:71: gfs2_edit restoremeta test.meta test.file" +at_fn_check_prepare_trace "edit.at:71" +( $at_check_trace; gfs2_edit restoremeta test.meta test.file +) >>"$at_stdout" 2>>"$at_stderr" 5>&- +at_status=$? at_failed=false +$at_check_filter +echo stderr:; cat "$at_stderr" +echo stdout:; cat "$at_stdout" +at_fn_check_status 0 $at_status "$at_srcdir/edit.at:71" +$at_failed && at_fn_log_failure +$at_traceon; } + +{ set +x +printf "%s\n" "$at_srcdir/edit.at:72: fsck.gfs2 -n test.file" +at_fn_check_prepare_trace "edit.at:72" +( $at_check_trace; fsck.gfs2 -n test.file +) >>"$at_stdout" 2>>"$at_stderr" 5>&- +at_status=$? at_failed=false +$at_check_filter +echo stderr:; cat "$at_stderr" +echo stdout:; cat "$at_stdout" +at_fn_check_status 0 $at_status "$at_srcdir/edit.at:72" +$at_failed && at_fn_log_failure +$at_traceon; } + + set +x + $at_times_p && times >"$at_times_file" +) 5>&1 2>&1 7>&- | eval $at_tee_pipe +read at_status <"$at_status_file" +#AT_STOP_43 +#AT_START_44 +at_fn_group_banner 44 'tune.at:4' \ + "Format version" " " 4 +at_xfail=no +( + printf "%s\n" "44. $at_setup_line: testing $at_desc ..." + $at_traceon + + { set +x printf "%s\n" "$at_srcdir/tune.at:6: rm -f \$GFS_TGT && truncate -s \${GFS_TGT_SZ}G \${GFS_TGT}" at_fn_check_prepare_notrace 'a ${...} parameter expansion' "tune.at:6" @@ -6348,13 +6444,13 @@ $at_traceon; } $at_times_p && times >"$at_times_file" ) 5>&1 2>&1 7>&- | eval $at_tee_pipe read at_status <"$at_status_file" -#AT_STOP_43 -#AT_START_44 -at_fn_group_banner 44 'tune.at:20' \ +#AT_STOP_44 +#AT_START_45 +at_fn_group_banner 45 'tune.at:20' \ "Handle bad fs" " " 4 at_xfail=no ( - printf "%s\n" "44. $at_setup_line: testing $at_desc ..." + printf "%s\n" "45. $at_setup_line: testing $at_desc ..." $at_traceon @@ -6392,13 +6488,13 @@ $at_traceon; } $at_times_p && times >"$at_times_file" ) 5>&1 2>&1 7>&- | eval $at_tee_pipe read at_status <"$at_status_file" -#AT_STOP_44 -#AT_START_45 -at_fn_group_banner 45 'tune.at:28' \ +#AT_STOP_45 +#AT_START_46 +at_fn_group_banner 46 'tune.at:28' \ "Expected output" " " 4 at_xfail=no ( - printf "%s\n" "45. $at_setup_line: testing $at_desc ..." + printf "%s\n" "46. $at_setup_line: testing $at_desc ..." $at_traceon @@ -6511,4 +6607,4 @@ $at_traceon; } $at_times_p && times >"$at_times_file" ) 5>&1 2>&1 7>&- | eval $at_tee_pipe read at_status <"$at_status_file" -#AT_STOP_45 +#AT_STOP_46