common/fuzzy: if the fuzz verb is random, keep fuzzing until we get a new value
[xfstests-dev.git] / common / populate
index c19666a0936bbe68fef159034b00f14867f58986..b77c508107fefed346b6bb4b010001ffe764e1aa 100644 (file)
@@ -21,6 +21,7 @@
 #  Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
 #  Mountain View, CA 94043, USA, or: http://www.sgi.com
 #-----------------------------------------------------------------------
+. ./common/quota
 
 _require_populate_commands() {
        _require_xfs_io_command "falloc"
@@ -73,26 +74,81 @@ __populate_create_attr() {
        done
 }
 
-# Fill up 60% of the remaining free space
+# Fill up some percentage of the remaining free space
 __populate_fill_fs() {
        dir="$1"
        pct="$2"
        test -z "${pct}" && pct=60
 
-       SRC_SZ="$(du -ks "${SRCDIR}" | cut -f 1)"
+       mkdir -p "${dir}/test/1"
+       cp -pRdu "${dir}"/S_IFREG* "${dir}/test/1/"
+
+       SRC_SZ="$(du -ks "${dir}/test/1" | cut -f 1)"
        FS_SZ="$(( $(stat -f "${dir}" -c '%a * %S') / 1024 ))"
 
        NR="$(( (FS_SZ * ${pct} / 100) / SRC_SZ ))"
-       test "${NR}" -lt 1 && NR=1
 
-       seq 1 "${NR}" | while read nr; do
-               cp -pRdu "${SRCDIR}" "${dir}/test.${nr}" >> $seqres.full 2>&1
+       echo "FILL FS"
+       echo "src_sz $SRC_SZ fs_sz $FS_SZ nr $NR"
+       seq 2 "${NR}" | while read nr; do
+               cp -pRdu "${dir}/test/1" "${dir}/test/${nr}"
        done
 }
 
+# For XFS, force on all the quota options if quota is enabled
+# and the user didn't feed us noquota.
+_populate_xfs_qmount_option()
+{
+       # User explicitly told us not to quota
+       if echo "${MOUNT_OPTIONS}" | grep -q 'noquota'; then
+               return
+       fi
+
+       # Don't bother if we can't turn on quotas
+       if [ ! -f /proc/fs/xfs/xqmstat ]; then
+               # No quota support
+               return
+       elif [ "${USE_EXTERNAL}" = "yes" ] && [ ! -z "${SCRATCH_RTDEV}" ]; then
+               # Quotas not supported on rt filesystems
+               return
+       elif [ -z "${XFS_QUOTA_PROG}" ]; then
+               # xfs quota tools not installed
+               return
+       fi
+
+       # Turn on all the quotas
+       if xfs_info "${TEST_DIR}" | grep -q 'crc=1'; then
+               # v5 filesystems can have group & project quotas
+               quota="usrquota,grpquota,prjquota"
+       else
+               # v4 filesystems cannot mix group & project quotas
+               quota="usrquota,grpquota"
+       fi
+
+       # Inject our quota mount options
+       if echo "${MOUNT_OPTIONS}" | grep -q "${quota}"; then
+               return
+       elif echo "${MOUNT_OPTIONS}" | egrep -q '(quota|noenforce)'; then
+               _qmount_option "${quota}"
+       else
+               export MOUNT_OPTIONS="$MOUNT_OPTIONS -o ${quota}"
+               echo "MOUNT_OPTIONS = $MOUNT_OPTIONS" >>$seqres.full
+       fi
+}
+
 # Populate an XFS on the scratch device with (we hope) all known
 # types of metadata block
 _scratch_xfs_populate() {
+       fill=1
+
+       for arg in $@; do
+               case "${arg}" in
+               "nofill")
+                       fill=0;;
+               esac
+       done
+
+       _populate_xfs_qmount_option
        _scratch_mount
        blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")"
        dblksz="$(xfs_info "${SCRATCH_MNT}" | grep naming.*bsize | sed -e 's/^.*bsize=//g' -e 's/\([0-9]*\).*$/\1/g')"
@@ -153,6 +209,9 @@ _scratch_xfs_populate() {
        mknod "${SCRATCH_MNT}/S_IFCHR" c 1 1
        mknod "${SCRATCH_MNT}/S_IFBLK" c 1 1
 
+       # special file with an xattr
+       setfacl -P -m u:nobody:r ${SCRATCH_MNT}/S_IFCHR
+
        # Attribute formats
        # LOCAL
        echo "+ local attr"
@@ -170,6 +229,18 @@ _scratch_xfs_populate() {
        echo "+ btree attr"
        __populate_create_attr "${SCRATCH_MNT}/ATTR.FMT_BTREE" "$((64 * blksz / 40))" true
 
+       # trusted namespace
+       touch ${SCRATCH_MNT}/ATTR.TRUSTED
+       setfattr -n trusted.moo -v urk ${SCRATCH_MNT}/ATTR.TRUSTED
+
+       # security namespace
+       touch ${SCRATCH_MNT}/ATTR.SECURITY
+       setfattr -n security.foo -v bar ${SCRATCH_MNT}/ATTR.SECURITY
+
+       # system namespace
+       touch ${SCRATCH_MNT}/ATTR.SYSTEM
+       setfacl -m u:root:r ${SCRATCH_MNT}/ATTR.SYSTEM
+
        # FMT_EXTENTS with a remote less-than-a-block value
        echo "+ attr extents with a remote less-than-a-block value"
        touch "${SCRATCH_MNT}/ATTR.FMT_EXTENTS_REMOTE3K"
@@ -225,7 +296,7 @@ _scratch_xfs_populate() {
 
        # Copy some real files (xfs tests, I guess...)
        echo "+ real files"
-       __populate_fill_fs "${SCRATCH_MNT}" 5
+       test $fill -ne 0 && __populate_fill_fs "${SCRATCH_MNT}" 5
 
        umount "${SCRATCH_MNT}"
 }
@@ -233,6 +304,15 @@ _scratch_xfs_populate() {
 # Populate an ext4 on the scratch device with (we hope) all known
 # types of metadata block
 _scratch_ext4_populate() {
+       fill=1
+
+       for arg in $@; do
+               case "${arg}" in
+               "nofill")
+                       fill=0;;
+               esac
+       done
+
        _scratch_mount
        blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")"
        dblksz="${blksz}"
@@ -283,6 +363,9 @@ _scratch_ext4_populate() {
        mknod "${SCRATCH_MNT}/S_IFCHR" c 1 1
        mknod "${SCRATCH_MNT}/S_IFBLK" c 1 1
 
+       # special file with an xattr
+       setfacl -P -m u:nobody:r ${SCRATCH_MNT}/S_IFCHR
+
        # Attribute formats
        # LOCAL
        echo "+ local attr"
@@ -292,6 +375,18 @@ _scratch_ext4_populate() {
        echo "+ block attr"
        __populate_create_attr "${SCRATCH_MNT}/ATTR.FMT_BLOCK" "$((blksz / 40))"
 
+       # trusted namespace
+       touch ${SCRATCH_MNT}/ATTR.TRUSTED
+       setfattr -n trusted.moo -v urk ${SCRATCH_MNT}/ATTR.TRUSTED
+
+       # security namespace
+       touch ${SCRATCH_MNT}/ATTR.SECURITY
+       setfattr -n security.foo -v bar ${SCRATCH_MNT}/ATTR.SECURITY
+
+       # system namespace
+       touch ${SCRATCH_MNT}/ATTR.SYSTEM
+       setfacl -m u:root:r ${SCRATCH_MNT}/ATTR.SYSTEM
+
        # Make an unused inode
        echo "+ empty file"
        touch "${SCRATCH_MNT}/unused"
@@ -300,8 +395,7 @@ _scratch_ext4_populate() {
 
        # Copy some real files (xfs tests, I guess...)
        echo "+ real files"
-       __populate_fill_fs "${SCRATCH_MNT}"
-       cp -pRdu --reflink=always "${SCRATCH_MNT}/S_IFREG.FMT_ETREE" "${SCRATCH_MNT}/S_IREG.FMT_ETREE.REFLINK" 2> /dev/null
+       test $fill -ne 0 && __populate_fill_fs "${SCRATCH_MNT}" 5
 
        umount "${SCRATCH_MNT}"
 }
@@ -575,7 +669,7 @@ _scratch_populate() {
                _scratch_xfs_populate
                _scratch_xfs_populate_check
                ;;
-       "ext4")
+       "ext2"|"ext3"|"ext4")
                _scratch_ext4_populate
                _scratch_ext4_populate_check
                ;;
@@ -585,39 +679,6 @@ _scratch_populate() {
        esac
 }
 
-# Modify various files after a fuzzing operation
-_scratch_fuzz_modify() {
-       nr="$1"
-
-       test -z "${nr}" && nr=50000
-       echo "+++ touch ${nr} files"
-       $XFS_IO_PROG -f -c "pwrite -S 0x63 0 ${BLK_SZ}" "/tmp/afile" > /dev/null
-       date="$(date)"
-       find "${SCRATCH_MNT}/" -type f 2> /dev/null | head -n "${nr}" | while read f; do
-               setfattr -n "user.date" -v "${date}" "$f"
-               cat "/tmp/afile" >> "$f"
-               mv "$f" "$f.longer"
-       done
-       rm -rf "/tmp/afile"
-
-       echo "+++ create files"
-       cp -pRdu "${SRCDIR}" "${SCRATCH_MNT}/test.moo"
-       sync
-
-       echo "+++ remove files"
-       rm -rf "${SCRATCH_MNT}/test.moo"
-       rm -rf "${SCRATCH_MNT}/test.1"
-}
-
-# Try to access files after fuzzing
-_scratch_fuzz_test() {
-       echo "+++ ls -laR" >> $seqres.full
-       ls -laR "${SCRATCH_MNT}/test.1/" >/dev/null 2>&1
-
-       echo "+++ cat files" >> $seqres.full
-       (find "${SCRATCH_MNT}/test.1/" -type f -size -1048576k -print0 | xargs -0 cat) >/dev/null 2>&1
-}
-
 # Fill a file system by repeatedly creating files in the given folder
 # starting with the given file size.  Files are reduced in size when
 # they can no longer fit until no more files can be created.
@@ -685,3 +746,63 @@ _fill_fs()
                file_count=$((file_count + 1))
        done
 }
+
+# Populate a scratch FS from scratch or from a cached image.
+_scratch_populate_cached() {
+       POPULATE_METADUMP="${TEST_DIR}/__populate.${FSTYP}"
+       POPULATE_METADUMP_DESCR="${TEST_DIR}/__populate.${FSTYP}.txt"
+
+       # Don't keep metadata images cached for more 48 hours...
+       rm -rf "$(find "${POPULATE_METADUMP}" -mtime +2 2>/dev/null)"
+
+       # Throw away cached image if it doesn't match our spec.
+       case "${FSTYP}" in
+       "ext4")
+               extra_descr="LOGDEV ${SCRATCH_LOGDEV} USE_EXTERNAL ${USE_EXTERNAL}"
+               # ext4 cannot e2image external logs, so we cannot restore
+               test -n "${SCRATCH_LOGDEV}" && rm -f "${POPULATE_METADUMP}"
+               ;;
+       "xfs")
+               extra_descr="LOGDEV ${SCRATCH_LOGDEV} USE_EXTERNAL ${USE_EXTERNAL} RTDEV ${SCRATCH_RTDEV}"
+               _populate_xfs_qmount_option
+               if echo "${MOUNT_OPTIONS}" | grep -q 'usrquota'; then
+                       extra_descr="${extra_descr} QUOTAS"
+               fi
+               ;;
+       *)
+               extra_descr="";;
+       esac
+       meta_descr="FSTYP ${FSTYP} MKFS_OPTIONS ${MKFS_OPTIONS} SIZE $(blockdev --getsz "${SCRATCH_DEV}") ${extra_descr} ARGS $@"
+       cmp -s "${POPULATE_METADUMP_DESCR}" <(echo "${meta_descr}") || rm -rf "${POPULATE_METADUMP}"
+
+       # Do we have a cached image?
+       if [ -r "${POPULATE_METADUMP}" ]; then
+               case "${FSTYP}" in
+               "xfs")
+                       xfs_mdrestore "${POPULATE_METADUMP}" "${SCRATCH_DEV}" && return
+                       ;;
+               "ext2"|"ext3"|"ext4")
+                       e2image -r "${POPULATE_METADUMP}" "${SCRATCH_DEV}" && return
+                       ;;
+               esac
+       fi
+
+       # Oh well, just create one from scratch
+       _scratch_mkfs
+       echo "${meta_descr}" > "${POPULATE_METADUMP_DESCR}"
+       case "${FSTYP}" in
+       "xfs")
+               _scratch_xfs_populate $@
+               _scratch_xfs_populate_check
+               _scratch_metadump "${POPULATE_METADUMP}" -a -o
+               ;;
+       "ext2"|"ext3"|"ext4")
+               _scratch_ext4_populate $@
+               _scratch_ext4_populate_check
+               e2image -Q "${SCRATCH_DEV}" "${POPULATE_METADUMP}"
+               ;;
+       *)
+               _fail "Don't know how to populate a ${FSTYP} filesystem."
+               ;;
+       esac
+}