1#!/bin/ksh -p 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# 24# Copyright 2007 Sun Microsystems, Inc. All rights reserved. 25# Copyright (c) 2017 by Lawrence Livermore National Security, LLC. 26# Use is subject to license terms. 27# 28 29. $STF_SUITE/tests/functional/slog/slog.kshlib 30 31# 32# DESCRIPTION: 33# Verify slogs are replayed correctly for a volume. 34# 35# The general idea is to build up an intent log from a bunch of 36# diverse user commands without actually committing them to the 37# file system. Then generate checksums for files and volume, 38# replay the intent log and verify the checksums. 39# 40# To enable this automated testing of the intent log some minimal 41# support is required of the file system. In particular, a 42# "freeze" command is required to flush the in-flight transactions; 43# to stop the actual committing of transactions; and to ensure no 44# deltas are discarded. All deltas past a freeze point are kept 45# for replay and comparison later. Here is the flow: 46# 47# STRATEGY: 48# 1. Create an empty volume (TESTVOL), set sync=always, and format 49# it with an ext4 filesystem and mount it. 50# 2. Freeze TESTVOL. 51# 3. Create log records of various types to verify replay. 52# 4. Generate checksums for all ext4 files. 53# 5. Unmount filesystem and export the pool 54# <at this stage TESTVOL is empty again and unfrozen, and the 55# intent log contains a complete set of deltas to replay it> 56# 6. Import TESTVOL <which replays the intent log> and mount it. 57# 7. Verify the stored checksums 58# 59 60verify_runnable "global" 61 62VOLUME=$ZVOL_DEVDIR/$TESTPOOL/$TESTVOL 63MNTPNT=$TESTDIR/$TESTVOL 64FSTYPE=none 65 66function cleanup_volume 67{ 68 if ismounted $MNTPNT $FSTYPE; then 69 log_must umount $MNTPNT 70 rmdir $MNTPNT 71 fi 72 73 rm -f $TESTDIR/checksum.files 74 75 cleanup 76} 77 78log_assert "Replay of intent log succeeds." 79log_onexit cleanup_volume 80log_must setup 81 82# 83# 1. Create an empty volume (TESTVOL), set sync=always, and format 84# it with an ext4 filesystem and mount it. 85# 86log_must zpool create $TESTPOOL ${DISKS%% *} 87log_must zfs create -V 128M $TESTPOOL/$TESTVOL 88log_must zfs set compression=on $TESTPOOL/$TESTVOL 89log_must zfs set sync=always $TESTPOOL/$TESTVOL 90log_must mkdir -p $TESTDIR 91block_device_wait 92if is_linux; then 93 # ext4 only on Linux 94 log_must new_fs -t ext4 -v $VOLUME 95 log_must mkdir -p $MNTPNT 96 log_must mount -o discard $VOLUME $MNTPNT 97 FSTYPE=ext4 98 log_must rmdir $MNTPNT/lost+found 99else 100 log_must new_fs $VOLUME 101 log_must mkdir -p $MNTPNT 102 log_must mount $VOLUME $MNTPNT 103 FSTYPE=$NEWFS_DEFAULT_FS 104fi 105log_must zpool sync 106 107# 108# 2. Freeze TESTVOL 109# 110log_must zpool freeze $TESTPOOL 111 112# 113# 3. Create log records of various types to verify replay. 114# 115 116# TX_WRITE 117log_must dd if=/dev/urandom of=$MNTPNT/latency-8k bs=8k count=1 oflag=sync 118log_must dd if=/dev/urandom of=$MNTPNT/latency-128k bs=128k count=1 oflag=sync 119 120# TX_WRITE (WR_INDIRECT) 121log_must zfs set logbias=throughput $TESTPOOL/$TESTVOL 122log_must dd if=/dev/urandom of=$MNTPNT/throughput-8k bs=8k count=1 123log_must dd if=/dev/urandom of=$MNTPNT/throughput-128k bs=128k count=1 124 125# TX_WRITE (holes) 126log_must dd if=/dev/urandom of=$MNTPNT/holes bs=128k count=8 127log_must dd if=/dev/zero of=$MNTPNT/holes bs=128k count=2 seek=2 conv=notrunc 128 129if is_linux; then 130 # TX_TRUNCATE 131 if fallocate --punch-hole 2>&1 | grep -q "unrecognized option"; then 132 log_note "fallocate(1) does not support --punch-hole" 133 else 134 log_must dd if=/dev/urandom of=$MNTPNT/discard bs=128k count=16 135 log_must fallocate --punch-hole -l 128K -o 512K $MNTPNT/discard 136 log_must fallocate --punch-hole -l 512K -o 1M $MNTPNT/discard 137 fi 138fi 139 140# 141# 4. Generate checksums for all ext4 files. 142# 143typeset checksum=$(cat $MNTPNT/* | sha256digest) 144 145# 146# 5. Unmount filesystem and export the pool 147# 148# At this stage TESTVOL is initialized with the random data and frozen, 149# the intent log contains a complete set of deltas to replay. 150# 151log_must umount $MNTPNT 152 153log_note "Verify transactions to replay:" 154log_must zdb -iv $TESTPOOL/$TESTVOL 155 156log_must zpool export $TESTPOOL 157 158# 159# 6. Import TESTPOOL, the intent log is replayed during minor creation. 160# 161# Import the pool to unfreeze it and claim log blocks. It has to be 162# `zpool import -f` because we can't write a frozen pool's labels! 163# 164log_must zpool import -f $TESTPOOL 165block_device_wait 166log_must mount $VOLUME $MNTPNT 167 168# 169# 7. Verify the stored checksums 170# 171log_note "Verify current block usage:" 172log_must zdb -bcv $TESTPOOL 173 174log_note "Verify checksums" 175typeset checksum1=$(cat $MNTPNT/* | sha256digest) 176[[ "$checksum1" == "$checksum" ]] || \ 177 log_fail "checksum mismatch ($checksum1 != $checksum)" 178 179log_pass "Replay of intent log succeeds." 180