xref: /freebsd/tools/test/stress2/lib/resources.c (revision 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d)
1*8a272653SPeter Holm /*-
2*8a272653SPeter Holm  * Copyright (c) 2008 Peter Holm <pho@FreeBSD.org>
3*8a272653SPeter Holm  * All rights reserved.
4*8a272653SPeter Holm  *
5*8a272653SPeter Holm  * Redistribution and use in source and binary forms, with or without
6*8a272653SPeter Holm  * modification, are permitted provided that the following conditions
7*8a272653SPeter Holm  * are met:
8*8a272653SPeter Holm  * 1. Redistributions of source code must retain the above copyright
9*8a272653SPeter Holm  *    notice, this list of conditions and the following disclaimer.
10*8a272653SPeter Holm  * 2. Redistributions in binary form must reproduce the above copyright
11*8a272653SPeter Holm  *    notice, this list of conditions and the following disclaimer in the
12*8a272653SPeter Holm  *    documentation and/or other materials provided with the distribution.
13*8a272653SPeter Holm  *
14*8a272653SPeter Holm  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*8a272653SPeter Holm  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*8a272653SPeter Holm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*8a272653SPeter Holm  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*8a272653SPeter Holm  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*8a272653SPeter Holm  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*8a272653SPeter Holm  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*8a272653SPeter Holm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*8a272653SPeter Holm  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*8a272653SPeter Holm  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*8a272653SPeter Holm  * SUCH DAMAGE.
25*8a272653SPeter Holm  *
26*8a272653SPeter Holm  */
27*8a272653SPeter Holm 
28*8a272653SPeter Holm /* Get various resource limits for the tests */
29*8a272653SPeter Holm 
30*8a272653SPeter Holm #include <sys/types.h>
31*8a272653SPeter Holm #include <sys/sysctl.h>
32*8a272653SPeter Holm #include <unistd.h>
33*8a272653SPeter Holm #include <stdio.h>
34*8a272653SPeter Holm #include <stdlib.h>
35*8a272653SPeter Holm #include <fcntl.h>
36*8a272653SPeter Holm #include <string.h>
37*8a272653SPeter Holm #include <sys/stat.h>
38*8a272653SPeter Holm #include <sys/param.h>
39*8a272653SPeter Holm #include <sys/mount.h>
40*8a272653SPeter Holm #include <kvm.h>
41*8a272653SPeter Holm #include <vm/vm_param.h>
42*8a272653SPeter Holm #include <errno.h>
43*8a272653SPeter Holm #include <err.h>
44*8a272653SPeter Holm #include <stdarg.h>
45*8a272653SPeter Holm #include <libutil.h>
46*8a272653SPeter Holm 
47*8a272653SPeter Holm #include "stress.h"
48*8a272653SPeter Holm 
49*8a272653SPeter Holm static int lockfd;
50*8a272653SPeter Holm static int dffd;
51*8a272653SPeter Holm static int flags;
52*8a272653SPeter Holm static char lockpath[128];
53*8a272653SPeter Holm static char dfpath[128];
54*8a272653SPeter Holm 
55*8a272653SPeter Holm static int64_t
56*8a272653SPeter Holm inodes(void)
57*8a272653SPeter Holm {
58*8a272653SPeter Holm 	char path[MAXPATHLEN+1];
59*8a272653SPeter Holm 	struct statfs buf;
60*8a272653SPeter Holm 
61*8a272653SPeter Holm 	if (op->inodes != 0)
62*8a272653SPeter Holm 		return (op->inodes);
63*8a272653SPeter Holm 	if (getcwd(path, sizeof(path)) == NULL)
64*8a272653SPeter Holm 		err(1, "getcwd()");
65*8a272653SPeter Holm 
66*8a272653SPeter Holm 	if (statfs(path, &buf) < 0)
67*8a272653SPeter Holm 		err(1, "statfs(%s)", path);
68*8a272653SPeter Holm 	if (!strcmp(buf.f_fstypename, "msdosfs"))
69*8a272653SPeter Holm 			buf.f_ffree = 9999;
70*8a272653SPeter Holm 	flags = buf.f_flags & MNT_VISFLAGMASK;
71*8a272653SPeter Holm 	if (op->verbose > 2)
72*8a272653SPeter Holm 		printf("Free inodes on %s (%s): %jd\n", path,
73*8a272653SPeter Holm 		    buf.f_mntonname, buf.f_ffree);
74*8a272653SPeter Holm 	return (buf.f_ffree);
75*8a272653SPeter Holm }
76*8a272653SPeter Holm 
77*8a272653SPeter Holm static int64_t
78*8a272653SPeter Holm df(void)
79*8a272653SPeter Holm {
80*8a272653SPeter Holm 	char path[MAXPATHLEN+1];
81*8a272653SPeter Holm 	struct statfs buf;
82*8a272653SPeter Holm 
83*8a272653SPeter Holm 	if (op->kblocks != 0)
84*8a272653SPeter Holm 		return (op->kblocks * (uint64_t)1024);
85*8a272653SPeter Holm 
86*8a272653SPeter Holm 	if (getcwd(path, sizeof(path)) == NULL)
87*8a272653SPeter Holm 		err(1, "getcwd()");
88*8a272653SPeter Holm 
89*8a272653SPeter Holm 	if (statfs(path, &buf) < 0)
90*8a272653SPeter Holm 		err(1, "statfs(%s)", path);
91*8a272653SPeter Holm 	if (buf.f_bavail > (int64_t)buf.f_blocks || buf.f_bavail < 0) {
92*8a272653SPeter Holm 		warnx("Corrupt statfs(%s). f_bavail = %jd!", path,
93*8a272653SPeter Holm 		    buf.f_bavail);
94*8a272653SPeter Holm 		buf.f_bavail = 100;
95*8a272653SPeter Holm 	}
96*8a272653SPeter Holm 	if (op->verbose > 2)
97*8a272653SPeter Holm 		printf("Free space on %s: %jd Mb\n", path, buf.f_bavail *
98*8a272653SPeter Holm 		    buf.f_bsize / 1024 / 1024);
99*8a272653SPeter Holm 	return (buf.f_bavail * buf.f_bsize);
100*8a272653SPeter Holm }
101*8a272653SPeter Holm 
102*8a272653SPeter Holm int64_t
103*8a272653SPeter Holm swap(void)
104*8a272653SPeter Holm {
105*8a272653SPeter Holm 	struct xswdev xsw;
106*8a272653SPeter Holm 	size_t mibsize, size;
107*8a272653SPeter Holm 	int mib[16], n;
108*8a272653SPeter Holm 	int64_t sz;
109*8a272653SPeter Holm 
110*8a272653SPeter Holm 	mibsize = sizeof mib / sizeof mib[0];
111*8a272653SPeter Holm 	sz = 0;
112*8a272653SPeter Holm 
113*8a272653SPeter Holm 	if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)
114*8a272653SPeter Holm 		err(1, "sysctlnametomib()");
115*8a272653SPeter Holm 
116*8a272653SPeter Holm 	for (n = 0; ; ++n) {
117*8a272653SPeter Holm 		mib[mibsize] = n;
118*8a272653SPeter Holm 		size = sizeof xsw;
119*8a272653SPeter Holm 		if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1)
120*8a272653SPeter Holm 			break;
121*8a272653SPeter Holm 		if (xsw.xsw_version != XSWDEV_VERSION)
122*8a272653SPeter Holm 			errx(1, "xswdev version mismatch");
123*8a272653SPeter Holm 		sz = sz + xsw.xsw_nblks - xsw.xsw_used;
124*8a272653SPeter Holm 	}
125*8a272653SPeter Holm 	if (errno != ENOENT)
126*8a272653SPeter Holm 		err(1, "sysctl()");
127*8a272653SPeter Holm 
128*8a272653SPeter Holm 	if (op->verbose > 2)
129*8a272653SPeter Holm 		printf("Total free swap space %jd Mb\n",
130*8a272653SPeter Holm 			sz * getpagesize() / 1024 / 1024);
131*8a272653SPeter Holm 
132*8a272653SPeter Holm 	return (sz * getpagesize());
133*8a272653SPeter Holm }
134*8a272653SPeter Holm 
135*8a272653SPeter Holm unsigned long
136*8a272653SPeter Holm usermem(void)
137*8a272653SPeter Holm {
138*8a272653SPeter Holm 	unsigned long mem;
139*8a272653SPeter Holm 	size_t nlen = sizeof(mem);
140*8a272653SPeter Holm 
141*8a272653SPeter Holm 	if (sysctlbyname("hw.usermem", &mem, &nlen, NULL, 0) == -1)
142*8a272653SPeter Holm 		err(1, "sysctlbyname() %s:%d", __FILE__, __LINE__);
143*8a272653SPeter Holm 
144*8a272653SPeter Holm 	if (op->verbose > 2)
145*8a272653SPeter Holm 		printf("Total free user memory %lu Mb\n",
146*8a272653SPeter Holm 			mem / 1024 / 1024);
147*8a272653SPeter Holm 
148*8a272653SPeter Holm 	return (mem);
149*8a272653SPeter Holm }
150*8a272653SPeter Holm 
151*8a272653SPeter Holm static void
152*8a272653SPeter Holm cleanupdf()
153*8a272653SPeter Holm {
154*8a272653SPeter Holm 	unlink(dfpath);
155*8a272653SPeter Holm }
156*8a272653SPeter Holm 
157*8a272653SPeter Holm void
158*8a272653SPeter Holm getdf(int64_t *block, int64_t *inode)
159*8a272653SPeter Holm {
160*8a272653SPeter Holm 	int i, j;
161*8a272653SPeter Holm 	char buf[128];
162*8a272653SPeter Holm 
163*8a272653SPeter Holm 	snprintf(lockpath, sizeof(lockpath), "%s/lock", op->cd);
164*8a272653SPeter Holm 	for (j = 0; j < 2; j++) {
165*8a272653SPeter Holm 		for (i = 0; i < 10000; i++) {
166*8a272653SPeter Holm 			if ((lockfd = open(lockpath,
167*8a272653SPeter Holm 			    O_CREAT | O_TRUNC | O_WRONLY |
168*8a272653SPeter Holm 			    O_EXCL, 0644)) != -1)
169*8a272653SPeter Holm 				break;
170*8a272653SPeter Holm 			usleep(10000); /* sleep 1/100 sec */
171*8a272653SPeter Holm 			if (i > 0 && i % 1000 == 0)
172*8a272653SPeter Holm 				fprintf(stderr, "%s is waiting for lock file"
173*8a272653SPeter Holm 				    " %s\n",
174*8a272653SPeter Holm 				    getprogname(), lockpath);
175*8a272653SPeter Holm 		}
176*8a272653SPeter Holm 		if (lockfd != -1)
177*8a272653SPeter Holm 			break;
178*8a272653SPeter Holm 		fprintf(stderr, "%s. Removing stale %s\n", getprogname(),
179*8a272653SPeter Holm 		    lockpath);
180*8a272653SPeter Holm 		unlink(lockpath);
181*8a272653SPeter Holm 	}
182*8a272653SPeter Holm 	if (lockfd == -1)
183*8a272653SPeter Holm 		errx(1, "%s. Can not create %s\n", getprogname(), lockpath);
184*8a272653SPeter Holm 	snprintf(dfpath, sizeof(dfpath), "%s/df", op->cd);
185*8a272653SPeter Holm 	if ((dffd = open(dfpath, O_RDWR, 0644)) == -1) {
186*8a272653SPeter Holm 		if ((dffd = open(dfpath,
187*8a272653SPeter Holm 				O_CREAT | O_TRUNC | O_WRONLY, 0644)) == -1) {
188*8a272653SPeter Holm 			unlink(lockpath);
189*8a272653SPeter Holm 			err(1, "creat(%s) %s:%d", dfpath, __FILE__,
190*8a272653SPeter Holm 			    __LINE__);
191*8a272653SPeter Holm 		}
192*8a272653SPeter Holm 		atexit(cleanupdf);
193*8a272653SPeter Holm 		*block = df();
194*8a272653SPeter Holm 		*inode = inodes();
195*8a272653SPeter Holm 		snprintf(buf, sizeof(buf), "%jd %jd", *block, *inode);
196*8a272653SPeter Holm 
197*8a272653SPeter Holm 		if (write(dffd, buf, strlen(buf) + 1) !=
198*8a272653SPeter Holm 		    (ssize_t)strlen(buf) +1)
199*8a272653SPeter Holm 			err(1, "write df. %s:%d", __FILE__, __LINE__);
200*8a272653SPeter Holm 	} else {
201*8a272653SPeter Holm 		if (read(dffd, buf, sizeof(buf)) < 1) {
202*8a272653SPeter Holm 			system("ls -l /tmp/stressX.control");
203*8a272653SPeter Holm 			unlink(lockpath);
204*8a272653SPeter Holm 			err(1, "read df. %s:%d", __FILE__, __LINE__);
205*8a272653SPeter Holm 		}
206*8a272653SPeter Holm 		sscanf(buf, "%jd %jd", block, inode);
207*8a272653SPeter Holm 	}
208*8a272653SPeter Holm 	close(dffd);
209*8a272653SPeter Holm }
210*8a272653SPeter Holm 
211*8a272653SPeter Holm void
212*8a272653SPeter Holm reservedf(int64_t blks, int64_t inos)
213*8a272653SPeter Holm {
214*8a272653SPeter Holm 	char buf[128];
215*8a272653SPeter Holm 	int64_t blocks, inodes;
216*8a272653SPeter Holm 
217*8a272653SPeter Holm 	if ((dffd = open(dfpath, O_RDWR, 0644)) == -1) {
218*8a272653SPeter Holm 		warn("open(%s) %s:%d. %s", dfpath, __FILE__, __LINE__,
219*8a272653SPeter Holm 		    getprogname());
220*8a272653SPeter Holm 		goto err;
221*8a272653SPeter Holm 	}
222*8a272653SPeter Holm 	if (read(dffd, buf, sizeof(buf)) < 1) {
223*8a272653SPeter Holm 		warn("read df. %s:%d", __FILE__, __LINE__);
224*8a272653SPeter Holm 		goto err;
225*8a272653SPeter Holm 	}
226*8a272653SPeter Holm 	sscanf(buf, "%jd %jd", &blocks, &inodes);
227*8a272653SPeter Holm 
228*8a272653SPeter Holm 	if (op->verbose > 2)
229*8a272653SPeter Holm 		printf("%-8s: reservefd(%9jdK, %6jd) out of (%9jdK, %6jd)\n",
230*8a272653SPeter Holm 				getprogname(), blks/1024, inos, blocks/1024,
231*8a272653SPeter Holm 				inodes);
232*8a272653SPeter Holm 	blocks -= blks;
233*8a272653SPeter Holm 	inodes -= inos;
234*8a272653SPeter Holm 
235*8a272653SPeter Holm 	snprintf(buf, sizeof(buf), "%jd %jd", blocks, inodes);
236*8a272653SPeter Holm 	if (blocks < 0 || inodes < 0)
237*8a272653SPeter Holm 		printf("******************************** %s: %s\n",
238*8a272653SPeter Holm 		    getprogname(), buf);
239*8a272653SPeter Holm 	if (lseek(dffd, 0, 0) == -1)
240*8a272653SPeter Holm 		err(1, "lseek. %s:%d", __FILE__, __LINE__);
241*8a272653SPeter Holm 	if (write(dffd, buf, strlen(buf) + 1) != (ssize_t)strlen(buf) +1)
242*8a272653SPeter Holm 		warn("write df. %s:%d", __FILE__, __LINE__);
243*8a272653SPeter Holm err:
244*8a272653SPeter Holm 	close(dffd);
245*8a272653SPeter Holm 	close(lockfd);
246*8a272653SPeter Holm 	if (unlink(lockpath) == -1)
247*8a272653SPeter Holm 		err(1, "unlink(%s)", lockpath);
248*8a272653SPeter Holm }
249