1#!/bin/ksh -p
2#
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
9# source.  A copy of the CDDL is also available via the Internet at
10# http://www.illumos.org/license/CDDL.
11#
12
13#
14# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
15#
16
17. $STF_SUITE/include/libtest.shlib
18
19#
20# DESCRIPTION:
21# 'zfs diff -t' should display inode change time correctly.
22#
23# STRATEGY:
24# 1. Create a snapshot
25# 2. Create some files with a random delay and snapshot the filesystem again
26# 3. Verify 'zfs diff -t' correctly display timestamps
27#
28
29verify_runnable "both"
30
31function cleanup
32{
33	for snap in $TESTSNAP1 $TESTSNAP2; do
34		snapexists "$snap" && destroy_dataset "$snap"
35	done
36	find "$MNTPOINT" -type f -delete
37	rm -f "$FILEDIFF"
38}
39
40#
41# Creates $count files in $fspath. Waits a random delay between each file.
42#
43function create_random # <fspath> <count>
44{
45	fspath="$1"
46	typeset -i count="$2"
47	typeset -i i=0
48
49	while (( i < count )); do
50		log_must touch "$fspath/file$i"
51		sleep $(random_int_between 1 3)
52		(( i = i + 1 ))
53	done
54}
55
56log_assert "'zfs diff -t' should display inode change time correctly."
57log_onexit cleanup
58
59DATASET="$TESTPOOL/$TESTFS"
60TESTSNAP1="$DATASET@snap1"
61TESTSNAP2="$DATASET@snap2"
62MNTPOINT="$(get_prop mountpoint $DATASET)"
63FILEDIFF="$TESTDIR/zfs-diff.txt"
64FILENUM=5
65
66# 1. Create a snapshot
67log_must zfs snapshot "$TESTSNAP1"
68
69# 2. Create some files with a random delay and snapshot the filesystem again
70create_random "$MNTPOINT" $FILENUM
71log_must zfs snapshot "$TESTSNAP2"
72
73# 3. Verify 'zfs diff -t' correctly display timestamps
74typeset -i count=0
75log_must eval "zfs diff -t $TESTSNAP1 $TESTSNAP2 > $FILEDIFF"
76awk '{print substr($1,1,index($1,".")-1)" "$NF}' < "$FILEDIFF" | while read line
77do
78	read ctime file <<< "$line"
79
80	# If path from 'zfs diff' is not a file (could be xattr object) skip it
81	if [[ ! -f "$file" ]]; then
82		continue;
83	fi
84
85	filetime=$(stat_ctime $file)
86	if [[ "$filetime" != "$ctime" ]]; then
87		log_fail "Unexpected ctime for file $file ($filetime != $ctime)"
88	else
89		log_note "Correct ctime read on $file: $ctime"
90	fi
91
92	(( i = i + 1 ))
93done
94if [[ $i != $FILENUM ]]; then
95	log_fail "Wrong number of files verified ($i != $FILENUM)"
96fi
97
98log_pass "'zfs diff -t' displays inode change time correctly."
99