1#!/bin/sh
2
3#
4# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
5#
6# SPDX-License-Identifier: BSD-2-Clause
7#
8
9# O_PATH test scenario.  Variation of nullfs29.sh
10
11[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
12. ../default.cfg
13
14md1=$mdstart
15md2=$((md1 + 1))
16mp1=/mnt$md1
17mp2=/mnt$md2
18mkdir -p $mp1 $mp2
19set -e
20for i in $mp1 $mp2; do
21	mount | grep -q "on $i " && umount -f $i
22done
23for i in $md1 $md2; do
24	mdconfig -l | grep -q md$i && mdconfig -d -u $i
25done
26
27mdconfig -a -t swap -s 2g -u $md1
28mdconfig -a -t swap -s 2g -u $md2
29newfs $newfs_flags -n md$md1 > /dev/null
30newfs $newfs_flags -n md$md2 > /dev/null
31mount /dev/md$md1 $mp1
32mount /dev/md$md2 $mp2
33mount -t unionfs -o noatime $mp1 $mp2
34set +e
35
36cat > /tmp/unionfs15.c <<EOF
37#include <sys/stat.h>
38#include <err.h>
39#include <errno.h>
40#include <fcntl.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44
45int
46main(void) {
47	int new_dir, new_file, ret;
48	struct stat sb;
49	char *dir = "test2";
50	char *path= "test2/what2";
51
52	if (mkdir(dir, 0755) == -1)
53		err(1, "mkdir(test2)");
54	new_dir = openat(AT_FDCWD, dir, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_PATH, 0700);
55	if (new_dir == -1)
56		err(1, "openat(%s)", dir);
57
58	ret = fstatat(new_dir, "what2", &sb, AT_SYMLINK_NOFOLLOW);
59	if (ret == 0)
60		errx(1, "Expected fstatat() to fail");
61	if (ret == -1 && errno != ENOENT)
62		err(1, "fstatat(%s)", dir);
63
64	close(new_dir);
65	new_file = openat(AT_FDCWD, path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0644);
66	if (new_file== -1)
67		err(1, "openat(%s)", path);
68}
69
70EOF
71mycc -o /tmp/unionfs15 -Wall -Wextra -O2 /tmp/unionfs15.c || exit 1
72cd $mp2
73/tmp/unionfs15; s=$?
74cd $here
75umount $mp2
76
77while mount | grep -Eq "on $mp2 .*unionfs"; do
78	umount $mp2 && break
79	sleep 5
80done
81umount $mp2
82umount $mp1
83mdconfig -d -u $md2
84mdconfig -d -u $md1
85rm -f /tmp/unionfs15.c /tmp/unionfs15
86exit $s
87