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