| #! /bin/bash | |
| # FS QA Test No. 253 | |
| # | |
| # Test xfs_db metadump functionality. | |
| # | |
| # This test was created to verify fixes for problems where metadump | |
| # would never complete due to an inability to find a suitable | |
| # obfuscated name to use. It also verifies a few other things, | |
| # including ensuring the "lost+found" directory and orphaned files | |
| # in it do not get obfuscated. | |
| # | |
| # This test also creates a number of files that are effectively | |
| # duplicates of existing files; this can happen in certain rare | |
| # instances where the obfuscation process has produced a filename | |
| # that is already in use (and no other name is available to use). | |
| # | |
| #----------------------------------------------------------------------- | |
| # Copyright (c) 2011 SGI. All Rights Reserved. | |
| # | |
| # This program is free software; you can redistribute it and/or | |
| # modify it under the terms of the GNU General Public License as | |
| # published by the Free Software Foundation. | |
| # | |
| # This program is distributed in the hope that it would be useful, | |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| # GNU General Public License for more details. | |
| # | |
| # You should have received a copy of the GNU General Public License | |
| # along with this program; if not, write the Free Software Foundation, | |
| # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| #----------------------------------------------------------------------- | |
| # | |
| # creator | |
| owner=aelder@sgi.com | |
| seq=`basename $0` | |
| echo "QA output created by $seq" | |
| here=`pwd` | |
| tmp=/tmp/$$ | |
| status=1 # failure is the default! | |
| trap "_cleanup; exit \$status" 0 1 2 3 15 | |
| _cleanup() | |
| { | |
| cd / | |
| rm -f $tmp.* | |
| rm -rf "${OUTPUT_DIR}" | |
| rm -f "${METADUMP_FILE}" | |
| } | |
| # get standard environment, filters and checks | |
| . ./common.rc | |
| . ./common.filter | |
| _require_scratch | |
| # real QA test starts here | |
| OUTPUT_DIR="${SCRATCH_MNT}/test_${seq}" | |
| METADUMP_FILE="${TEST_MNT}/${seq}_metadump" | |
| ORPHANAGE="lost+found" | |
| _supported_fs xfs | |
| _supported_os Linux | |
| function create_file() { | |
| [ $# -eq 1 ] || return 1 | |
| touch $(printf "$@") | |
| } | |
| echo "Disciplyne of silence is goed." | |
| _scratch_mkfs >/dev/null 2>&1 | |
| _scratch_mount | |
| # Initialize and mount the scratch filesystem, then create a bunch | |
| # of files that exercise the original problem. | |
| # | |
| # The problem arose when a file name produced a hash that contained | |
| # either 0x00 (string terminator) or 0x27 ('/' character) in a | |
| # spot used to determine a character in an obfuscated name. This | |
| # occurred in one of 5 spots at the end of the name, at position | |
| # (last-4), (last-3), (last-2), (last-1), or (last). | |
| rm -f "${METADUMP_FILE}" | |
| mkdir -p "${OUTPUT_DIR}" | |
| cd "${OUTPUT_DIR}" | |
| # Start out with some basic test files | |
| create_file 'abcde' # hash 0x1c58f263 ("normal" name) | |
| create_file 'f' # hash 0x00000066 (1-byte name) | |
| create_file 'gh' # hash 0x000033e8 (2-byte name) | |
| create_file 'ijk' # hash 0x001a756b (3-byte name) | |
| create_file 'lmno' # hash 0x0d9b776f (4-byte name) | |
| create_file 'pqrstu' # hash 0x1e5cf9f2 (6-byte name) | |
| create_file 'abcdefghijklmnopqrstuvwxyz' # a most remarkable word (0x55004ae3) | |
| # Create a short directory name; it won't be obfuscated. Populate | |
| # it with some longer named-files. The first part of the obfuscated | |
| # filenames should use printable characters. | |
| mkdir foo | |
| create_file 'foo/longer_file_name_1' # hash 0xe83634ec | |
| create_file 'foo/longer_file_name_2' # hash 0xe83634ef | |
| create_file 'foo/longer_file_name_3' # hash 0xe83634ee | |
| # Now create a longer directory name | |
| mkdir longer_directory_name | |
| create_file 'longer_directory_name/f1' # directory hash 0x9c7accdd | |
| create_file 'longer_directory_name/f2' # filenames are short, no hash | |
| create_file 'longer_directory_name/f3' | |
| # The problematic name originally reported by Arkadiusz MiĆkiewicz | |
| create_file 'R\323\257NE' # hash 0x3a4be740, forces (last-3) = 0x2f | |
| # Other names that force a 0x00 byte | |
| create_file 'Pbcde' # hash 0x0c58f260, forces (last-4) = 0x00 | |
| create_file 'a\001\203de' # hash 0x1000f263, forces (last-3) = 0x00 | |
| create_file 'ab\001\344e' # hash 0x1c403263, forces (last-2) = 0x00 | |
| create_file 'abc\200e' # hash 0x1c588063, forces (last-1) = 0x00 | |
| create_file 'abcd\006' # hash 0x1c58f200, forces (last) = 0x00 | |
| # Names that force a 0x2f byte; note no name will ever force (last-4) = 0x2f | |
| create_file 'a.\343de' # hash 0x15f8f263 forces (last-3) = 0x00 | |
| create_file 'ac\257de' # hash 0x1c4bf263, forces (last-2) = 0x2f | |
| create_file 'abe\257e' # hash 0x1c5917e3, forces (last-1) = 0x2f | |
| create_file 'abcd)' # hash 0x1c58f22f, forces (last) = 0x2f | |
| # The following names are possible results of obfuscating the name | |
| # "abcde". Previously, xfs_metadump could get hung up trying to | |
| # obfuscate names when too many of the same length had the same hash | |
| # value. | |
| create_file '!bcda' # essentially a dup of 'abcde' | |
| create_file 'Abcdg' # essentially a dup of 'abcde' | |
| create_file 'qbcdd' # essentially a dup of 'abcde' | |
| create_file '1bcd`' # essentially a dup of 'abcde' | |
| create_file 'Qbcdf' # essentially a dup of 'abcde' | |
| create_file '\001bcdc' # essentially a dup of 'abcde' | |
| create_file 'Qbce\346' # essentially a dup of 'abcde' | |
| create_file 'abb\344e' # essentially a dup of 'abcde' | |
| # The orphanage directory (lost+found) should not be obfuscated. | |
| # Files thereunder can be, but not if their name is the same as | |
| # their inode number. Test this. | |
| cd "${SCRATCH_MNT}" | |
| mkdir -p "${ORPHANAGE}" | |
| TEMP_ORPHAN="${ORPHANAGE}/__orphan__" | |
| NON_ORPHAN="${ORPHANAGE}/__should_be_obfuscated__" | |
| # Create an orphan, whose name is the same as its inode number | |
| touch "${TEMP_ORPHAN}" | |
| INUM=$(ls -i "${TEMP_ORPHAN}" | awk '{ print $1; }') | |
| ORPHAN="${SCRATCH_MNT}/lost+found/${INUM}" | |
| mv "${TEMP_ORPHAN}" "${ORPHAN}" | |
| # Create non-orphan, which *should* be obfuscated | |
| touch "${NON_ORPHAN}" | |
| # Get a listing of all the files before obfuscation | |
| ls -R >> "${seq}.full" | |
| ls -R | od -c >> "${seq}.full" | |
| # Now unmount the filesystem and create a metadump file | |
| cd /; sync; sync # Old school | |
| _scratch_unmount | |
| xfs_metadump -f "${SCRATCH_DEV}" "${METADUMP_FILE}" | |
| # Now restore the obfuscated one back and take a look around | |
| xfs_mdrestore "${METADUMP_FILE}" "${SCRATCH_DEV}" | |
| _scratch_mount | |
| # Get a listing of all the files after obfuscation | |
| cd "${SCRATCH_MNT}" | |
| ls -R >> "${seq}.full" | |
| ls -R | od -c >> "${seq}.full" | |
| # Finally, re-make the filesystem since to ensure we don't | |
| # leave a directory with duplicate entries lying around. | |
| cd / | |
| _scratch_unmount | |
| _scratch_mkfs >/dev/null 2>&1 | |
| # all done | |
| status=0 | |
| exit |