From 1ece8d2ba380794f2ca668218c3d75b73004a021 Mon Sep 17 00:00:00 2001 From: CentOS Buildsys Date: Sep 17 2013 13:21:27 +0000 Subject: import gfs2-utils-3.1.6-8.el7.src.rpm --- diff --git a/.gfs2-utils.metadata b/.gfs2-utils.metadata new file mode 100644 index 0000000..995608c --- /dev/null +++ b/.gfs2-utils.metadata @@ -0,0 +1 @@ +646baa99ee0f8dd4075d0e2c920cb66feb9d3404 SOURCES/gfs2-utils-3.1.6.tar.gz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/bz1000066-gfs2_utils_tests_Switch_to_autotest.patch b/SOURCES/bz1000066-gfs2_utils_tests_Switch_to_autotest.patch new file mode 100644 index 0000000..7c17c60 --- /dev/null +++ b/SOURCES/bz1000066-gfs2_utils_tests_Switch_to_autotest.patch @@ -0,0 +1,399 @@ +commit 5cfd080b0830e4d16ea8edcfbb8a0b5dce23c964 +Author: Andrew Price +Date: Mon Aug 19 12:59:58 2013 +0100 + + gfs2-utils tests: Switch to autotest + + Replaces the custom tool_tests.sh test harness with the Autotest + framework provided by Autoconf. See doc/README.tests for details. + + This is just a straight rework of the existing tests as Autotest test + groups. + + Resolves: rhbz#1000066 + + Signed-off-by: Andrew Price + +diff --git a/.gitignore b/.gitignore +index 26d89d0..ae72f2b 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -44,7 +44,13 @@ gfs2/tune/tunegfs2 + test-driver + tests/check_libgfs2 + tests/testvol +-tests/tests.log ++tests/testsuite.log ++tests/testsuite.dir ++tests/testsuite.trs ++tests/atconfig ++tests/atlocal ++tests/package.m4 ++tests/testsuite + ABOUT-NLS + po/Makevars.template + po/POTFILES +diff --git a/configure.ac b/configure.ac +index 911dd88..628d85e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -203,6 +203,7 @@ CPPFLAGS="-I\$(top_builddir)/make -I\$(top_srcdir)/make \ + -I. $ENV_CPPFLAGS" + LDFLAGS="$ENV_LDFLAGS" + ++AC_CONFIG_TESTDIR([tests], [gfs2/libgfs2:gfs2/mkfs:gfs2/fsck:gfs2/edit:gfs2/convert:gfs2/tune:tests]) + AC_CONFIG_FILES([Makefile + gfs2/Makefile + gfs2/include/Makefile +@@ -216,6 +217,7 @@ AC_CONFIG_FILES([Makefile + gfs2/scripts/Makefile + doc/Makefile + tests/Makefile ++ tests/atlocal + po/Makefile.in + ]) + +diff --git a/doc/README.tests b/doc/README.tests +new file mode 100644 +index 0000000..fa35803 +--- /dev/null ++++ b/doc/README.tests +@@ -0,0 +1,42 @@ ++Working with the gfs2-utils test suite ++-------------------------------------- ++ ++The test suite in the tests directory of the gfs2-utils source tree is based on ++the Autotest framework provided by Autoconf. The basic idea is that the ++testsuite.at file is the main source file for the tests, written in m4 and ++generating a bourne shell script called testsuite. ++ ++When run, either using 'make check' or directly from within the tests ++directory, the testsuite script sources atconfig and atlocal for configuration ++and then runs the whole testsuite or a specified set of tests (see ./testsuite ++-h for help). ++ ++A number of GFS2-specific convenience macros have been defined in testsuite.at ++to make defining new tests quick and easy. Also, some variables have been ++defined in atlocal.in so that full paths to programs do not have to be included ++in each test. Configuration should be specified in atlocal.in as atconfig is ++generated by the configure script and atlocal is generated from atlocal.in at ++build time. ++ ++To keep the test suite organised, the testsuite.at file sources the actual ++tests from other files, e.g. mkfs.at. ++ ++A single test, specified as a test group in Autotest terms, follows the form ++ ++ AT_SETUP([Test title]) ++ ...test goes here... ++ AT_CLEANUP ++ ++so, when adding tests, this is generally all that is required unless the tests ++do not fit into an existing category, in which case AT_BANNER can be used to ++group them, and they can be organised into a new .at file and sourced from ++testsuite.at. ++ ++Since the tests can be run individually (e.g. ./testsuite 15) any new tests ++which require the dummy volume $GFS_TGT to be present should call GFS_TGT_REGEN ++before attempting to use it. ++ ++Documentation for Autotest, including the AT_* macros used to define tests, can ++be found in the autoconf manual at: ++ ++ http://www.gnu.org/software/autoconf/manual/index.html +diff --git a/tests/Makefile.am b/tests/Makefile.am +index af01c49..3336304 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -1,15 +1,64 @@ +-TESTS_ENVIRONMENT = TOPBUILDDIR=$(top_builddir) +-EXTRA_DIST = tool_tests.sh +-CLEANFILES = tests.log ++EXTRA_DIST = $(TESTSUITE_AT) package.m4 $(TESTSUITE) atlocal atconfig ++DISTCLEANFILES = atlocal atconfig ++CLEANFILES = testvol + + if BUILD_TESTS +-check_PROGRAMS = check_libgfs2 +-check_libgfs2_SOURCES = check_meta.c \ +- $(top_srcdir)/gfs2/libgfs2/libgfs2.h +-check_libgfs2_CFLAGS = -I$(top_srcdir)/gfs2/libgfs2 \ +- -I$(top_srcdir)/gfs2/include \ +- @check_CFLAGS@ +-check_libgfs2_LDADD = $(top_builddir)/gfs2/libgfs2/libgfs2.la @check_LIBS@ ++check_PROGRAMS = check_libgfs2 ++ ++check_libgfs2_SOURCES = \ ++ check_meta.c \ ++ $(top_srcdir)/gfs2/libgfs2/libgfs2.h ++ ++check_libgfs2_CFLAGS = \ ++ -I$(top_srcdir)/gfs2/libgfs2 \ ++ -I$(top_srcdir)/gfs2/include \ ++ @check_CFLAGS@ ++ ++check_libgfs2_LDADD = \ ++ $(top_builddir)/gfs2/libgfs2/libgfs2.la \ ++ @check_LIBS@ + endif + +-TESTS = $(check_PROGRAMS) tool_tests.sh ++# The `:;' works around a Bash 3.2 bug when the output is not writable. ++$(srcdir)/package.m4: $(top_srcdir)/configure.ac ++ :;{ \ ++ echo '# Signature of the current package.' && \ ++ echo 'm4_define([AT_PACKAGE_NAME],' && \ ++ echo ' [$(PACKAGE_NAME)])' && \ ++ echo 'm4_define([AT_PACKAGE_TARNAME],' && \ ++ echo ' [$(PACKAGE_TARNAME)])' && \ ++ echo 'm4_define([AT_PACKAGE_VERSION],' && \ ++ echo ' [$(PACKAGE_VERSION)])' && \ ++ echo 'm4_define([AT_PACKAGE_STRING],' && \ ++ echo ' [$(PACKAGE_STRING)])' && \ ++ echo 'm4_define([AT_PACKAGE_BUGREPORT],' && \ ++ echo ' [$(PACKAGE_BUGREPORT)])'; \ ++ echo 'm4_define([AT_PACKAGE_URL],' && \ ++ echo ' [$(PACKAGE_URL)])'; \ ++ } >'$(srcdir)/package.m4' ++ ++TESTSUITE_AT = \ ++ testsuite.at \ ++ mkfs.at \ ++ libgfs2.at ++ ++TESTSUITE = $(srcdir)/testsuite ++ ++check-local: atconfig atlocal $(TESTSUITE) ++ $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS) ++ ++installcheck-local: atconfig atlocal $(TESTSUITE) ++ $(SHELL) '$(TESTSUITE)' AUTOTEST_PATH='$(sbindir):tests' $(TESTSUITEFLAGS) ++ ++clean-local: ++ test ! -f '$(TESTSUITE)' || $(SHELL) '$(TESTSUITE)' --clean ++ ++atconfig: $(top_builddir)/config.status ++ cd $(top_builddir) && ./config.status tests/$@ ++ ++AUTOM4TE = $(SHELL) $(top_srcdir)/missing --run autom4te ++AUTOTEST = $(AUTOM4TE) --language=autotest ++ ++$(TESTSUITE): $(TESTSUITE_AT) package.m4 ++ $(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at ++ mv $@.tmp $@ +diff --git a/tests/atlocal.in b/tests/atlocal.in +new file mode 100644 +index 0000000..660c87a +--- /dev/null ++++ b/tests/atlocal.in +@@ -0,0 +1,7 @@ ++GFS_TGT="$abs_builddir/testvol" ++GFS_TGT_SZ=10 ++ ++gfs_max_blocks() ++{ ++ printf $((GFS_TGT_SZ*1073741824/$1)) ++} +diff --git a/tests/libgfs2.at b/tests/libgfs2.at +new file mode 100644 +index 0000000..a6b478a +--- /dev/null ++++ b/tests/libgfs2.at +@@ -0,0 +1,5 @@ ++AT_BANNER([libgfs2 unit tests]) ++ ++AT_SETUP([Metadata check]) ++AT_CHECK([check_libgfs2], 0, [ignore], [ignore]) ++AT_CLEANUP +diff --git a/tests/mkfs.at b/tests/mkfs.at +new file mode 100644 +index 0000000..aff6a0d +--- /dev/null ++++ b/tests/mkfs.at +@@ -0,0 +1,64 @@ ++AT_TESTED([mkfs.gfs2]) ++AT_BANNER([mkfs.gfs2 tests]) ++ ++AT_SETUP([Locking protocol validation]) ++AT_CHECK([mkfs.gfs2 -O -p badprotocol $GFS_TGT], 255, [ignore], [ignore]) ++AT_CLEANUP ++ ++AT_SETUP([Resource group size validation]) ++AT_CHECK([mkfs.gfs2 -O -p lock_nolock -r 31 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([mkfs.gfs2 -O -p lock_nolock -r 2049 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CLEANUP ++ ++AT_SETUP([Journal size validation]) ++AT_CHECK([mkfs.gfs2 -O -p lock_nolock -J 7 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([mkfs.gfs2 -O -p lock_nolock -J 1025 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CLEANUP ++ ++AT_SETUP([Block count validation]) ++GFS_TGT_REGEN ++AT_CHECK([mkfs.gfs2 -O -p lock_nolock -b 512 $GFS_TGT $(($(gfs_max_blocks 512)+1))], 255, [ignore], [ignore]) ++AT_CHECK([mkfs.gfs2 -O -p lock_nolock -b 4096 $GFS_TGT $(($(gfs_max_blocks 4096)+1))], 255, [ignore], [ignore]) ++AT_CLEANUP ++ ++AT_SETUP([Quota change file size validation]) ++AT_CHECK([mkfs.gfs2 -O -p lock_nolock -c 0 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([mkfs.gfs2 -O -p lock_nolock -c 65 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CLEANUP ++ ++AT_SETUP([Locking protocols]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_dlm -t foo:bar $GFS_TGT]) ++AT_CLEANUP ++ ++AT_SETUP([Max. blocks, min. block size]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 512 $GFS_TGT $(gfs_max_blocks 512)]) ++AT_CLEANUP ++ ++AT_SETUP([Max. blocks, max. block size]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 4096 $GFS_TGT $(util_max_blocks 4096)]) ++AT_CLEANUP ++ ++AT_SETUP([Max. resource group size]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -r 2048 $GFS_TGT]) ++AT_CLEANUP ++ ++AT_SETUP([Min. resource group size]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -r 32 $GFS_TGT]) ++AT_CLEANUP ++ ++AT_SETUP([Max. journal size]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -J 1024 $GFS_TGT]) ++AT_CLEANUP ++ ++AT_SETUP([Min. journal size]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -J 8 $GFS_TGT]) ++AT_CLEANUP ++ ++AT_SETUP([Max. quota change file size]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -c 64 $GFS_TGT]) ++AT_CLEANUP ++ ++AT_SETUP([Min. quota change file size]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -c 1 $GFS_TGT]) ++AT_CLEANUP +diff --git a/tests/testsuite.at b/tests/testsuite.at +new file mode 100644 +index 0000000..2c74985 +--- /dev/null ++++ b/tests/testsuite.at +@@ -0,0 +1,16 @@ ++# Regenerate the sparse file used for testing and skip the test if it fails ++m4_define([GFS_TGT_REGEN], ++[AT_CHECK([rm -f $GFS_TGT && truncate -s ${GFS_TGT_SZ}G ${GFS_TGT}], [ignore], [ignore], [ignore]) ++AT_SKIP_IF([test ! -f ${GFS_TGT}])]) ++ ++# Regenerate, check, fsck is used a lot so combine it into one macro ++m4_define([GFS_FSCK_CHECK], ++[GFS_TGT_REGEN ++AT_CHECK($1, 0, [ignore], [ignore]) ++AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore])]) ++ ++AT_INIT([]) ++AT_COLOR_TESTS ++ ++m4_include([mkfs.at]) ++m4_include([libgfs2.at]) +diff --git a/tests/tool_tests.sh b/tests/tool_tests.sh +deleted file mode 100755 +index 7b9a5c3..0000000 +--- a/tests/tool_tests.sh ++++ /dev/null +@@ -1,94 +0,0 @@ +-#!/bin/sh +- +-# This script runs gfs2 utils with various options, checking exit codes against +-# expected values. If any test fails to exit with an expected code, the exit code +-# of the whole script will be non-zero but the tests will continue to be run. The +-# sparse file which is used as the target of the tests can be configured by +-# setting the environment variables TEST_TARGET (the filename) and TEST_TARGET_SZ +-# (its apparent size in gigabytes). Defaults to "testvol" and 10GB. +- +-MKFS="${TOPBUILDDIR}/gfs2/mkfs/mkfs.gfs2 -O" +-FSCK="${TOPBUILDDIR}/gfs2/fsck/fsck.gfs2 -n" +- +-# Name of the sparse file we'll use for testing +-TEST_TARGET=${TEST_TARGET:-testvol} +-# Log of test output +-TEST_LOG=${TEST_LOG:-tests.log} +-truncate -cs0 "${TEST_LOG}" +-# Size, in GB, of the sparse file we'll create to run the tests +-TEST_TARGET_SZ=${TEST_TARGET_SZ:-10} +-[ $TEST_TARGET_SZ -gt 0 ] || { echo "Target size (in GB) must be greater than 0" >&2; exit 1; } +-# Overall success (so we can keep going if one test fails) +-TEST_RET=0 +- +-fn_test() +-{ +- local expected="$1" +- local cmd="$2" +- echo -n "** Test '$cmd'" | tee -a "${TEST_LOG}" +- $cmd &>> "${TEST_LOG}"; +- local ret=$? +- echo -n " (exp: $expected got: $ret) " | tee -a "${TEST_LOG}" +- if [ "$ret" != "$expected" ]; +- then +- echo "FAIL" | tee -a "${TEST_LOG}" +- TEST_RET=1 +- TEST_GRP_RET=1 +- else +- echo "PASS" | tee -a "${TEST_LOG}" +- fi +-} +- +-fn_rm_target() +-{ +- fn_test 0 "rm -f $TEST_TARGET" +-} +- +-fn_recreate_target() +-{ +- fn_rm_target +- fn_test 0 "truncate -s ${TEST_TARGET_SZ}G ${TEST_TARGET}" +-} +- +-util_max_blocks() +-{ +- printf $((TEST_TARGET_SZ*1073741824/$1)) +-} +- +-# Tests start here +-fn_recreate_target +-fn_test 0 "$MKFS -p lock_nolock $TEST_TARGET" +-fn_test 0 "$MKFS -p lock_dlm -t foo:bar $TEST_TARGET" +-fn_test 0 "$FSCK $TEST_TARGET" +-fn_test 255 "$MKFS -p badprotocol $TEST_TARGET" +-fn_test 255 "$MKFS -p lock_nolock -r 31 $TEST_TARGET" +-fn_test 255 "$MKFS -p lock_nolock -r 2049 $TEST_TARGET" +-fn_test 0 "$MKFS -p lock_nolock -r 32 $TEST_TARGET" +-fn_test 0 "$FSCK $TEST_TARGET" +-fn_test 0 "$MKFS -p lock_nolock -r 2048 $TEST_TARGET" +-fn_test 0 "$FSCK $TEST_TARGET" +-fn_test 255 "$MKFS -p lock_nolock -b 512 $TEST_TARGET $(($(util_max_blocks 512)+1))" +-fn_test 255 "$MKFS -p lock_nolock -b 4096 $TEST_TARGET $(($(util_max_blocks 4096)+1))" +-fn_test 0 "$MKFS -p lock_nolock -b 512 $TEST_TARGET $(util_max_blocks 512)" +-fn_test 0 "$FSCK $TEST_TARGET" +-fn_test 0 "$MKFS -p lock_nolock -b 4096 $TEST_TARGET $(util_max_blocks 4096)" +-fn_test 0 "$FSCK $TEST_TARGET" +-fn_test 255 "$MKFS -p lock_nolock -J 7 $TEST_TARGET" +-fn_test 255 "$MKFS -p lock_nolock -J 1025 $TEST_TARGET" +-fn_test 0 "$MKFS -p lock_nolock -J 1024 $TEST_TARGET" +-fn_test 0 "$FSCK $TEST_TARGET" +-fn_test 0 "$MKFS -p lock_nolock -J 8 $TEST_TARGET" +-fn_test 0 "$FSCK $TEST_TARGET" +-fn_test 255 "$MKFS -p lock_nolock -c 0 $TEST_TARGET" +-fn_test 255 "$MKFS -p lock_nolock -c 65 $TEST_TARGET" +-fn_test 0 "$MKFS -p lock_nolock -c 1 $TEST_TARGET" +-fn_test 0 "$FSCK $TEST_TARGET" +-fn_test 0 "$MKFS -p lock_nolock -c 64 $TEST_TARGET" +-fn_test 0 "$FSCK $TEST_TARGET" +- +-# Tests end here +- +-# Only remove the test file on success +-[ "$TEST_RET" = "0" ] && fn_test 0 "rm -f $TEST_TARGET" +-echo "Tool test output written to ${TEST_LOG}" +-exit $TEST_RET diff --git a/SOURCES/bz1001583-1-fsck_gfs2_Allocate_enough_space_for_the_block_map.patch b/SOURCES/bz1001583-1-fsck_gfs2_Allocate_enough_space_for_the_block_map.patch new file mode 100644 index 0000000..4cb0e05 --- /dev/null +++ b/SOURCES/bz1001583-1-fsck_gfs2_Allocate_enough_space_for_the_block_map.patch @@ -0,0 +1,45 @@ +commit a8f380e9330ffa6d08b172041433ed46adc7b207 +Author: Andrew Price +Date: Mon Aug 19 15:23:57 2013 +0100 + + fsck.gfs2: Allocate enough space for the block map + + Building with gcc 4.8's address sanitizer and running the test suite + throws up an issue where the block map allocated in fsck.gfs2 is not + large enough when the required size is an odd number. For example, when + the number of blocks is 3, the mapsize (number of chars to allocate + memory for) would be (3 >> 1) which is too small as each block requires + 4 bits. This patch adds 1 to the mapsize, as suggested in an existing + comment, to ensure we have enough space in these situations. + + Note that this has (probably) never made fsck.gfs2 misbehave as it only + ever accessed 4 bits past the end of the block map and by chance that + memory was never being modified by anything else in the rare cases in + which it was used. + + Resolves: bz#1001583 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c +index 408d89a..3e3050f 100644 +--- a/gfs2/fsck/util.c ++++ b/gfs2/fsck/util.c +@@ -534,15 +534,10 @@ static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size) + + /* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs + * must be 1-based */ +- bmap->mapsize = BLOCKMAP_SIZE4(size); ++ bmap->mapsize = BLOCKMAP_SIZE4(size) + 1; + +- if (!(bmap->map = malloc(sizeof(char) * bmap->mapsize))) ++ if (!(bmap->map = calloc(bmap->mapsize, sizeof(char)))) + return -ENOMEM; +- if (!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) { +- free(bmap->map); +- bmap->map = NULL; +- return -ENOMEM; +- } + return 0; + } + diff --git a/SOURCES/bz1001583-2-libgfs2_Move_the_BLOCKMAP_macros_into_fsck_gfs2.patch b/SOURCES/bz1001583-2-libgfs2_Move_the_BLOCKMAP_macros_into_fsck_gfs2.patch new file mode 100644 index 0000000..cd8c2ad --- /dev/null +++ b/SOURCES/bz1001583-2-libgfs2_Move_the_BLOCKMAP_macros_into_fsck_gfs2.patch @@ -0,0 +1,43 @@ +commit f485b63bc2c0daa6b84d0c376fecb74c2d3784bd +Author: Andrew Price +Date: Mon Aug 19 16:21:28 2013 +0100 + + libgfs2: Move the BLOCKMAP_* macros into fsck.gfs2 + + These macros were only being used by fsck.gfs2 so they can safely be + moved into gfs2/fsck/util.h + + Resolves: bz#1001583 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h +index 580acd8..276c726 100644 +--- a/gfs2/fsck/util.h ++++ b/gfs2/fsck/util.h +@@ -23,6 +23,10 @@ extern void dup_listent_delete(struct duptree *dt, struct inode_with_dups *id); + + extern const char *reftypes[ref_types + 1]; + ++#define BLOCKMAP_SIZE4(size) ((size) >> 1) ++#define BLOCKMAP_BYTE_OFFSET4(x) (((x) & 0x0000000000000001) << 2) ++#define BLOCKMAP_MASK4 (0xf) ++ + static inline uint8_t block_type(uint64_t bblock) + { + static unsigned char *byte; +diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h +index dd7420b..1548cf3 100644 +--- a/gfs2/libgfs2/libgfs2.h ++++ b/gfs2/libgfs2/libgfs2.h +@@ -68,10 +68,6 @@ __BEGIN_DECLS + + #endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ + +-#define BLOCKMAP_SIZE4(size) (size >> 1) +-#define BLOCKMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2) +-#define BLOCKMAP_MASK4 (0xf) +- + enum lgfs2_meta_type { + LGFS2_MT_GFS2_SB = 0, + LGFS2_MT_GFS_SB = 1, diff --git a/SOURCES/bz1003059-fsck_gfs2_Check_and_repair_per_node_contents_such_as_quota_changeX.patch b/SOURCES/bz1003059-fsck_gfs2_Check_and_repair_per_node_contents_such_as_quota_changeX.patch new file mode 100644 index 0000000..a2cd6e6 --- /dev/null +++ b/SOURCES/bz1003059-fsck_gfs2_Check_and_repair_per_node_contents_such_as_quota_changeX.patch @@ -0,0 +1,220 @@ +commit e6c114baac5102d0ac8cc542565d56657593e3c5 +Author: Bob Peterson +Date: Tue Sep 3 11:21:00 2013 -0500 + + fsck.gfs2: Check and repair per_node contents such as quota_changeX + + This patch gives fsck.gfs2 the ability to check the system files that + are in the per_node directory: All the inum_rangeX, statfs_changeX + and quota_changeX files. If they're found to be corrupt, they are + deleted and rebuilt. + + rhbz#1003059 + +diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c +index 727cc18..26f7d48 100644 +--- a/gfs2/fsck/pass2.c ++++ b/gfs2/fsck/pass2.c +@@ -1595,6 +1595,116 @@ struct metawalk_fxns pass2_fxns = { + .repair_leaf = pass2_repair_leaf, + }; + ++static int check_metalist_qc(struct gfs2_inode *ip, uint64_t block, ++ struct gfs2_buffer_head **bh, int h, ++ int *is_valid, int *was_duplicate, void *private) ++{ ++ *was_duplicate = 0; ++ *is_valid = 1; ++ *bh = bread(ip->i_sbd, block); ++ return meta_is_good; ++} ++ ++static int check_data_qc(struct gfs2_inode *ip, uint64_t metablock, ++ uint64_t block, void *private) ++{ ++ struct gfs2_buffer_head *bh; ++ ++ /* At this point, basic data block checks have already been done, ++ so we only need to make sure they're QC blocks. */ ++ if (!valid_block(ip->i_sbd, block)) ++ return -1; ++ ++ bh = bread(ip->i_sbd, block); ++ if (gfs2_check_meta(bh, GFS2_METATYPE_QC) != 0) { ++ log_crit(_("Error: quota_change block at %lld (0x%llx) is " ++ "the wrong metadata type.\n"), ++ (unsigned long long)block, (unsigned long long)block); ++ brelse(bh); ++ return -1; ++ } ++ brelse(bh); ++ return 0; ++} ++ ++struct metawalk_fxns quota_change_fxns = { ++ .check_metalist = check_metalist_qc, ++ .check_data = check_data_qc, ++}; ++ ++/* check_pernode_for - verify a file within the system per_node directory ++ * @x - index number X ++ * @per_node - pointer to the per_node inode ++ * @fn - system file name ++ * @filelen - the file length the system file needs to be ++ * @multiple - the file length must be a multiple (versus the exact value) ++ * @pass - a metawalk function for checking the data blocks (if any) ++ * @builder - a rebuild function for the file ++ * ++ * Returns: 0 if all went well, else error. */ ++static int check_pernode_for(int x, struct gfs2_inode *pernode, const char *fn, ++ unsigned long long filelen, int multiple, ++ struct metawalk_fxns *pass, ++ int builder(struct gfs2_inode *per_node, ++ unsigned int j)) ++{ ++ struct gfs2_inode *ip; ++ int error, valid_size = 1; ++ ++ log_debug(_("Checking system file %s\n"), fn); ++ error = gfs2_lookupi(pernode, fn, strlen(fn), &ip); ++ if (error) { ++ log_err(_("System file %s is missing.\n"), fn); ++ if (!query( _("Rebuild the system file? (y/n) "))) ++ return 0; ++ goto build_it; ++ } ++ if (!ip->i_di.di_size) ++ valid_size = 0; ++ else if (!multiple && ip->i_di.di_size != filelen) ++ valid_size = 0; ++ else if (multiple && (ip->i_di.di_size % filelen)) ++ valid_size = 0; ++ if (!valid_size) { ++ log_err(_("System file %s has an invalid size. Is %llu, " ++ "should be %llu.\n"), fn, ip->i_di.di_size, filelen); ++ if (!query( _("Rebuild the system file? (y/n) "))) ++ goto out_good; ++ fsck_inode_put(&ip); ++ goto build_it; ++ } ++ if (pass) { ++ error = check_metatree(ip, pass); ++ if (!error) ++ goto out_good; ++ log_err(_("System file %s has bad contents.\n"), fn); ++ if (!query( _("Delete and rebuild the system file? (y/n) "))) ++ goto out_good; ++ check_metatree(ip, &pass2_fxns_delete); ++ fsck_inode_put(&ip); ++ gfs2_dirent_del(pernode, fn, strlen(fn)); ++ goto build_it; ++ } ++out_good: ++ fsck_inode_put(&ip); ++ return 0; ++ ++build_it: ++ if (builder(pernode, x)) { ++ log_err(_("Error building %s\n"), fn); ++ return -1; ++ } ++ error = gfs2_lookupi(pernode, fn, strlen(fn), &ip); ++ if (error) { ++ log_err(_("Error rebuilding %s.\n"), fn); ++ return -1; ++ } ++ fsck_blockmap_set(ip, ip->i_di.di_num.no_addr, fn, gfs2_inode_file); ++ reprocess_inode(ip, fn); ++ log_err(_("System file %s rebuilt.\n"), fn); ++ goto out_good; ++} ++ + /* Check system directory inode */ + /* Should work for all system directories: root, master, jindex, per_node */ + static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, +@@ -1707,7 +1817,26 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname, + sysinode->i_di.di_num.no_addr); + } + } +- return 0; ++ error = 0; ++ if (sysinode == sysinode->i_sbd->md.pinode) { ++ int j; ++ char fn[64]; ++ ++ /* Make sure all the per_node files are there, and valid */ ++ for (j = 0; j < sysinode->i_sbd->md.journals; j++) { ++ sprintf(fn, "inum_range%d", j); ++ error += check_pernode_for(j, sysinode, fn, 16, 0, ++ NULL, build_inum_range); ++ sprintf(fn, "statfs_change%d", j); ++ error += check_pernode_for(j, sysinode, fn, 24, 0, ++ NULL, build_statfs_change); ++ sprintf(fn, "quota_change%d", j); ++ error += check_pernode_for(j, sysinode, fn, 1048576, 1, ++ "a_change_fxns, ++ build_quota_change); ++ } ++ } ++ return error; + } + + /** +diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h +index 1548cf3..f864a08 100644 +--- a/gfs2/libgfs2/libgfs2.h ++++ b/gfs2/libgfs2/libgfs2.h +@@ -770,6 +770,10 @@ extern int do_init_statfs(struct gfs2_sbd *sdp); + extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type); + extern unsigned lgfs2_bm_scan(struct rgrp_tree *rgd, unsigned idx, + uint64_t *buf, uint8_t state); ++extern int build_inum_range(struct gfs2_inode *per_node, unsigned int j); ++extern int build_statfs_change(struct gfs2_inode *per_node, unsigned int j); ++extern int build_quota_change(struct gfs2_inode *per_node, unsigned int j); ++ + /* super.c */ + extern int check_sb(struct gfs2_sb *sb); + extern int read_sb(struct gfs2_sbd *sdp); +diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c +index 2a8c6f7..e888f1e 100644 +--- a/gfs2/libgfs2/structures.c ++++ b/gfs2/libgfs2/structures.c +@@ -180,7 +180,7 @@ int build_jindex(struct gfs2_sbd *sdp) + return 0; + } + +-static int build_inum_range(struct gfs2_inode *per_node, unsigned int j) ++int build_inum_range(struct gfs2_inode *per_node, unsigned int j) + { + struct gfs2_sbd *sdp = per_node->i_sbd; + char name[256]; +@@ -204,7 +204,7 @@ static int build_inum_range(struct gfs2_inode *per_node, unsigned int j) + return 0; + } + +-static int build_statfs_change(struct gfs2_inode *per_node, unsigned int j) ++int build_statfs_change(struct gfs2_inode *per_node, unsigned int j) + { + struct gfs2_sbd *sdp = per_node->i_sbd; + char name[256]; +@@ -228,7 +228,7 @@ static int build_statfs_change(struct gfs2_inode *per_node, unsigned int j) + return 0; + } + +-static int build_quota_change(struct gfs2_inode *per_node, unsigned int j) ++int build_quota_change(struct gfs2_inode *per_node, unsigned int j) + { + struct gfs2_sbd *sdp = per_node->i_sbd; + struct gfs2_meta_header mh; +diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c +index eb97c40..f87734a 100644 +--- a/gfs2/libgfs2/super.c ++++ b/gfs2/libgfs2/super.c +@@ -119,6 +119,7 @@ int read_sb(struct gfs2_sbd *sdp) + sdp->sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sdp->bsize; + sdp->sd_blocks_per_bitmap = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) + * GFS2_NBBY; ++ sdp->qcsize = GFS2_DEFAULT_QCSIZE; + + return 0; + } diff --git a/SOURCES/bz990683-fsck_gfs2_Add_ability_to_detect_journal_inode_indirect_block_corruption.patch b/SOURCES/bz990683-fsck_gfs2_Add_ability_to_detect_journal_inode_indirect_block_corruption.patch new file mode 100644 index 0000000..f73d832 --- /dev/null +++ b/SOURCES/bz990683-fsck_gfs2_Add_ability_to_detect_journal_inode_indirect_block_corruption.patch @@ -0,0 +1,193 @@ +commit 83f0041621aa8abf112ae5c89d0f129cf00d8905 +Author: Bob Peterson +Date: Tue Jul 30 14:01:40 2013 -0500 + + fsck.gfs2: Add ability to detect journal inode indirect block corruption + + This patch gives the journal replay portion of fsck.gfs2 the ability to + do basic sanity checks on the indirect blocks associated with journals. + If corrupt indirect blocks are found, the journal is considered damaged, + and should be rebuilt by pass1. + + rhbz#990683 + +diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c +index 71d9909..41d575a 100644 +--- a/gfs2/fsck/fs_recovery.c ++++ b/gfs2/fsck/fs_recovery.c +@@ -12,6 +12,7 @@ + #include "fsck.h" + #include "fs_recovery.h" + #include "libgfs2.h" ++#include "metawalk.h" + #include "util.h" + + #define JOURNAL_NAME_SIZE 16 +@@ -559,6 +560,63 @@ reinit: + return error; + } + ++/* We can't use the rangecheck function from pass1 because we haven't gone ++ * through initialization properly yet. */ ++static int rangecheck_jblock(struct gfs2_inode *ip, uint64_t block) ++{ ++ if((block > ip->i_sbd->fssize) || (block <= ip->i_sbd->sb_addr)) { ++ log_info( _("Bad block pointer (out of range) found in " ++ "journal inode %lld (0x%llx).\n"), ++ (unsigned long long)ip->i_di.di_num.no_addr, ++ (unsigned long long)ip->i_di.di_num.no_addr); ++ return meta_error; /* Exits check_metatree quicker */ ++ } ++ return meta_is_good; ++} ++ ++static int rangecheck_jmeta(struct gfs2_inode *ip, uint64_t block, ++ struct gfs2_buffer_head **bh, int h, ++ int *is_valid, int *was_duplicate, ++ void *private) ++{ ++ int rc; ++ ++ *bh = NULL; ++ *was_duplicate = 0; ++ *is_valid = 0; ++ rc = rangecheck_jblock(ip, block); ++ if (rc == meta_is_good) { ++ *bh = bread(ip->i_sbd, block); ++ *is_valid = (gfs2_check_meta(*bh, GFS2_METATYPE_IN) == 0); ++ if (!(*is_valid)) { ++ log_err( _("Journal at block %lld (0x%llx) has a bad " ++ "indirect block pointer %lld (0x%llx) " ++ "(points to something that is not an " ++ "indirect block).\n"), ++ (unsigned long long)ip->i_di.di_num.no_addr, ++ (unsigned long long)ip->i_di.di_num.no_addr, ++ (unsigned long long)block, ++ (unsigned long long)block); ++ brelse(*bh); ++ return meta_skip_further; ++ } ++ } ++ return rc; ++} ++ ++static int rangecheck_jdata(struct gfs2_inode *ip, uint64_t metablock, ++ uint64_t block, void *private) ++{ ++ return rangecheck_jblock(ip, block); ++} ++ ++struct metawalk_fxns rangecheck_journal = { ++ .private = NULL, ++ .invalid_meta_is_fatal = 1, ++ .check_metalist = rangecheck_jmeta, ++ .check_data = rangecheck_jdata, ++}; ++ + /* + * replay_journals - replay the journals + * sdp: the super block +@@ -583,9 +641,39 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check, + sdp->jsize = GFS2_DEFAULT_JSIZE; + + for(i = 0; i < sdp->md.journals; i++) { ++ if (sdp->md.journal[i]) { ++ struct rgrp_tree rgd; ++ struct gfs2_bitmap bits; ++ ++ /* The real rgrp tree hasn't been built at this point, ++ * so we need to dummy one up that covers the whole ++ * file system so basic functions in check_metatree ++ * don't segfault. */ ++ rgd.start = sdp->sb_addr + 1; ++ rgd.length = 1; ++ rgd.bh = NULL; ++ bits.bi_start = 0; ++ bits.bi_len = sdp->fssize / GFS2_NBBY; ++ rgd.bits = &bits; ++ rgd.ri.ri_addr = sdp->sb_addr + 1; ++ rgd.ri.ri_length = 1; ++ rgd.ri.ri_data0 = sdp->sb_addr + 2; ++ rgd.ri.ri_data = sdp->fssize - (sdp->sb_addr + 2); ++ ++ sdp->rgtree.osi_node = (struct osi_node *)&rgd; ++ error = check_metatree(sdp->md.journal[i], ++ &rangecheck_journal); ++ sdp->rgtree.osi_node = NULL; ++ if (error) ++ /* Don't use fsck_inode_put here because it's a ++ system file and we need to dismantle it. */ ++ inode_put(&sdp->md.journal[i]); ++ error = 0; /* bad journal is non-fatal */ ++ } + if (!sdp->md.journal[i]) { + log_err(_("File system journal \"journal%d\" is " +- "missing: pass1 will try to recreate it.\n"), ++ "missing or corrupt: pass1 will try to " ++ "recreate it.\n"), + i); + continue; + } +diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c +index 22f3334..b8cef87 100644 +--- a/gfs2/fsck/metawalk.c ++++ b/gfs2/fsck/metawalk.c +@@ -1238,9 +1238,12 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp, + for (tmp = prev_list->next; tmp != prev_list; tmp = tmp->next){ + bh = osi_list_entry(tmp, struct gfs2_buffer_head, + b_altlist); ++ if (gfs2_check_meta(bh, iblk_type)) { ++ if (pass->invalid_meta_is_fatal) ++ return meta_error; + +- if (gfs2_check_meta(bh, iblk_type)) + continue; ++ } + + /* Now check the metadata itself */ + for (ptr = (uint64_t *)(bh->b_data + head_size); +@@ -1286,6 +1289,9 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp, + "%llu (0x%llx)\n"), + (unsigned long long)block, + (unsigned long long)block); ++ if (pass->invalid_meta_is_fatal) ++ return meta_error; ++ + continue; + } + if (was_duplicate) { +@@ -1300,6 +1306,9 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp, + "%lld (0x%llx)\n"), + (unsigned long long)block, + (unsigned long long)block); ++ if (pass->invalid_meta_is_fatal) ++ return meta_error; ++ + continue; + } + if (!nbh) +diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h +index a5a51c2..5e30bfe 100644 +--- a/gfs2/fsck/metawalk.h ++++ b/gfs2/fsck/metawalk.h +@@ -93,6 +93,7 @@ enum meta_check_rc { + */ + struct metawalk_fxns { + void *private; ++ int invalid_meta_is_fatal; + int (*check_leaf_depth) (struct gfs2_inode *ip, uint64_t leaf_no, + int ref_count, struct gfs2_buffer_head *lbh); + int (*check_leaf) (struct gfs2_inode *ip, uint64_t block, +diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c +index a701d82..408d89a 100644 +--- a/gfs2/fsck/util.c ++++ b/gfs2/fsck/util.c +@@ -579,6 +579,8 @@ int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock, + static unsigned char *byte; + static uint64_t b; + ++ if (!bmap) ++ return 0; + if (bblock > bmap->size) + return -1; + diff --git a/SOURCES/bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string.patch b/SOURCES/bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string.patch new file mode 100644 index 0000000..dc5e4de --- /dev/null +++ b/SOURCES/bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string.patch @@ -0,0 +1,185 @@ +commit 43da4b0b6a55cfad8f78a703fb3359cac0c4968a +Author: Andrew Price +Date: Thu Aug 8 17:50:47 2013 +0100 + + gfs2_grow: Don't try to open an empty string + + sdp->device_name wasn't getting set in gfs2_grow so is_gfs2() (called + via check_for_gfs2()) fails to open "" and so we get an ENOENT. + + This fixes the open("") by setting sdp->device_name before passing it to + is_pathname_mounted(), which has been updated to make it more clear + which args will be modified by it. + + is_gfs2() and check_for_gfs2() have also been removed from libgfs2 as + these were the only places they were being called and they aren't + needed: superblock checking is done further along via other functions + calling check_sb(). + + Resolves: rhbz#991204 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c +index b45ae08..6612fe7 100644 +--- a/gfs2/fsck/initialize.c ++++ b/gfs2/fsck/initialize.c +@@ -1491,7 +1491,7 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, + strncpy(sdp->device_name, opts.device, + sizeof(sdp->device_name)); + sdp->path_name = sdp->device_name; /* This gets overwritten */ +- is_mounted = is_pathname_mounted(sdp, &ro); ++ is_mounted = is_pathname_mounted(sdp->path_name, sdp->device_name, &ro); + /* If the device is busy, but not because it's mounted, fail. + This protects against cases where the file system is LVM + and perhaps mounted on a different node. */ +diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h +index fe7129a..e994d3b 100644 +--- a/gfs2/libgfs2/libgfs2.h ++++ b/gfs2/libgfs2/libgfs2.h +@@ -716,11 +716,9 @@ extern void decrease_verbosity(void); + extern int compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize, + uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs); + extern int compute_constants(struct gfs2_sbd *sdp); +-extern int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount); +-extern int is_gfs2(struct gfs2_sbd *sdp); ++extern int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount); + extern int find_gfs2_meta(struct gfs2_sbd *sdp); + extern int dir_exists(const char *dir); +-extern int check_for_gfs2(struct gfs2_sbd *sdp); + extern int mount_gfs2_meta(struct gfs2_sbd *sdp); + extern void cleanup_metafs(struct gfs2_sbd *sdp); + extern int set_sysfs(const char *fsname, const char *filename, const char *val); +diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c +index c05a770..6f2dbdb 100644 +--- a/gfs2/libgfs2/misc.c ++++ b/gfs2/libgfs2/misc.c +@@ -99,7 +99,7 @@ int compute_constants(struct gfs2_sbd *sdp) + return 0; + } + +-int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) ++int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount) + { + FILE *fp; + struct mntent *mnt; +@@ -112,7 +112,7 @@ int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) + perror("open: /proc/mounts"); + return 0; + } +- if (stat(sdp->path_name, &st_buf) == 0) { ++ if (stat(path_name, &st_buf) == 0) { + if (S_ISBLK(st_buf.st_mode)) { + #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ + file_rdev = st_buf.st_rdev; +@@ -124,12 +124,12 @@ int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) + } + while ((mnt = getmntent (fp)) != NULL) { + /* Check if they specified the device instead of mnt point */ +- if (strcmp(sdp->device_name, mnt->mnt_fsname) == 0) { +- strcpy(sdp->path_name, mnt->mnt_dir); /* fix it */ ++ if (strcmp(device_name, mnt->mnt_fsname) == 0) { ++ strcpy(path_name, mnt->mnt_dir); /* fix it */ + break; + } +- if (strcmp(sdp->path_name, mnt->mnt_dir) == 0) { +- strcpy(sdp->device_name, mnt->mnt_fsname); /* fix it */ ++ if (strcmp(path_name, mnt->mnt_dir) == 0) { ++ strcpy(device_name, mnt->mnt_fsname); /* fix it */ + break; + } + if (stat(mnt->mnt_fsname, &st_buf) == 0) { +@@ -160,36 +160,6 @@ int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) + return 1; /* mounted */ + } + +-int is_gfs2(struct gfs2_sbd *sdp) +-{ +- int fd, rc; +- struct gfs2_sb sb; +- +- fd = open(sdp->device_name, O_RDWR); +- if (fd < 0) +- return 0; +- +- rc = 0; +- if (lseek(fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK, SEEK_SET) >= 0 && +- read(fd, &sb, sizeof(sb)) == sizeof(sb) && +- be32_to_cpu(sb.sb_header.mh_magic) == GFS2_MAGIC && +- be32_to_cpu(sb.sb_header.mh_type) == GFS2_METATYPE_SB) +- rc = 1; +- close(fd); +- return rc; +-} +- +-int check_for_gfs2(struct gfs2_sbd *sdp) +-{ +- int ro; +- +- if (!is_pathname_mounted(sdp, &ro)) +- return -1; +- if (!is_gfs2(sdp)) +- return -1; +- return 0; +-} +- + static int lock_for_admin(struct gfs2_sbd *sdp) + { + int error; +diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c +index 73c7f84..d324af9 100644 +--- a/gfs2/mkfs/main_grow.c ++++ b/gfs2/mkfs/main_grow.c +@@ -323,6 +323,7 @@ main_grow(int argc, char *argv[]) + int rgcount, rindex_fd; + char rindex_name[PATH_MAX]; + int error = EXIT_SUCCESS; ++ int ro_mnt = 0; + + memset(sdp, 0, sizeof(struct gfs2_sbd)); + sdp->bsize = GFS2_DEFAULT_BSIZE; +@@ -336,17 +337,20 @@ main_grow(int argc, char *argv[]) + int sane; + struct rgrp_tree *last_rgrp; + ++ strncpy(sdp->device_name, argv[optind], PATH_MAX - 1); + sdp->path_name = argv[optind++]; +- sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC); +- if (sdp->path_fd < 0){ ++ ++ if ((!is_pathname_mounted(sdp->path_name, sdp->device_name, &ro_mnt))) { + perror(sdp->path_name); + exit(EXIT_FAILURE); + } + +- if (check_for_gfs2(sdp)) { ++ sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC); ++ if (sdp->path_fd < 0){ + perror(sdp->path_name); + exit(EXIT_FAILURE); + } ++ + sdp->device_fd = open(sdp->device_name, + (test ? O_RDONLY : O_RDWR) | O_CLOEXEC); + if (sdp->device_fd < 0){ +diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c +index 58fb046..2646829 100644 +--- a/gfs2/mkfs/main_jadd.c ++++ b/gfs2/mkfs/main_jadd.c +@@ -491,6 +491,7 @@ void main_jadd(int argc, char *argv[]) + { + struct gfs2_sbd sbd, *sdp = &sbd; + unsigned int total; ++ int ro_mnt = 0; + + memset(sdp, 0, sizeof(struct gfs2_sbd)); + sdp->jsize = GFS2_DEFAULT_JSIZE; +@@ -506,7 +507,7 @@ void main_jadd(int argc, char *argv[]) + exit(EXIT_FAILURE); + } + +- if (check_for_gfs2(sdp)) { ++ if (!is_pathname_mounted(sdp->path_name, sdp->device_name, &ro_mnt)) { + perror(sdp->path_name); + exit(EXIT_FAILURE); + } diff --git a/SOURCES/bz996236-gfs2_tool_catch_interrupts_while_the_metafs_is_mounted.patch b/SOURCES/bz996236-gfs2_tool_catch_interrupts_while_the_metafs_is_mounted.patch new file mode 100644 index 0000000..f1163f1 --- /dev/null +++ b/SOURCES/bz996236-gfs2_tool_catch_interrupts_while_the_metafs_is_mounted.patch @@ -0,0 +1,184 @@ +commit 12604ad33b41eca2b7c6511da8d519a299787ef5 +Author: Bob Peterson +Date: Mon Aug 12 15:08:55 2013 -0500 + + gfs2_tool: catch interrupts while the metafs is mounted + + This patch catches interrupt signals while the metafs is mounted, + and if interrupted, sets a flag. Later, if the caller sees the flag, + they will unmount the metafs. That way, the metafs is never left + mounted by accident if a gfs2_grow or gfs2_jadd is interrupted or + killed. + +diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h +index e994d3b..dd7420b 100644 +--- a/gfs2/libgfs2/libgfs2.h ++++ b/gfs2/libgfs2/libgfs2.h +@@ -713,6 +713,8 @@ extern void increase_verbosity(void); + extern void decrease_verbosity(void); + /* misc.c */ + ++extern int metafs_interrupted; ++ + extern int compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize, + uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs); + extern int compute_constants(struct gfs2_sbd *sdp); +diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c +index 6f2dbdb..7f500e6 100644 +--- a/gfs2/libgfs2/misc.c ++++ b/gfs2/libgfs2/misc.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + #include "libgfs2.h" + +@@ -25,6 +26,8 @@ + #define SYS_BASE "/sys/fs/gfs2" /* FIXME: Look in /proc/mounts to find this */ + #define DIV_RU(x, y) (((x) + (y) - 1) / (y)) + ++int metafs_interrupted = 0; ++ + int compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize, + uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs) + { +@@ -179,10 +182,15 @@ static int lock_for_admin(struct gfs2_sbd *sdp) + return 0; + } + ++static void sighandler(int error) ++{ ++ metafs_interrupted = 1; ++} + + int mount_gfs2_meta(struct gfs2_sbd *sdp) + { + int ret; ++ struct sigaction sa = { .sa_handler = &sighandler }; + + memset(sdp->metafs_path, 0, PATH_MAX); + snprintf(sdp->metafs_path, PATH_MAX - 1, "/tmp/.gfs2meta.XXXXXX"); +@@ -190,6 +198,15 @@ int mount_gfs2_meta(struct gfs2_sbd *sdp) + if(!mkdtemp(sdp->metafs_path)) + return -1; + ++ sigaction(SIGINT, &sa, NULL); ++ sigaction(SIGILL, &sa, NULL); ++ sigaction(SIGTERM, &sa, NULL); ++ sigaction(SIGHUP, &sa, NULL); ++ sigaction(SIGABRT, &sa, NULL); ++ sigaction(SIGSEGV, &sa, NULL); ++ sigaction(SIGCONT, &sa, NULL); ++ sigaction(SIGUSR1, &sa, NULL); ++ sigaction(SIGUSR2, &sa, NULL); + ret = mount(sdp->path_name, sdp->metafs_path, "gfs2meta", 0, NULL); + if (ret) { + rmdir(sdp->metafs_path); +@@ -203,6 +220,7 @@ int mount_gfs2_meta(struct gfs2_sbd *sdp) + void cleanup_metafs(struct gfs2_sbd *sdp) + { + int ret; ++ struct sigaction sa = { .sa_handler = SIG_DFL }; + + if (sdp->metafs_fd <= 0) + return; +@@ -215,6 +233,16 @@ void cleanup_metafs(struct gfs2_sbd *sdp) + sdp->metafs_path, strerror(errno)); + else + rmdir(sdp->metafs_path); ++ sigaction(SIGINT, &sa, NULL); ++ sigaction(SIGILL, &sa, NULL); ++ sigaction(SIGTERM, &sa, NULL); ++ sigaction(SIGHUP, &sa, NULL); ++ sigaction(SIGABRT, &sa, NULL); ++ sigaction(SIGSEGV, &sa, NULL); ++ sigaction(SIGCONT, &sa, NULL); ++ sigaction(SIGUSR1, &sa, NULL); ++ sigaction(SIGUSR2, &sa, NULL); ++ metafs_interrupted = 0; + } + + int set_sysfs(const char *fsname, const char *filename, const char *val) +diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c +index d324af9..5db91d9 100644 +--- a/gfs2/mkfs/main_grow.c ++++ b/gfs2/mkfs/main_grow.c +@@ -372,10 +372,13 @@ main_grow(int argc, char *argv[]) + perror(_("Bad constants (1)")); + exit(EXIT_FAILURE); + } +- if (read_sb(sdp) < 0) +- die( _("Error reading superblock.\n")); ++ if (read_sb(sdp) < 0) { ++ fprintf(stderr, _("Error reading superblock.\n")); ++ exit(EXIT_FAILURE); ++ } + if (sdp->gfs1) { +- die( _("cannot grow gfs1 filesystem\n")); ++ fprintf(stderr, _("cannot grow gfs1 filesystem\n")); ++ exit(EXIT_FAILURE); + } + fix_device_geometry(sdp); + if (mount_gfs2_meta(sdp)) { +@@ -387,7 +390,8 @@ main_grow(int argc, char *argv[]) + rindex_fd = open(rindex_name, (test ? O_RDONLY : O_RDWR) | O_CLOEXEC); + if (rindex_fd < 0) { + cleanup_metafs(sdp); +- die( _("GFS2 rindex not found. Please run fsck.gfs2.\n")); ++ perror(_("GFS2 rindex not found. Please run fsck.gfs2.\n")); ++ exit(EXIT_FAILURE); + } + /* Get master dinode */ + sdp->master_dir = lgfs2_inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr); +@@ -402,6 +406,8 @@ main_grow(int argc, char *argv[]) + /* we're only going to write out new RG information after */ + /* the existing RGs, and only write to the index at EOF. */ + ri_update(sdp, rindex_fd, &rgcount, &sane); ++ if (metafs_interrupted) ++ goto out; + fssize = filesystem_size(sdp); + if (!sdp->rgtree.osi_node) { + log_err(_("Error: No resource groups found.\n")); +@@ -424,10 +430,16 @@ main_grow(int argc, char *argv[]) + } else { + int old_rg_count; + ++ if (metafs_interrupted) ++ goto out; + compute_rgrp_layout(sdp, &sdp->rgtree, TRUE); ++ if (metafs_interrupted) ++ goto out; + debug_print_rgrps(sdp, &sdp->rgtree); + print_info(sdp); + initialize_new_portion(sdp, &old_rg_count); ++ if (metafs_interrupted) ++ goto out; + fix_rindex(sdp, rindex_fd, old_rg_count); + } + out: +@@ -439,6 +451,7 @@ main_grow(int argc, char *argv[]) + } + close(sdp->path_fd); + sync(); +- log_notice( _("gfs2_grow complete.\n")); ++ if (!metafs_interrupted) ++ log_notice( _("gfs2_grow complete.\n")); + exit(error); + } +diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c +index 2646829..b6cd8e4 100644 +--- a/gfs2/mkfs/main_jadd.c ++++ b/gfs2/mkfs/main_jadd.c +@@ -529,6 +529,10 @@ void main_jadd(int argc, char *argv[]) + for (sdp->md.journals = sdp->orig_journals; + sdp->md.journals < total; + sdp->md.journals++) { ++ if (metafs_interrupted) { ++ cleanup_metafs(&sbd); ++ exit(130); ++ } + add_ir(sdp); + add_sc(sdp); + add_qc(sdp); diff --git a/SPECS/gfs2-utils.spec b/SPECS/gfs2-utils.spec new file mode 100644 index 0000000..4799851 --- /dev/null +++ b/SPECS/gfs2-utils.spec @@ -0,0 +1,376 @@ +############################################################################### +############################################################################### +## +## Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved. +## +## This copyrighted material is made available to anyone wishing to use, +## modify, copy, or redistribute it subject to the terms and conditions +## of the GNU General Public License v.2. +## +############################################################################### +############################################################################### + +Name: gfs2-utils +Version: 3.1.6 +Release: 8%{?dist} +License: GPLv2+ and LGPLv2+ +Group: System Environment/Kernel +Summary: Utilities for managing the global file system (GFS2) +%{?fedora:Requires: kernel-modules-extra} +Obsoletes: gfs2-cluster < %{version} +BuildRequires: ncurses-devel +BuildRequires: kernel-headers +BuildRequires: automake +BuildRequires: perl +BuildRequires: libtool +BuildRequires: zlib-devel +BuildRequires: gettext-devel +BuildRequires: bison +BuildRequires: flex +BuildRequires: libblkid-devel +BuildRequires: check-devel +URL: https://fedorahosted.org/cluster/wiki/HomePage + +# The source for this package was pulled from the upstream git tree. +# Use the following commands to generate the tarball: +# git clone git://git.fedorahosted.org/gfs2-utils.git +# cd gfs2-utils +# ./make-tarball.sh +# +Source0: https://fedorahosted.org/released/gfs2-utils/gfs2-utils-%{version}.tar.gz +Patch0: bz990683-fsck_gfs2_Add_ability_to_detect_journal_inode_indirect_block_corruption.patch +Patch1: bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string.patch +Patch2: bz1000066-gfs2_utils_tests_Switch_to_autotest.patch +Patch3: bz1001583-1-fsck_gfs2_Allocate_enough_space_for_the_block_map.patch +Patch4: bz1001583-2-libgfs2_Move_the_BLOCKMAP_macros_into_fsck_gfs2.patch +Patch5: bz996236-gfs2_tool_catch_interrupts_while_the_metafs_is_mounted.patch +Patch6: bz1003059-fsck_gfs2_Check_and_repair_per_node_contents_such_as_quota_changeX.patch + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +%prep +%setup -q -n gfs2-utils +%patch0 -p1 -b .bz990683-fsck_gfs2_Add_ability_to_detect_journal_inode_indirect_block_corruption +%patch1 -p1 -b .bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string +%patch2 -p1 -b .bz1000066-gfs2_utils_tests_Switch_to_autotest.patch +%patch3 -p1 -b .bz1001583-1-fsck_gfs2_Allocate_enough_space_for_the_block_map.patch +%patch4 -p1 -b .bz1001583-2-libgfs2_Move_the_BLOCKMAP_macros_into_fsck_gfs2.patch +%patch5 -p1 -b .bz996236-gfs2_tool_catch_interrupts_while_the_metafs_is_mounted +%patch6 -p1 -b .bz1003059-fsck_gfs2_Check_and_repair_per_node_contents_such_as_quota_changeX + +%build +./autogen.sh +%configure +make %{_smp_mflags} + +%check +make check + +%install +rm -rf %{buildroot} +make -C gfs2 install DESTDIR=%{buildroot} +# Don't ship gfs2_{trace,lockcapture} in this package +rm -f %{buildroot}/sbin/gfs2_trace +rm -f %{buildroot}/sbin/gfs2_lockcapture +rm -f %{buildroot}%{_mandir}/man8/gfs2_trace.8 +rm -f %{buildroot}%{_mandir}/man8/gfs2_lockcapture.8 +# Install into /usr/sbin per UsrMove +mv %{buildroot}/sbin/fsck.gfs2 %{buildroot}/usr/sbin/ +mv %{buildroot}/sbin/mkfs.gfs2 %{buildroot}/usr/sbin/ +mv %{buildroot}/sbin/gfs2_grow %{buildroot}/usr/sbin/ +mv %{buildroot}/sbin/gfs2_jadd %{buildroot}/usr/sbin/ + +%clean +rm -rf %{buildroot} + +%description -n gfs2-utils +The gfs2-utils package contains a number of utilities for creating, +checking, modifying, and correcting any inconsistencies in GFS2 +file systems. + +%files -n gfs2-utils +%defattr(-,root,root,-) +%doc doc/COPYING.* doc/COPYRIGHT doc/*.txt +%doc doc/README.contributing doc/README.licence doc/README.tests +%{_sbindir}/fsck.gfs2 +%{_sbindir}/gfs2_grow +%{_sbindir}/gfs2_jadd +%{_sbindir}/mkfs.gfs2 +%{_sbindir}/gfs2_convert +%{_sbindir}/gfs2_edit +%{_sbindir}/tunegfs2 +%{_mandir}/man8/*gfs2* +%{_mandir}/man5/* + +%changelog +* Tue Sep 17 2013 Andrew Price - 3.1.6-8 +- Don't use README.* for docs (it can pick up some patch files) + Related: rhbz#1000066 + +* Tue Sep 17 2013 Andrew Price - 3.1.6-7 +- fsck.gfs2: Check and repair per_node contents such as quota_changeX + Resolves: rhbz#1003059 + +* Fri Sep 06 2013 Andrew Price - 3.1.6-6 +- gfs2_tool: catch interrupts while the metafs is mounted + Resolves: rhbz#996236 + +* Tue Aug 27 2013 Andrew Price - 3.1.6-5 +- gfs2-utils tests: Switch to autotest + Resolves: rhbz#1000066 +- fsck.gfs2: Allocate enough space for the block map (2 patches) + Resolves: rhbz#1001583 + +* Tue Aug 27 2013 Andrew Price - 3.1.6-4 +- Install utils into /usr/sbin instead of /sbin + Resolves: rhbz#996539 + +* Tue Aug 13 2013 Andrew Price - 3.1.6-3 +- fsck.gfs2: Add the ability to detect journal inode indirect block corruption + Resolves: rhbz#990683 +- gfs2_grow: Don't try to open an empty string + Resolves: rhbz#991204 + +* Mon Jul 29 2013 Andrew Price - 3.1.6-2 +- Don't install gfs2_lockcapture and gfs2_trace + Resolves: rhbz#987019 +- Run test suite after build (requires check-devel build req) +- Install both of the READMEs into doc/ + +* Wed Jul 24 2013 Andrew Price - 3.1.6-1 +- New upstream release +- Drop 'file' requirement - mkfs.gfs2 now uses libblkid instead +- Drop 'ncurses' requirement - dependency is added automatically +- Drop requires chkconfig and initscripts - no longer installs daemons +- Drop fix_build_on_rawhide.patch - upstream +- Add build req on libblkid-devel + +* Wed Feb 13 2013 Fedora Release Engineering - 3.1.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Nov 13 2012 Andrew Price - 3.1.5-1 +- New upstream release + Removes mount.gfs2, gfs2_tool, gfs2_quota +- Remove rawhide_transition.patch - now obsolete +- Update BuildRequires: + Change glibc-kernheaders to kernel-headers + Add bison and flex +- Provide a valid url for Source0 +- Add fix_build_on_rawhide.patch to fix a circular dep introduced in + bison 2.6, and a make -j race between libgfs2 and gfs2l + +* Tue Aug 14 2012 Andrew Price - 3.1.4-6 +- Make the kernel-modules-extra requirement Fedora-specific + Resolves bz#847955 + +* Thu Jul 19 2012 Fedora Release Engineering - 3.1.4-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Apr 17 2012 Andrew Price - 3.1.4-4 +- Remove commented-out sections +- Clean up some lintian warnings +- Add dependency on kernel-modules-extra as per bz#811547 + +* Wed Mar 07 2012 Andrew Price - 3.1.4-3 +- Remove redundant postinstall scriptlet + +* Thu Feb 2 2012 Fabio M. Di Nitto - 3.1.4-2 +- make sure to Obsolete gfs2-cluster + +* Wed Feb 01 2012 Andrew Price - 3.1.4-1 +- New upstream release + Adds gfs2_lockgather script +- Remove gfs2-cluster (commented out for now) +- Remove dependency on corosynclib-devel and systemd-units +- Add rawhide_transition.patch to stop gfs_controld from building + +* Fri Jan 13 2012 Fedora Release Engineering - 3.1.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Thu Dec 15 2011 Andrew Price - 3.1.3-1 +- New upstream release + Bugfixes and improvements to fsck.gfs2 + Fixes various other bugs + Improve strings and translation support +- Adds gfs2-cluster systemd unit +- Removes gfs2* init scripts + +* Wed Jul 06 2011 Andrew Price - 3.1.2-1 +- New upstream release + Fixes several bugs + Improves translation support + Adds savemeta compression +- Add zlib-devel to BuildRequires +- Add gettext-devel to BuildRequires + +* Wed May 25 2011 Steven Whitehouse - 3.1.1-3 +- Update wiki URL +- Remove gfs2_tool and gfs2_quota from package + +* Fri Feb 25 2011 Bob Peterson - 3.1.1-2 +- Bumping release number to keep upgrades consistent. + +* Wed Feb 23 2011 Bob Peterson - 3.1.1-1 +- gfs2_edit savemeta doesn't save all leafs for big directories +- gfs2_edit improvements +- fsck.gfs2: can't repair rgrps resulting from gfs_grow->gfs2_convert +- fsck.gfs2: reports master/root dinodes as unused and fixes bitmap + +* Tue Feb 08 2011 Fedora Release Engineering - 3.1.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Jan 20 2011 Steven Whitehouse - 3.1.0-4 +- Drop mount.gfs2 and its man page +- Only list gfs2_tool once in the files list + +* Wed Dec 8 2010 Fabio M. Di Nitto - 3.1.0-3 +- Drop circular dependency on cman + +* Fri Dec 3 2010 Fabio M. Di Nitto - 3.1.0-2 +- gfs2-cluster should Obsoletes/Provides gfs-pcmk + +* Tue Sep 30 2010 Steven Whitehouse - 3.1.0-1 +- Bringing this package back for upstream GFS2 + Addition of gfs2tune to the utils + Merge of gfs_controld from cman + +* Thu Jan 22 2009 Fabio M. Di Nitto - 2.03.11-1 +- New upstream release + Fix several bugs and drastically improve startup errors. + +* Wed Dec 10 2008 Fabio M. Di Nitto - 2.03.10-1 +- New upstream release + Fix several bugs and port gfs1 code to match 2.6.27 kernel. + +* Fri Oct 31 2008 Fabio M. Di Nitto - 2.03.09-1 +- New upstream release + Fix rhbz#468966 + Addresses several security issues similar to CVE-2008-4192 and + CVE-2008-4579 after deep code audit from upstream +- cleanup patches to match 2.6.26 kernel in F-9 + +* Tue Oct 21 2008 Fabio M. Di Nitto - 2.03.08-1 +- New upstream release + Fix rhbz#460376 CVE-2008-4192 + Fix rhbz#467386 CVE-2008-4579 +- cleanup/update patches to match 2.6.26 kernel in F-9 + +* Thu Aug 14 2008 Fabio M. Di Nitto - 2.03.07-1 +- New upstream release +- Fix rgmanager startup locking issues +- Apply patch to include kernel headers from 2.6.26 required to build + userland. Userland will run in 2.6.25 compatibility mode +- Apply patch to keep kernel modules at 2.6.25 (upstream is at 2.6.26) + (this patch is purely cosmetic since we don't build kernel modules + but keep the source in sync is Good (tm)) +- Cleanup packaging for installed docs and file permissions + +* Mon Jul 14 2008 Fabio M. Di Nitto - 2.03.05-1 +- New upstream release +- Cleanup installed doc after upstream + +* Wed Jun 11 2008 Fabio M. Di Nitto 2.03.04-1 +- New upstream release +- Resolves: #446995 #318271 #447378 #445662 +- Update license tags after major upstream cleanup +- Include COPYRIGHT file + +* Fri May 30 2008 Fabio M. Di Nitto 2.03.03-1 +- New upstream release +- Fix several build warnings +- Update spec files to use macros +- Update Requires to use packages rather than pointing at files +- Drop BR on kernel-devel since it's not required anymore +- Update build section to use proper _sysconfdir, libdir and sbindir +- Avoid abusing cd when we can ask make to do the work for us +- Remove /usr/sbin from file section. We don't have any file there + and we can avoid shipping stuff by mistake + +* Mon Apr 14 2008 Steven Whitehouse 2.03.00-3 +- Fabbione saves the day. We can get rid of the sed stuff after all + +* Mon Apr 14 2008 Steven Whitehouse 2.03.00-1 +- New upstream sources +- Eric Sandeen's solution to kernel version dep + +* Wed Apr 09 2008 Steven Whitehouse 0.1.25.2.02.01-15 +- Remove obsolete chkconfig patch for initscript +- Enable parallel make +- Remove obsolete copy of gfs2_ondisk.h (this should be in glibc-kernheaders) + +* Wed Apr 09 2008 Steven Whitehouse 0.1.25.2.02.01-14 +- Update URL +- Fix license spec + +* Fri Mar 14 2008 Chris Feist 0.1.25.2.02.00-2 +- New upstream sources. + +* Tue Jan 16 2007 Chris Feist 0.1.24-1 +- New upstream sources. +- Resolves: rhbz#222747 + +* Wed Jan 03 2007 Chris Feist 0.1.24-1 +- Updated sources +- Resolves: rhbz#218560 + +* Thu Dec 21 2006 Chris Feist 0.1.23-1 +- Updated sources +- Resolves: rhbz#218560 + +* Tue Dec 19 2006 Chris Feist 0.1.22-1 +- New upstream sources. +- Resolves: rhbz#219878 + +* Tue Dec 04 2006 Chris Feist 0.1.21-1 +- New upstream sources. +- Resolves: rhbz#218134 rhbz#215962 + +* Thu Nov 30 2006 Chris Feist 0.1.19-1 +- New upstream sources. +- Resolves: rhbz#217798 + +* Wed Nov 29 2006 Chris Feist 0.1.18-1 +- New upstream sources. +- Resolves: rhbz#217460 + +* Thu Oct 26 2006 Chris Feist 0.1.14-1 +- New upstream sources. + +* Fri Oct 13 2006 Chris Feist 0.1.12-1 +- New Upstream sources. + +* Fri Oct 13 2006 Chris Feist 0.1.10-1 +- New Upstream sources. + +* Mon Oct 09 2006 Chris Feist 0.1.9-1 +- New Upstream sources. + +* Mon Sep 25 2006 Chris Feist 0.1.8-1 +- New Upstream sources. + +* Wed Sep 13 2006 Chris Feist 0.1.7-1 +- New Upstream sources. + +* Thu Sep 07 2006 Chris Feist 0.1.6-2 +- Fix typo in uninstall script (turn off gfs2 instead of gfs) + +* Mon Aug 28 2006 Chris Feist 0.1.6-1 +- New Upstream sources. + +* Tue Aug 22 2006 Chris Feist 0.1.5-1 +- New Upstream sources. + +* Mon Aug 14 2006 Chris Feist 0.1.3-0 +- New Upstream sources, use dist tag. + +* Fri Jul 14 2006 Chris Feist +- Rebuild with updated sources + +* Wed Jul 12 2006 Jesse Keating +- rebuild + +* Tue Jun 27 2006 Florian La Roche +- fix typo in preun script + +* Fri Jun 09 2006 Chris Feist - 0.1.0-1.fc6.3 +- Initial build of gfs-utils.