xref: /freebsd/tools/test/stress2/misc/ufssuspend.sh (revision 61e21613)
1#!/bin/sh
2
3# ioctl(g_ufs_suspend_handle, UFSSUSPEND, &statfsp->f_fsid) test scenario.
4
5# Bug 230220 - UFS: the freezing ioctl (i.e.UFSSUSPEND) causes panic or EBUSY
6# "panic: devfs_set_cdevpriv failed" seen.
7# Test scenario by Dexuan Cui <decui microsoft com>
8# Fixed by r337055.
9
10[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
11. ../default.cfg
12
13cat > /tmp/ufssuspend.c <<EOF
14
15#include <sys/types.h>
16#include <sys/ioctl.h>
17#include <sys/param.h>
18#include <sys/ucred.h>
19#include <sys/mount.h>
20
21#include <ufs/ffs/fs.h>
22
23#include <err.h>
24#include <errno.h>
25#include <fcntl.h>
26#include <paths.h>
27#include <poll.h>
28#include <stdint.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <sysexits.h>
33#include <syslog.h>
34#include <unistd.h>
35
36static int g_ufs_suspend_handle = -1;
37static const char *dev = "/dev";
38
39static int
40freeze(void)
41{
42	struct statfs *mntbuf, *statfsp;
43	int mntsize;
44	int error = 0;
45	int i;
46
47	g_ufs_suspend_handle = open(_PATH_UFSSUSPEND, O_RDWR);
48	if (g_ufs_suspend_handle == -1) {
49		printf("unable to open %s", _PATH_UFSSUSPEND);
50		return (errno);
51	}
52
53	mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
54	if (mntsize == 0) {
55		printf("There is no mount information\n");
56		return (EINVAL);
57	}
58
59	for (i = mntsize - 1; i >= 0; --i) {
60		statfsp = &mntbuf[i];
61
62		if (strncmp(statfsp->f_mntonname, dev, strlen(dev)) == 0)
63			continue; /* skip to freeze '/dev' */
64
65		if (statfsp->f_flags & MNT_RDONLY)
66			continue; /* skip to freeze RDONLY partition */
67
68		if (strncmp(statfsp->f_fstypename, "ufs", 3) != 0)
69			continue; /* so far, only UFS can be frozen */
70
71		printf("suspending fs: %s\n",  statfsp->f_mntonname);
72		error = ioctl(g_ufs_suspend_handle, UFSSUSPEND, &statfsp->f_fsid);
73		if (error != 0) {
74			printf("error: %d\n", errno);
75			error = errno;
76		} else {
77			printf("Successfully suspend fs: %s\n",  statfsp->f_mntonname);
78		}
79	}
80
81	return (error);
82}
83
84/**
85 * closing the opened handle will thaw the FS.
86 */
87static int
88thaw(void)
89{
90	int error = 0;
91
92	if (g_ufs_suspend_handle != -1) {
93		error = close(g_ufs_suspend_handle);
94		if (!error) {
95			g_ufs_suspend_handle = -1;
96			printf("Successfully thaw the fs\n");
97		} else {
98			error = errno;
99			printf("Fail to thaw the fs: "
100					"%d %s\n", errno, strerror(errno));
101		}
102	} else {
103		printf("The fs has already been thawed\n\n");
104	}
105
106	return (error);
107}
108
109int
110main(void)
111{
112	int error;
113
114	error = freeze();
115	printf("freeze: err=%d\n", error);
116
117	error = thaw();
118	printf("thaw: err=%d\n", error);
119
120	return 0;
121}
122EOF
123
124mycc -o /tmp/ufssuspend -Wall -Wextra -O2 -g /tmp/ufssuspend.c || exit 1
125rm /tmp/ufssuspend.c
126
127cd /tmp
128./ufssuspend > /dev/null
129s=$?
130rm /tmp/ufssuspend
131exit $s
132