xref: /freebsd/tools/test/stress2/misc/setrlimit.sh (revision 4d846d260e2b9a3d4d0a701462568268cbfe7a5b)
1977d8fb9SPeter Holm#!/bin/sh
2977d8fb9SPeter Holm
3977d8fb9SPeter Holm#
4*4d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause
5977d8fb9SPeter Holm#
6977d8fb9SPeter Holm# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
7977d8fb9SPeter Holm#
8977d8fb9SPeter Holm# Redistribution and use in source and binary forms, with or without
9977d8fb9SPeter Holm# modification, are permitted provided that the following conditions
10977d8fb9SPeter Holm# are met:
11977d8fb9SPeter Holm# 1. Redistributions of source code must retain the above copyright
12977d8fb9SPeter Holm#    notice, this list of conditions and the following disclaimer.
13977d8fb9SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright
14977d8fb9SPeter Holm#    notice, this list of conditions and the following disclaimer in the
15977d8fb9SPeter Holm#    documentation and/or other materials provided with the distribution.
16977d8fb9SPeter Holm#
17977d8fb9SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18977d8fb9SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19977d8fb9SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20977d8fb9SPeter Holm# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21977d8fb9SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22977d8fb9SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23977d8fb9SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24977d8fb9SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25977d8fb9SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26977d8fb9SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27977d8fb9SPeter Holm# SUCH DAMAGE.
28977d8fb9SPeter Holm#
29977d8fb9SPeter Holm
30977d8fb9SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
31977d8fb9SPeter Holm
32977d8fb9SPeter Holm# Test setrlimit() max file size and ftruncate()
33977d8fb9SPeter Holm
34977d8fb9SPeter Holm# Problem seen:
35977d8fb9SPeter Holm# Testing UFS -O1
36977d8fb9SPeter Holm# setrlimit: ftruncate(5413) did not fail. limit = 2791
37977d8fb9SPeter Holm# Testing FFS -U
38977d8fb9SPeter Holm# setrlimit: ftruncate(9956) did not fail. limit = 7880
39977d8fb9SPeter Holm# Testing msdosfs
40977d8fb9SPeter Holm# setrlimit: ftruncate(9033) did not fail. limit = 5884
41977d8fb9SPeter Holm# Testing tmpfs
42977d8fb9SPeter Holm# setrlimit: ftruncate(123) did not fail. limit = 86
43977d8fb9SPeter Holm
44977d8fb9SPeter Holm. ../default.cfg
45977d8fb9SPeter Holm
46977d8fb9SPeter Holmcat > /tmp/setrlimit.c <<EOF
47977d8fb9SPeter Holm#include <sys/types.h>
48977d8fb9SPeter Holm#include <sys/resource.h>
49977d8fb9SPeter Holm#include <sys/stat.h>
50977d8fb9SPeter Holm
51977d8fb9SPeter Holm#include <err.h>
52977d8fb9SPeter Holm#include <errno.h>
53977d8fb9SPeter Holm#include <fcntl.h>
54977d8fb9SPeter Holm#include <signal.h>
55977d8fb9SPeter Holm#include <stdio.h>
56977d8fb9SPeter Holm#include <stdlib.h>
57977d8fb9SPeter Holm#include <unistd.h>
58977d8fb9SPeter Holm
59977d8fb9SPeter Holmstatic int signals;
60977d8fb9SPeter Holm
61977d8fb9SPeter Holmstatic void
62977d8fb9SPeter Holmhandler(int sig __unused)
63977d8fb9SPeter Holm{
64977d8fb9SPeter Holm#if defined(DEBUG)
65977d8fb9SPeter Holm	fprintf(stderr, "Got signal SIGXFSZ\n");
66977d8fb9SPeter Holm#endif
67977d8fb9SPeter Holm	signals++;
68977d8fb9SPeter Holm}
69977d8fb9SPeter Holm
70977d8fb9SPeter Holmvoid
71977d8fb9SPeter Holmtest(int argc, char *argv[])
72977d8fb9SPeter Holm{
73977d8fb9SPeter Holm	struct rlimit rlim;
74977d8fb9SPeter Holm	rlim_t limit, sz;
75977d8fb9SPeter Holm	struct sigaction act;
76977d8fb9SPeter Holm	long pos;
77977d8fb9SPeter Holm	int e, expected, fd;
78977d8fb9SPeter Holm	char file[] = "setrlimit.file";
79977d8fb9SPeter Holm
80977d8fb9SPeter Holm	if (argc != 2) {
81977d8fb9SPeter Holm		fprintf(stderr, "Usage: %s <FS size>\n", argv[0]);
82977d8fb9SPeter Holm		exit(1);
83977d8fb9SPeter Holm	}
84977d8fb9SPeter Holm	expected = signals = 0;
85977d8fb9SPeter Holm	sz = atol(argv[1]);
86977d8fb9SPeter Holm	arc4random_buf(&limit, sizeof(limit));
87977d8fb9SPeter Holm	if (limit < 0)
88977d8fb9SPeter Holm		limit = -limit;
89977d8fb9SPeter Holm	limit = limit % sz + 1;
90977d8fb9SPeter Holm	rlim.rlim_cur = rlim.rlim_max = limit;
91977d8fb9SPeter Holm	if (setrlimit(RLIMIT_FSIZE, &rlim) == -1)
92977d8fb9SPeter Holm		err(1, "setrlimit(%ld)", limit);
93977d8fb9SPeter Holm
94977d8fb9SPeter Holm	act.sa_handler = handler;
95977d8fb9SPeter Holm	act.sa_flags = 0;
96977d8fb9SPeter Holm	sigemptyset(&act.sa_mask);
97977d8fb9SPeter Holm	if (sigaction(SIGXFSZ, &act, NULL) != 0)
98977d8fb9SPeter Holm		err(1, "sigaction");
99977d8fb9SPeter Holm
100977d8fb9SPeter Holm	if ((fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE)) == -1)
101977d8fb9SPeter Holm		err(1, "open(%s)", file);
102977d8fb9SPeter Holm
103977d8fb9SPeter Holm	e  = 0;
104977d8fb9SPeter Holm	arc4random_buf(&pos, sizeof(pos));
105977d8fb9SPeter Holm	if (pos < 0)
106977d8fb9SPeter Holm		pos = -pos;
107977d8fb9SPeter Holm	pos = pos % (limit * 2);
108977d8fb9SPeter Holm	if (pos > limit)
109977d8fb9SPeter Holm		expected = 1;
110977d8fb9SPeter Holm	if (ftruncate(fd, pos) == -1) {
111977d8fb9SPeter Holm		e = errno;
112977d8fb9SPeter Holm		if (pos <= limit)
113977d8fb9SPeter Holm			errc(1, e, "ftruncate(%ld), limit = %ld", pos, limit);
114977d8fb9SPeter Holm	} else {
115977d8fb9SPeter Holm		if (pos > limit)
116977d8fb9SPeter Holm			errx(1, "ftruncate(%ld) did not fail. limit = %ld", pos, limit);
117977d8fb9SPeter Holm	}
118977d8fb9SPeter Holm
119977d8fb9SPeter Holm	if (lseek(fd, limit - 1, SEEK_SET) == -1)
120977d8fb9SPeter Holm		err(1, "lseek(limit - 1)");
121977d8fb9SPeter Holm	if (write(fd, "a", 1) != 1)
122977d8fb9SPeter Holm		err(1, "write() at limit - 1. limit = %ld", limit);
123977d8fb9SPeter Holm
124977d8fb9SPeter Holm	if (write(fd, "b", 1) != -1)
125977d8fb9SPeter Holm		err(1, "write() at limit. limit = %ld", limit);
126977d8fb9SPeter Holm	expected++;
127977d8fb9SPeter Holm
128977d8fb9SPeter Holm	/* Partial write test. No signal is expected */
129977d8fb9SPeter Holm	if (lseek(fd, limit - 1, SEEK_SET) == -1)
130977d8fb9SPeter Holm		err(1, "lseek(limit - 1)");
131977d8fb9SPeter Holm	if (write(fd, "12", 2) != 1)
132977d8fb9SPeter Holm		err(1, "write() at limit - 1. limit = %ld", limit);
133977d8fb9SPeter Holm
134977d8fb9SPeter Holm	if (signals != expected)
135977d8fb9SPeter Holm		errx(1, "Expected %d signals, got %d", expected, signals);
136977d8fb9SPeter Holm
137977d8fb9SPeter Holm	close(fd);
138977d8fb9SPeter Holm	unlink(file);
139977d8fb9SPeter Holm}
140977d8fb9SPeter Holm
141977d8fb9SPeter Holmint
142977d8fb9SPeter Holmmain(int argc, char *argv[])
143977d8fb9SPeter Holm{
144977d8fb9SPeter Holm	int i;
145977d8fb9SPeter Holm
146977d8fb9SPeter Holm	for (i = 0; i < 100; i++)
147977d8fb9SPeter Holm		test(argc, argv);
148977d8fb9SPeter Holm
149977d8fb9SPeter Holm}
150977d8fb9SPeter HolmEOF
151977d8fb9SPeter Holm
152977d8fb9SPeter Holmhere=`pwd`
153977d8fb9SPeter Holms=0
154977d8fb9SPeter Holmcc -o /tmp/setrlimit -Wall -Wextra -O0 -g /tmp/setrlimit.c || exit 1
155977d8fb9SPeter Holm
156977d8fb9SPeter Holmmount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
157977d8fb9SPeter Holm[ -c /dev/md$mdstart ] &&  mdconfig -d -u $mdstart
158977d8fb9SPeter Holm
159977d8fb9SPeter Holmecho "Testing UFS -O1"
160977d8fb9SPeter Holmmdconfig -t swap -s 1g -u $mdstart
161977d8fb9SPeter Holmnewfs -O1 /dev/md$mdstart > /dev/null
162977d8fb9SPeter Holmmount /dev/md$mdstart $mntpoint
163977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 ||  s=1
164977d8fb9SPeter Holmcd $here
165977d8fb9SPeter Holmumount $mntpoint
166977d8fb9SPeter Holmmdconfig -d -u $mdstart
167977d8fb9SPeter Holm
168977d8fb9SPeter Holmecho "Testing FFS -U"
169977d8fb9SPeter Holmmdconfig -t swap -s 1g -u $mdstart
170977d8fb9SPeter Holmnewfs -U /dev/md$mdstart > /dev/null
171977d8fb9SPeter Holmmount /dev/md$mdstart $mntpoint
172977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 2))
173977d8fb9SPeter Holmcd $here
174977d8fb9SPeter Holmumount $mntpoint
175977d8fb9SPeter Holmmdconfig -d -u $mdstart
176977d8fb9SPeter Holm
177977d8fb9SPeter Holmecho "Testing msdosfs"
178977d8fb9SPeter Holmmdconfig -t swap -s 1g -u $mdstart
179977d8fb9SPeter Holmnewfs_msdos -F 32 -b 8192 /dev/md$mdstart > /dev/null 2>&1
180977d8fb9SPeter Holmmount -t msdosfs /dev/md$mdstart $mntpoint
181977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 4))
182977d8fb9SPeter Holmcd $here
183977d8fb9SPeter Holmumount $mntpoint
184977d8fb9SPeter Holmmdconfig -d -u $mdstart
185977d8fb9SPeter Holm
186977d8fb9SPeter Holmecho "Testing tmpfs"
187977d8fb9SPeter Holmmount -o size=20000 -t tmpfs dummy $mntpoint
188977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 8))
189977d8fb9SPeter Holmcd $here
190977d8fb9SPeter Holmumount $mntpoint
191977d8fb9SPeter Holm
192977d8fb9SPeter Holmrm -f /tmp/setrlimit /tmp/setrlimit.c
193977d8fb9SPeter Holmexit $s
194