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 -F' shows different object types correctly.
22#
23# STRATEGY:
24# 1. Prepare a dataset
25# 2. Create different objects and verify 'zfs diff -F' shows the correct type
26#
27
28verify_runnable "both"
29
30function cleanup
31{
32	log_must zfs destroy -r "$DATASET"
33	rm -f "$FILEDIFF"
34}
35
36#
37# Verify object at $path is of type $symbol using 'zfs diff -F'
38# Valid types are:
39# * B (Block device)
40# * C (Character device)
41# * / (Directory)
42# * > (Door)
43# * | (Named pipe)
44# * @ (Symbolic link)
45# * P (Event port)
46# * = (Socket)
47# * F (Regular file)
48#
49function verify_object_class # <path> <symbol>
50{
51	path="$1"
52	symbol="$2"
53
54	log_must eval "zfs diff -F $TESTSNAP1 $TESTSNAP2 > $FILEDIFF"
55	diffsym="$(awk -v path="$path" '$NF == path { print $2 }' $FILEDIFF)"
56	if [[ "$diffsym" != "$symbol" ]]; then
57		log_fail "Unexpected type for $path ('$diffsym' != '$symbol')"
58	else
59		log_note "Object $path type is correctly displayed as '$symbol'"
60	fi
61
62	log_must zfs destroy "$TESTSNAP1"
63	log_must zfs destroy "$TESTSNAP2"
64}
65
66log_assert "'zfs diff -F' should show different object types correctly."
67log_onexit cleanup
68
69DATASET="$TESTPOOL/$TESTFS/fs"
70TESTSNAP1="$DATASET@snap1"
71TESTSNAP2="$DATASET@snap2"
72FILEDIFF="$TESTDIR/zfs-diff.txt"
73if is_freebsd; then
74	MAJOR=$(stat -f %Hr /dev/null)
75	MINOR=$(stat -f %Lr /dev/null)
76else
77	MAJOR=$(stat -c %t /dev/null)
78	MINOR=$(stat -c %T /dev/null)
79fi
80
81# 1. Prepare a dataset
82log_must zfs create $DATASET
83MNTPOINT="$(get_prop mountpoint $DATASET)"
84log_must zfs set devices=on $DATASET
85log_must zfs set xattr=sa $DATASET
86
87# 2. Create different objects and verify 'zfs diff -F' shows the correct type
88# 2. F (Regular file)
89log_must zfs snapshot "$TESTSNAP1"
90log_must touch "$MNTPOINT/file"
91log_must zfs snapshot "$TESTSNAP2"
92verify_object_class "$MNTPOINT/file" "F"
93
94# 2. @ (Symbolic link)
95log_must zfs snapshot "$TESTSNAP1"
96log_must ln -s "$MNTPOINT/file" "$MNTPOINT/link"
97log_must zfs snapshot "$TESTSNAP2"
98verify_object_class "$MNTPOINT/link" "@"
99
100# 2. B (Block device)
101log_must zfs snapshot "$TESTSNAP1"
102log_must mknod "$MNTPOINT/bdev" b $MAJOR $MINOR
103log_must zfs snapshot "$TESTSNAP2"
104verify_object_class "$MNTPOINT/bdev" "B"
105
106# 2. C (Character device)
107log_must zfs snapshot "$TESTSNAP1"
108log_must mknod "$MNTPOINT/cdev" c $MAJOR $MINOR
109log_must zfs snapshot "$TESTSNAP2"
110verify_object_class "$MNTPOINT/cdev" "C"
111
112# 2. | (Named pipe)
113log_must zfs snapshot "$TESTSNAP1"
114log_must mkfifo "$MNTPOINT/fifo"
115log_must zfs snapshot "$TESTSNAP2"
116verify_object_class "$MNTPOINT/fifo" "|"
117
118# 2. / (Directory)
119log_must zfs snapshot "$TESTSNAP1"
120log_must mkdir "$MNTPOINT/dir"
121log_must zfs snapshot "$TESTSNAP2"
122verify_object_class "$MNTPOINT/dir" "/"
123
124# 2. = (Socket)
125log_must zfs snapshot "$TESTSNAP1"
126log_must zfs_diff-socket "$MNTPOINT/sock"
127log_must zfs snapshot "$TESTSNAP2"
128verify_object_class "$MNTPOINT/sock" "="
129
130log_pass "'zfs diff -F' shows different object types correctly."
131