155141f2cSYan-Hao Wang# SPDX-License-Identifier: BSD-2-Clause 255141f2cSYan-Hao Wang# 355141f2cSYan-Hao Wang# Copyright (c) 2023 The FreeBSD Foundation 455141f2cSYan-Hao Wang# 555141f2cSYan-Hao Wang# This software was developed1 by Yan-Hao Wang <bses30074@gmail.com> 655141f2cSYan-Hao Wang# under sponsorship from the FreeBSD Foundation. 755141f2cSYan-Hao Wang# 855141f2cSYan-Hao Wang# Redistribution and use in source and binary forms, with or without 955141f2cSYan-Hao Wang# modification, are permitted provided that the following conditions 1055141f2cSYan-Hao Wang# are met: 1155141f2cSYan-Hao Wang# 1. Redistributions of source code must retain the above copyright 1255141f2cSYan-Hao Wang# notice, this list of conditions and the following disclaimer. 1355141f2cSYan-Hao Wang# 2. Redistributions in binary form must reproduce the above copyright 1455141f2cSYan-Hao Wang# notice, this list of conditions and the following disclaimer in the 1555141f2cSYan-Hao Wang# documentation and/or other materials provided with the distribution. 1655141f2cSYan-Hao Wang# 1755141f2cSYan-Hao Wang# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1855141f2cSYan-Hao Wang# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1955141f2cSYan-Hao Wang# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2055141f2cSYan-Hao Wang# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2155141f2cSYan-Hao Wang# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2255141f2cSYan-Hao Wang# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2355141f2cSYan-Hao Wang# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2455141f2cSYan-Hao Wang# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2555141f2cSYan-Hao Wang# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2655141f2cSYan-Hao Wang# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2755141f2cSYan-Hao Wang# SUCH DAMAGE. 2855141f2cSYan-Hao Wang# 2955141f2cSYan-Hao Wang 3055141f2cSYan-Hao Wang. $(atf_get_srcdir)/conf.sh 3155141f2cSYan-Hao Wang 3255141f2cSYan-Hao Wangatf_test_case create cleanup 3355141f2cSYan-Hao Wangcreate_head() 3455141f2cSYan-Hao Wang{ 3555141f2cSYan-Hao Wang atf_set "descr" "Test gunion create and destroy" 3655141f2cSYan-Hao Wang atf_set "require.user" "root" 3755141f2cSYan-Hao Wang} 3855141f2cSYan-Hao Wangcreate_body() 3955141f2cSYan-Hao Wang{ 4055141f2cSYan-Hao Wang gunion_test_setup 4155141f2cSYan-Hao Wang 42*96950419SGleb Smirnoff attach_md upperdev -s 1m 43*96950419SGleb Smirnoff attach_md lowerdev -s 1m 4455141f2cSYan-Hao Wang newfs -U "/dev/${lowerdev}" 4555141f2cSYan-Hao Wang 4655141f2cSYan-Hao Wang atf_check gunion create "$upperdev" "$lowerdev" 4755141f2cSYan-Hao Wang guniondev="${upperdev}-${lowerdev}.union" 4855141f2cSYan-Hao Wang atf_check -o inline:"/dev/${guniondev}\n" ls "/dev/${guniondev}" 4955141f2cSYan-Hao Wang atf_check -o ignore fsck -p -f "/dev/${guniondev}" 5055141f2cSYan-Hao Wang 5155141f2cSYan-Hao Wang atf_check gunion destroy "$guniondev" 5255141f2cSYan-Hao Wang atf_check -s not-exit:0 -o ignore -e ignore ls "/dev/${guniondev}" 5355141f2cSYan-Hao Wang} 5455141f2cSYan-Hao Wangcreate_cleanup() 5555141f2cSYan-Hao Wang{ 5655141f2cSYan-Hao Wang gunion_test_cleanup 5755141f2cSYan-Hao Wang} 5855141f2cSYan-Hao Wang 5955141f2cSYan-Hao Wangatf_test_case basic cleanup 6055141f2cSYan-Hao Wangbasic_head() 6155141f2cSYan-Hao Wang{ 6255141f2cSYan-Hao Wang atf_set "descr" "Check gunion doesn't affect lowerdev status and lowerdev can't be mounted when being in a gunion" 6355141f2cSYan-Hao Wang atf_set "require.user" "root" 6455141f2cSYan-Hao Wang} 6555141f2cSYan-Hao Wangbasic_body() 6655141f2cSYan-Hao Wang{ 6755141f2cSYan-Hao Wang gunion_test_setup 6855141f2cSYan-Hao Wang 69*96950419SGleb Smirnoff attach_md upperdev -s 1m 70*96950419SGleb Smirnoff attach_md lowerdev -s 1m 7155141f2cSYan-Hao Wang newfs -U "/dev/${lowerdev}" 7255141f2cSYan-Hao Wang mkdir lowermnt 7355141f2cSYan-Hao Wang mkdir gunionmnt 7455141f2cSYan-Hao Wang 7555141f2cSYan-Hao Wang mount "/dev/${lowerdev}" lowermnt 7655141f2cSYan-Hao Wang echo "lower file" > lower_file 7755141f2cSYan-Hao Wang cp lower_file lowermnt/lower_file 7855141f2cSYan-Hao Wang sync 7955141f2cSYan-Hao Wang umount lowermnt 8055141f2cSYan-Hao Wang 8155141f2cSYan-Hao Wang gunion create "$upperdev" "$lowerdev" 8255141f2cSYan-Hao Wang guniondev="${upperdev}-${lowerdev}.union" 8355141f2cSYan-Hao Wang atf_check -s not-exit:0 -o ignore -e ignore mount "/dev/${lowerdev}" lowermnt 8455141f2cSYan-Hao Wang 8555141f2cSYan-Hao Wang mount "/dev/${guniondev}" gunionmnt 8655141f2cSYan-Hao Wang echo "update lower file" >> gunionmnt/lower_file 8755141f2cSYan-Hao Wang echo "gunion file" > gunion_file 8855141f2cSYan-Hao Wang cp gunion_file gunionmnt/gunion_file 8955141f2cSYan-Hao Wang sync 9055141f2cSYan-Hao Wang umount gunionmnt 9155141f2cSYan-Hao Wang 9255141f2cSYan-Hao Wang gunion destroy "$guniondev" 9355141f2cSYan-Hao Wang mount "/dev/${lowerdev}" lowermnt 9455141f2cSYan-Hao Wang checksum lowermnt/lower_file lower_file 9555141f2cSYan-Hao Wang atf_check -s not-exit:0 -o ignore -e ignore ls lowermnt/gunion_file 9655141f2cSYan-Hao Wang} 9755141f2cSYan-Hao Wangbasic_cleanup() 9855141f2cSYan-Hao Wang{ 9955141f2cSYan-Hao Wang gunion_test_cleanup 10055141f2cSYan-Hao Wang} 10155141f2cSYan-Hao Wang 10255141f2cSYan-Hao Wangatf_test_case commit cleanup 10355141f2cSYan-Hao Wangcommit_head() 10455141f2cSYan-Hao Wang{ 10555141f2cSYan-Hao Wang atf_set "descr" "Test basic gunion commit without option" 10655141f2cSYan-Hao Wang atf_set "require.user" "root" 10755141f2cSYan-Hao Wang} 10855141f2cSYan-Hao Wangcommit_body() 10955141f2cSYan-Hao Wang{ 11055141f2cSYan-Hao Wang gunion_test_setup 11155141f2cSYan-Hao Wang 112*96950419SGleb Smirnoff attach_md upperdev -s 1m 113*96950419SGleb Smirnoff attach_md lowerdev -s 1m 11455141f2cSYan-Hao Wang newfs -U "/dev/${lowerdev}" 11555141f2cSYan-Hao Wang mkdir lowermnt 11655141f2cSYan-Hao Wang mkdir gunionmnt 11755141f2cSYan-Hao Wang 11855141f2cSYan-Hao Wang mount "/dev/${lowerdev}" lowermnt 11955141f2cSYan-Hao Wang echo "lower file" > lower_file 12055141f2cSYan-Hao Wang cp lower_file lowermnt/lower_file 12155141f2cSYan-Hao Wang sync 12255141f2cSYan-Hao Wang umount lowermnt 12355141f2cSYan-Hao Wang 12455141f2cSYan-Hao Wang gunion create "$upperdev" "$lowerdev" 12555141f2cSYan-Hao Wang guniondev="${upperdev}-${lowerdev}.union" 12655141f2cSYan-Hao Wang mount "/dev/${guniondev}" gunionmnt 12755141f2cSYan-Hao Wang checksum gunionmnt/lower_file lower_file 12855141f2cSYan-Hao Wang 12955141f2cSYan-Hao Wang echo "update lower file" >> lower_file 13055141f2cSYan-Hao Wang cp -f lower_file gunionmnt/lower_file 13155141f2cSYan-Hao Wang echo "gunion file" > gunion_file 13255141f2cSYan-Hao Wang cp gunion_file gunionmnt/gunion_file 13355141f2cSYan-Hao Wang sync 13455141f2cSYan-Hao Wang umount gunionmnt 13555141f2cSYan-Hao Wang atf_check gunion commit "$guniondev" 13655141f2cSYan-Hao Wang gunion destroy "$guniondev" 13755141f2cSYan-Hao Wang 13855141f2cSYan-Hao Wang atf_check -o ignore fsck -p -f "/dev/${lowerdev}" 13955141f2cSYan-Hao Wang mount "/dev/${lowerdev}" lowermnt 14055141f2cSYan-Hao Wang checksum lowermnt/lower_file lower_file 14155141f2cSYan-Hao Wang checksum lowermnt/gunion_file gunion_file 14255141f2cSYan-Hao Wang} 14355141f2cSYan-Hao Wangcommit_cleanup() 14455141f2cSYan-Hao Wang{ 14555141f2cSYan-Hao Wang gunion_test_cleanup 14655141f2cSYan-Hao Wang} 14755141f2cSYan-Hao Wang 14855141f2cSYan-Hao Wangatf_test_case offset cleanup 14955141f2cSYan-Hao Wangoffset_head() 15055141f2cSYan-Hao Wang{ 15155141f2cSYan-Hao Wang atf_set "descr" "Test gunion create with -o offset option" 15255141f2cSYan-Hao Wang atf_set "require.user" "root" 15355141f2cSYan-Hao Wang} 15455141f2cSYan-Hao Wangoffset_body() 15555141f2cSYan-Hao Wang{ 15655141f2cSYan-Hao Wang gunion_test_setup 15755141f2cSYan-Hao Wang 158*96950419SGleb Smirnoff attach_md upperdev -s 1m 159*96950419SGleb Smirnoff attach_md lowerdev -s 1m 16055141f2cSYan-Hao Wang gpart create -s GPT "/dev/${lowerdev}" 16155141f2cSYan-Hao Wang gpart add -t freebsd-ufs "$lowerdev" 16255141f2cSYan-Hao Wang newfs "/dev/${lowerdev}p1" 16355141f2cSYan-Hao Wang gpt_entry_1=$(gpart show "/dev/${lowerdev}") 16455141f2cSYan-Hao Wang mkdir gunionmnt 16555141f2cSYan-Hao Wang 16655141f2cSYan-Hao Wang secsize="$(diskinfo "/dev/${lowerdev}" | awk '{print $2}')" 16755141f2cSYan-Hao Wang p1_start_sector="$(gpart show -p "/dev/${lowerdev}" | grep ${lowerdev}p1 | awk '{print $1}')" 16855141f2cSYan-Hao Wang offset_size="$((secsize * p1_start_sector))" 16955141f2cSYan-Hao Wang 17055141f2cSYan-Hao Wang gunion create -o "$offset_size" "$upperdev" "$lowerdev" 17155141f2cSYan-Hao Wang guniondev="${upperdev}-${lowerdev}.union" 17255141f2cSYan-Hao Wang 17355141f2cSYan-Hao Wang atf_check -o ignore fsck -p -f "/dev/${guniondev}" 17455141f2cSYan-Hao Wang atf_check mount "/dev/${guniondev}" gunionmnt 17555141f2cSYan-Hao Wang umount gunionmnt 17655141f2cSYan-Hao Wang gunion destroy "$guniondev" 17755141f2cSYan-Hao Wang 17855141f2cSYan-Hao Wang gpt_entry_2=$(gpart show "/dev/${lowerdev}") 17955141f2cSYan-Hao Wang atf_check_equal "$gpt_entry_1" "$gpt_entry_2" 18055141f2cSYan-Hao Wang} 18155141f2cSYan-Hao Wangoffset_cleanup() 18255141f2cSYan-Hao Wang{ 18355141f2cSYan-Hao Wang gunion_test_cleanup 18455141f2cSYan-Hao Wang} 18555141f2cSYan-Hao Wang 18655141f2cSYan-Hao Wangatf_test_case size cleanup 18755141f2cSYan-Hao Wangsize_head() 18855141f2cSYan-Hao Wang{ 18955141f2cSYan-Hao Wang atf_set "descr" "Test gunion create with -s size option" 19055141f2cSYan-Hao Wang atf_set "require.user" "root" 19155141f2cSYan-Hao Wang} 19255141f2cSYan-Hao Wangsize_body() 19355141f2cSYan-Hao Wang{ 19455141f2cSYan-Hao Wang gunion_test_setup 19555141f2cSYan-Hao Wang 196*96950419SGleb Smirnoff attach_md upperdev -s 2m 197*96950419SGleb Smirnoff attach_md lowerdev -s 1m 19855141f2cSYan-Hao Wang newfs -U "/dev/${lowerdev}" 19955141f2cSYan-Hao Wang 20055141f2cSYan-Hao Wang gunion create -s 2m "$upperdev" "$lowerdev" 20155141f2cSYan-Hao Wang guniondev="${upperdev}-${lowerdev}.union" 20255141f2cSYan-Hao Wang echo "$guniondev" > guniondev 20355141f2cSYan-Hao Wang 20455141f2cSYan-Hao Wang size="$(diskinfo "/dev/$guniondev" | awk '{print $3}')" 20555141f2cSYan-Hao Wang atf_check_equal "2097152" "$size" # 2 MB = 2097152 bytes 20655141f2cSYan-Hao Wang} 20755141f2cSYan-Hao Wangsize_cleanup() 20855141f2cSYan-Hao Wang{ 20955141f2cSYan-Hao Wang gunion_test_cleanup 21055141f2cSYan-Hao Wang} 21155141f2cSYan-Hao Wang 21255141f2cSYan-Hao Wangatf_test_case secsize cleanup 21355141f2cSYan-Hao Wangsecsize_head() 21455141f2cSYan-Hao Wang{ 21555141f2cSYan-Hao Wang atf_set "descr" "Test gunion create with -S secsize option" 21655141f2cSYan-Hao Wang atf_set "require.user" "root" 21755141f2cSYan-Hao Wang} 21855141f2cSYan-Hao Wangsecsize_body() 21955141f2cSYan-Hao Wang{ 22055141f2cSYan-Hao Wang gunion_test_setup 22155141f2cSYan-Hao Wang 222*96950419SGleb Smirnoff attach_md upperdev -s 1m 223*96950419SGleb Smirnoff attach_md lowerdev -s 1m 22455141f2cSYan-Hao Wang newfs -S 512 -U "/dev/${lowerdev}" 22555141f2cSYan-Hao Wang lower_secsize="$(diskinfo "/dev/${lowerdev}" | awk '{print $2}')" 22655141f2cSYan-Hao Wang atf_check_equal "512" "$lower_secsize" 22755141f2cSYan-Hao Wang 22855141f2cSYan-Hao Wang gunion create -S 1024 "$upperdev" "$lowerdev" 22955141f2cSYan-Hao Wang guniondev="${upperdev}-${lowerdev}.union" 23055141f2cSYan-Hao Wang echo "$guniondev" > guniondev 23155141f2cSYan-Hao Wang 23255141f2cSYan-Hao Wang secsize="$(diskinfo "/dev/${guniondev}" | awk '{print $2}')" 23355141f2cSYan-Hao Wang atf_check_equal "1024" "$secsize" 23455141f2cSYan-Hao Wang} 23555141f2cSYan-Hao Wangsecsize_cleanup() 23655141f2cSYan-Hao Wang{ 23755141f2cSYan-Hao Wang gunion_test_cleanup 23855141f2cSYan-Hao Wang} 23955141f2cSYan-Hao Wang 24055141f2cSYan-Hao Wangatf_test_case gunionname cleanup 24155141f2cSYan-Hao Wanggunionname_head() 24255141f2cSYan-Hao Wang{ 24355141f2cSYan-Hao Wang atf_set "descr" "Test gunion create with -Z gunionname option" 24455141f2cSYan-Hao Wang atf_set "require.user" "root" 24555141f2cSYan-Hao Wang} 24655141f2cSYan-Hao Wanggunionname_body() 24755141f2cSYan-Hao Wang{ 24855141f2cSYan-Hao Wang gunion_test_setup 24955141f2cSYan-Hao Wang 250*96950419SGleb Smirnoff attach_md upperdev -s 1m 251*96950419SGleb Smirnoff attach_md lowerdev -s 1m 25255141f2cSYan-Hao Wang newfs -U "/dev/${lowerdev}" 25355141f2cSYan-Hao Wang 25455141f2cSYan-Hao Wang gunion create -Z gunion1 "$upperdev" "$lowerdev" 25555141f2cSYan-Hao Wang echo "gunion1.union" > guniondev 25655141f2cSYan-Hao Wang atf_check -o inline:"/dev/gunion1.union\n" ls /dev/gunion1.union 25755141f2cSYan-Hao Wang} 25855141f2cSYan-Hao Wanggunionname_cleanup() 25955141f2cSYan-Hao Wang{ 26055141f2cSYan-Hao Wang gunion_test_cleanup 26155141f2cSYan-Hao Wang} 26255141f2cSYan-Hao Wang 26355141f2cSYan-Hao Wangatf_test_case revert cleanup 26455141f2cSYan-Hao Wangrevert_head() 26555141f2cSYan-Hao Wang{ 26655141f2cSYan-Hao Wang atf_set "descr" "Test gunion revert" 26755141f2cSYan-Hao Wang atf_set "require.user" "root" 26855141f2cSYan-Hao Wang} 26955141f2cSYan-Hao Wangrevert_body() 27055141f2cSYan-Hao Wang{ 27155141f2cSYan-Hao Wang gunion_test_setup 27255141f2cSYan-Hao Wang 273*96950419SGleb Smirnoff attach_md upperdev -s 1m 274*96950419SGleb Smirnoff attach_md lowerdev -s 1m 27555141f2cSYan-Hao Wang newfs -U "/dev/${lowerdev}" 27655141f2cSYan-Hao Wang mkdir lowermnt 27755141f2cSYan-Hao Wang mkdir gunionmnt 27855141f2cSYan-Hao Wang 27955141f2cSYan-Hao Wang mount "/dev/${lowerdev}" lowermnt 28055141f2cSYan-Hao Wang echo "lower file" > lower_file 28155141f2cSYan-Hao Wang cp lower_file lowermnt/lower_file 28255141f2cSYan-Hao Wang sync 28355141f2cSYan-Hao Wang umount lowermnt 28455141f2cSYan-Hao Wang 28555141f2cSYan-Hao Wang atf_check gunion create "$upperdev" "$lowerdev" 28655141f2cSYan-Hao Wang guniondev="${upperdev}-${lowerdev}.union" 28755141f2cSYan-Hao Wang mount "/dev/${guniondev}" gunionmnt 28855141f2cSYan-Hao Wang 28955141f2cSYan-Hao Wang echo "update lower file" >> gunionmnt/lower_file 29055141f2cSYan-Hao Wang echo "gunion file" > gunion_file 29155141f2cSYan-Hao Wang cp gunion_file gunionmnt/gunion_file 29255141f2cSYan-Hao Wang sync 29355141f2cSYan-Hao Wang umount gunionmnt 29455141f2cSYan-Hao Wang atf_check gunion revert "$guniondev" 29555141f2cSYan-Hao Wang 29655141f2cSYan-Hao Wang mount "/dev/${guniondev}" gunionmnt 29755141f2cSYan-Hao Wang checksum gunionmnt/lower_file lower_file 29855141f2cSYan-Hao Wang atf_check -s not-exit:0 -o ignore -e ignore ls gunionmnt/gunion_file 29955141f2cSYan-Hao Wang 30055141f2cSYan-Hao Wang umount gunionmnt 30155141f2cSYan-Hao Wang gunion destroy "$guniondev" 30255141f2cSYan-Hao Wang} 30355141f2cSYan-Hao Wangrevert_cleanup() 30455141f2cSYan-Hao Wang{ 30555141f2cSYan-Hao Wang gunion_test_cleanup 30655141f2cSYan-Hao Wang} 30755141f2cSYan-Hao Wang 30855141f2cSYan-Hao Wangatf_init_test_cases() 30955141f2cSYan-Hao Wang{ 31055141f2cSYan-Hao Wang atf_add_test_case create 31155141f2cSYan-Hao Wang atf_add_test_case basic 31255141f2cSYan-Hao Wang atf_add_test_case commit 31355141f2cSYan-Hao Wang atf_add_test_case offset 31455141f2cSYan-Hao Wang atf_add_test_case size 31555141f2cSYan-Hao Wang atf_add_test_case secsize 31655141f2cSYan-Hao Wang atf_add_test_case gunionname 31755141f2cSYan-Hao Wang atf_add_test_case revert 31855141f2cSYan-Hao Wang} 31955141f2cSYan-Hao Wang 32055141f2cSYan-Hao Wangchecksum() 32155141f2cSYan-Hao Wang{ 32255141f2cSYan-Hao Wang src=$1 32355141f2cSYan-Hao Wang work=$2 32455141f2cSYan-Hao Wang 32555141f2cSYan-Hao Wang if [ ! -e "$src" ]; then 32655141f2cSYan-Hao Wang atf_fail "file not exist" 32755141f2cSYan-Hao Wang fi 32855141f2cSYan-Hao Wang if [ ! -e "$work" ]; then 32955141f2cSYan-Hao Wang atf_fail "file not exist" 33055141f2cSYan-Hao Wang fi 33155141f2cSYan-Hao Wang 33255141f2cSYan-Hao Wang src_checksum=$(md5 -q "$src") 33355141f2cSYan-Hao Wang work_checksum=$(md5 -q "$work") 33455141f2cSYan-Hao Wang 33555141f2cSYan-Hao Wang if [ "$work_checksum" != "$src_checksum" ]; then 33655141f2cSYan-Hao Wang atf_fail "md5 checksum didn't match with ${src} and ${work}" 33755141f2cSYan-Hao Wang fi 33855141f2cSYan-Hao Wang} 339