xref: /freebsd/tests/sys/fs/unionfs/unionfs_test.sh (revision a678e87f5533521f6dec1a4e85c3decb1c3b6584)
1*a678e87fSDag-Erling Smørgrav#!/bin/sh
2*a678e87fSDag-Erling Smørgrav#-
3*a678e87fSDag-Erling Smørgrav# SPDX-License-Identifier: BSD-2-Clause
4*a678e87fSDag-Erling Smørgrav#
5*a678e87fSDag-Erling Smørgrav# Copyright (c) 2025 Klara, Inc.
6*a678e87fSDag-Erling Smørgrav#
7*a678e87fSDag-Erling Smørgrav# Redistribution and use in source and binary forms, with or without
8*a678e87fSDag-Erling Smørgrav# modification, are permitted provided that the following conditions
9*a678e87fSDag-Erling Smørgrav# are met:
10*a678e87fSDag-Erling Smørgrav# 1. Redistributions of source code must retain the above copyright
11*a678e87fSDag-Erling Smørgrav#    notice, this list of conditions and the following disclaimer.
12*a678e87fSDag-Erling Smørgrav# 2. Redistributions in binary form must reproduce the above copyright
13*a678e87fSDag-Erling Smørgrav#    notice, this list of conditions and the following disclaimer in the
14*a678e87fSDag-Erling Smørgrav#    documentation and/or other materials provided with the distribution.
15*a678e87fSDag-Erling Smørgrav#
16*a678e87fSDag-Erling Smørgrav# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*a678e87fSDag-Erling Smørgrav# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*a678e87fSDag-Erling Smørgrav# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*a678e87fSDag-Erling Smørgrav# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*a678e87fSDag-Erling Smørgrav# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*a678e87fSDag-Erling Smørgrav# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*a678e87fSDag-Erling Smørgrav# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*a678e87fSDag-Erling Smørgrav# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*a678e87fSDag-Erling Smørgrav# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*a678e87fSDag-Erling Smørgrav# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*a678e87fSDag-Erling Smørgrav# SUCH DAMAGE.
27*a678e87fSDag-Erling Smørgrav#
28*a678e87fSDag-Erling Smørgrav
29*a678e87fSDag-Erling Smørgrav# Create and mount a filesystem for use in our tests
30*a678e87fSDag-Erling Smørgravunionfs_mkfs() {
31*a678e87fSDag-Erling Smørgrav	local name=$1
32*a678e87fSDag-Erling Smørgrav	local size=${2:-1}
33*a678e87fSDag-Erling Smørgrav	# Create mountpoint
34*a678e87fSDag-Erling Smørgrav	atf_check mkdir ${name}
35*a678e87fSDag-Erling Smørgrav	# Create filesystem image
36*a678e87fSDag-Erling Smørgrav	atf_check -e ignore dd if=/dev/zero of=${name}.img bs=1m count=${size}
37*a678e87fSDag-Erling Smørgrav	echo ${name} >>imgs
38*a678e87fSDag-Erling Smørgrav	# Create memory disk
39*a678e87fSDag-Erling Smørgrav	atf_check -o save:${name}.md mdconfig ${name}.img
40*a678e87fSDag-Erling Smørgrav	md=$(cat ${name}.md)
41*a678e87fSDag-Erling Smørgrav	echo ${md} >>mds
42*a678e87fSDag-Erling Smørgrav	# Format and mount filesystem
43*a678e87fSDag-Erling Smørgrav	atf_check -o ignore newfs /dev/${md}
44*a678e87fSDag-Erling Smørgrav	atf_check mount /dev/${md} ${name}
45*a678e87fSDag-Erling Smørgrav	echo ${name} >>mounts
46*a678e87fSDag-Erling Smørgrav}
47*a678e87fSDag-Erling Smørgrav
48*a678e87fSDag-Erling Smørgrav# Mount a unionfs
49*a678e87fSDag-Erling Smørgravunionfs_mount() {
50*a678e87fSDag-Erling Smørgrav	local upper=$1
51*a678e87fSDag-Erling Smørgrav	local lower=$2
52*a678e87fSDag-Erling Smørgrav	# Mount upper over lower
53*a678e87fSDag-Erling Smørgrav	atf_check mount -t unionfs ${upper} ${lower}
54*a678e87fSDag-Erling Smørgrav	echo ${lower} >>mounts
55*a678e87fSDag-Erling Smørgrav}
56*a678e87fSDag-Erling Smørgrav
57*a678e87fSDag-Erling Smørgrav# Clean up after a test
58*a678e87fSDag-Erling Smørgravunionfs_cleanup() {
59*a678e87fSDag-Erling Smørgrav	# Unmount filesystems
60*a678e87fSDag-Erling Smørgrav	if [ -f mounts ]; then
61*a678e87fSDag-Erling Smørgrav		tail -r mounts | while read mount; do
62*a678e87fSDag-Erling Smørgrav			umount ${mount} || true
63*a678e87fSDag-Erling Smørgrav		done
64*a678e87fSDag-Erling Smørgrav	fi
65*a678e87fSDag-Erling Smørgrav	# Destroy memory disks
66*a678e87fSDag-Erling Smørgrav	if [ -f mds ]; then
67*a678e87fSDag-Erling Smørgrav		tail -r mds | while read md; do
68*a678e87fSDag-Erling Smørgrav			mdconfig -d -u ${md} || true
69*a678e87fSDag-Erling Smørgrav		done
70*a678e87fSDag-Erling Smørgrav	fi
71*a678e87fSDag-Erling Smørgrav	# Delete filesystem images and mountpoints
72*a678e87fSDag-Erling Smørgrav	if [ -f imgs ]; then
73*a678e87fSDag-Erling Smørgrav		tail -r imgs | while read name; do
74*a678e87fSDag-Erling Smørgrav			rm -f ${name}.img || true
75*a678e87fSDag-Erling Smørgrav			rmdir ${name} || true
76*a678e87fSDag-Erling Smørgrav		done
77*a678e87fSDag-Erling Smørgrav	fi
78*a678e87fSDag-Erling Smørgrav}
79*a678e87fSDag-Erling Smørgrav
80*a678e87fSDag-Erling Smørgravatf_test_case unionfs_basic cleanup
81*a678e87fSDag-Erling Smørgravunionfs_basic_head() {
82*a678e87fSDag-Erling Smørgrav	atf_set "descr" "Basic function test"
83*a678e87fSDag-Erling Smørgrav	atf_set "require.user" "root"
84*a678e87fSDag-Erling Smørgrav	atf_set "require.kmods" "unionfs"
85*a678e87fSDag-Erling Smørgrav}
86*a678e87fSDag-Erling Smørgravunionfs_basic_body() {
87*a678e87fSDag-Erling Smørgrav	# Create upper and lower
88*a678e87fSDag-Erling Smørgrav	unionfs_mkfs upper
89*a678e87fSDag-Erling Smørgrav	unionfs_mkfs lower
90*a678e87fSDag-Erling Smørgrav	# Mount upper over lower
91*a678e87fSDag-Erling Smørgrav	unionfs_mount upper lower
92*a678e87fSDag-Erling Smørgrav	# Create object on unionfs
93*a678e87fSDag-Erling Smørgrav	atf_check touch upper/file
94*a678e87fSDag-Erling Smørgrav	atf_check mkdir upper/dir
95*a678e87fSDag-Erling Smørgrav	atf_check touch lower/dir/file
96*a678e87fSDag-Erling Smørgrav	# Verify that objects were created on upper
97*a678e87fSDag-Erling Smørgrav	atf_check test -f lower/file
98*a678e87fSDag-Erling Smørgrav	atf_check test -d lower/dir
99*a678e87fSDag-Erling Smørgrav	atf_check test -f upper/dir/file
100*a678e87fSDag-Erling Smørgrav}
101*a678e87fSDag-Erling Smørgravunionfs_basic_cleanup() {
102*a678e87fSDag-Erling Smørgrav	unionfs_cleanup
103*a678e87fSDag-Erling Smørgrav}
104*a678e87fSDag-Erling Smørgrav
105*a678e87fSDag-Erling Smørgravatf_test_case unionfs_exec cleanup
106*a678e87fSDag-Erling Smørgravunionfs_exec_head() {
107*a678e87fSDag-Erling Smørgrav	atf_set "descr" "Test executing programs"
108*a678e87fSDag-Erling Smørgrav	atf_set "require.user" "root"
109*a678e87fSDag-Erling Smørgrav	atf_set "require.kmods" "unionfs"
110*a678e87fSDag-Erling Smørgrav}
111*a678e87fSDag-Erling Smørgravunionfs_exec_body() {
112*a678e87fSDag-Erling Smørgrav	# Create upper and copy a binary to it
113*a678e87fSDag-Erling Smørgrav	unionfs_mkfs upper
114*a678e87fSDag-Erling Smørgrav	atf_check cp -p /usr/bin/true upper/upper
115*a678e87fSDag-Erling Smørgrav	# Create lower and copy a binary to it
116*a678e87fSDag-Erling Smørgrav	unionfs_mkfs lower
117*a678e87fSDag-Erling Smørgrav	atf_check cp -p /usr/bin/true lower/lower
118*a678e87fSDag-Erling Smørgrav	# Mount upper over lower
119*a678e87fSDag-Erling Smørgrav	unionfs_mount upper lower
120*a678e87fSDag-Erling Smørgrav	# Execute both binaries
121*a678e87fSDag-Erling Smørgrav	atf_check lower/lower
122*a678e87fSDag-Erling Smørgrav	atf_check lower/upper
123*a678e87fSDag-Erling Smørgrav}
124*a678e87fSDag-Erling Smørgravunionfs_exec_cleanup() {
125*a678e87fSDag-Erling Smørgrav	unionfs_cleanup
126*a678e87fSDag-Erling Smørgrav}
127*a678e87fSDag-Erling Smørgrav
128*a678e87fSDag-Erling Smørgravatf_test_case unionfs_rename cleanup
129*a678e87fSDag-Erling Smørgravunionfs_rename_head() {
130*a678e87fSDag-Erling Smørgrav	atf_set "descr" "Test renaming objects on lower"
131*a678e87fSDag-Erling Smørgrav	atf_set "require.user" "root"
132*a678e87fSDag-Erling Smørgrav	atf_set "require.kmods" "unionfs"
133*a678e87fSDag-Erling Smørgrav}
134*a678e87fSDag-Erling Smørgravunionfs_rename_body() {
135*a678e87fSDag-Erling Smørgrav	# Create upper and lower
136*a678e87fSDag-Erling Smørgrav	unionfs_mkfs upper
137*a678e87fSDag-Erling Smørgrav	unionfs_mkfs lower
138*a678e87fSDag-Erling Smørgrav	# Create objects on lower
139*a678e87fSDag-Erling Smørgrav	atf_check touch lower/file
140*a678e87fSDag-Erling Smørgrav	atf_check mkdir lower/dir
141*a678e87fSDag-Erling Smørgrav	atf_check ln -s dead lower/link
142*a678e87fSDag-Erling Smørgrav	# Mount upper over lower
143*a678e87fSDag-Erling Smørgrav	unionfs_mount upper lower
144*a678e87fSDag-Erling Smørgrav	# Rename objects
145*a678e87fSDag-Erling Smørgrav	atf_check mv lower/file lower/newfile
146*a678e87fSDag-Erling Smørgrav	atf_check mv lower/dir lower/newdir
147*a678e87fSDag-Erling Smørgrav	atf_check mv lower/link lower/newlink
148*a678e87fSDag-Erling Smørgrav	# Verify that old names no longer exist
149*a678e87fSDag-Erling Smørgrav	atf_check test ! -f lower/file
150*a678e87fSDag-Erling Smørgrav	atf_check test ! -d lower/dir
151*a678e87fSDag-Erling Smørgrav	atf_check test ! -L lower/link
152*a678e87fSDag-Erling Smørgrav	# Verify that new names exist on upper
153*a678e87fSDag-Erling Smørgrav	atf_check test -f upper/newfile
154*a678e87fSDag-Erling Smørgrav	atf_check test -d upper/newdir
155*a678e87fSDag-Erling Smørgrav	atf_check test -L upper/newlink
156*a678e87fSDag-Erling Smørgrav}
157*a678e87fSDag-Erling Smørgravunionfs_rename_cleanup() {
158*a678e87fSDag-Erling Smørgrav	unionfs_cleanup
159*a678e87fSDag-Erling Smørgrav}
160*a678e87fSDag-Erling Smørgrav
161*a678e87fSDag-Erling Smørgravatf_init_test_cases() {
162*a678e87fSDag-Erling Smørgrav	atf_add_test_case unionfs_basic
163*a678e87fSDag-Erling Smørgrav	atf_add_test_case unionfs_exec
164*a678e87fSDag-Erling Smørgrav	atf_add_test_case unionfs_rename
165*a678e87fSDag-Erling Smørgrav}
166