1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2020 Intel Corporation 4# All rights reserved. 5# 6testdir=$(readlink -f "$(dirname "$0")") 7rootdir=$(readlink -f "$testdir/../../") 8source "$testdir/common.sh" 9 10cleanup() { 11 rm -f "$test_file0"{,.link} 12 rm -f "$test_file1"{,.link} 13} 14 15append() { 16 local dump0 17 local dump1 18 19 dump0=$(gen_bytes 32) 20 dump1=$(gen_bytes 32) 21 22 printf '%s' "$dump0" > "$test_file0" 23 printf '%s' "$dump1" > "$test_file1" 24 25 "${DD_APP[@]}" --if="$test_file0" --of="$test_file1" --oflag=append 26 27 [[ $(< "$test_file1") == "${dump1}${dump0}" ]] 28} 29 30directory() { 31 NOT "${DD_APP[@]}" --if="$test_file0" --iflag=directory --of="$test_file0" 32 NOT "${DD_APP[@]}" --if="$test_file0" --of="$test_file0" --oflag=directory 33} 34 35nofollow() { 36 local test_file0_link=$test_file0.link 37 local test_file1_link=$test_file1.link 38 39 ln -fs "$test_file0" "$test_file0_link" 40 ln -fs "$test_file1" "$test_file1_link" 41 42 NOT "${DD_APP[@]}" --if="$test_file0_link" --iflag=nofollow --of="$test_file1" 43 NOT "${DD_APP[@]}" --if="$test_file0" --of="$test_file1_link" --oflag=nofollow 44 45 # Do an extra step of checking if we actually can follow symlinks 46 gen_bytes 512 > "$test_file0" 47 48 "${DD_APP[@]}" --if="$test_file0_link" --of="$test_file1" 49 [[ $(< "$test_file0") == "$(< "$test_file1")" ]] 50} 51 52noatime() { 53 local atime_if 54 local atime_of 55 56 # It seems like spdk_dd doesn't update the atime in case 0 bytes are copied. 57 # This differs from how standard dd works for instance 58 gen_bytes 512 > "$test_file0" 59 60 atime_if=$(stat --printf="%X" "$test_file0") 61 atime_of=$(stat --printf="%X" "$test_file1") 62 63 # Make sure atime has a chance to be updated - if all tests finish within 64 # 1s (see %X) we may get a false negative at the last check. See: 65 # https://github.com/spdk/spdk/issues/2720 66 sleep 1 67 68 "${DD_APP[@]}" --if="$test_file0" --iflag=noatime --of="$test_file1" 69 ((atime_if == $(stat --printf="%X" "$test_file0"))) 70 ((atime_of == $(stat --printf="%X" "$test_file1"))) 71 72 "${DD_APP[@]}" --if="$test_file0" --of="$test_file1" 73 ((atime_if < $(stat --printf="%X" "$test_file0"))) 74} 75 76io() { 77 local flags_ro flags_rw flag_ro flag_rw 78 79 # O_NONBLOCK is actually a no-op, from a functional perspective, while 80 # open()ing a regular file, but let's keep it just to test its usage. 81 flags_ro=(direct nonblock) 82 flags_rw=("${flags_ro[@]}" sync dsync) 83 84 # simply check if data was correctly copied between files 85 for flag_ro in "${flags_ro[@]}"; do 86 gen_bytes 512 > "$test_file0" 87 for flag_rw in "${flags_rw[@]}"; do 88 "${DD_APP[@]}" \ 89 --if="$test_file0" \ 90 --iflag="$flag_ro" \ 91 --of="$test_file1" \ 92 --oflag="$flag_rw" 93 [[ $(< "$test_file0") == "$(< "$test_file1")" ]] 94 done 95 done 96} 97 98tests() { 99 printf '* First test run%s\n' \ 100 "${msg[liburing_in_use]}" >&2 101 102 run_test "dd_flag_append" append 103 run_test "dd_flag_directory" directory 104 run_test "dd_flag_nofollow" nofollow 105 run_test "dd_flag_noatime" noatime 106 run_test "dd_flags_misc" io 107} 108 109tests_forced_aio() { 110 printf '* Second test run%s\n' \ 111 "${msg[liburing_in_use ? 2 : 0]}" >&2 112 113 DD_APP+=("--aio") 114 run_test "dd_flag_append_forced_aio" append 115 run_test "dd_flag_directory_forced_aio" directory 116 run_test "dd_flag_nofollow_forced_aio" nofollow 117 run_test "dd_flag_noatime_forced_aio" noatime 118 run_test "dd_flags_misc_forced_aio" io 119} 120 121msg[0]=", using AIO" 122msg[1]=", liburing in use" 123msg[2]=", disabling liburing, forcing AIO" 124 125trap "cleanup" EXIT 126 127test_file0=$SPDK_TEST_STORAGE/dd.dump0 128test_file1=$SPDK_TEST_STORAGE/dd.dump1 129 130tests 131tests_forced_aio 132