Path: blob/main/tools/test/stress2/testcases/lockf/lockf.c
39566 views
/*-1* Copyright (c) 2008 Peter Holm <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*25*/2627/* Test lockf(3) */2829#include <sys/param.h>30#include <sys/wait.h>3132#include <err.h>33#include <errno.h>34#include <fcntl.h>35#include <signal.h>36#include <stdio.h>37#include <stdlib.h>38#include <unistd.h>3940#include "stress.h"4142static pid_t pid;43static int fd;44static int freespace;45static char file[128];4647static int48get(void) {49int r, sem;5051do {52r = lockf(fd, F_LOCK, 0);53} while (r == -1 && errno == EINTR && done_testing == 0);54if (r == -1)55err(1, "lockf(%s, F_LOCK)", file);56if (lseek(fd, 0, SEEK_SET) == -1) // XXX57err(1, "lseek"); // XXX58r = read(fd, &sem, sizeof(sem));59if (r == -1)60err(1, "get: read(%d)", fd);61if (r == 0)62errx(1, "get() read 0 bytes");63if (r != sizeof(sem))64errx(1, "get() size error: %d", r);65if (lseek(fd, 0, SEEK_SET) == -1)66err(1, "lseek");67if (lockf(fd, F_ULOCK, 0) == -1)68err(1, "lockf(%s, F_ULOCK)", file);69return (sem);70}7172static void73incr(void) {74int r, sem;7576do {77r = lockf(fd, F_LOCK, 0);78} while (r == -1 && errno == EINTR && done_testing == 0);79if (r == -1)80err(1, "lockf(%s, F_LOCK)", file);81if (read(fd, &sem, sizeof(sem)) != sizeof(sem))82err(1, "incr: read(%d)", fd);83if (lseek(fd, 0, SEEK_SET) == -1)84err(1, "lseek");85sem++;86if (write(fd, &sem, sizeof(sem)) != sizeof(sem))87err(1, "incr: read");88if (lseek(fd, 0, SEEK_SET) == -1)89err(1, "lseek");90if (lockf(fd, F_ULOCK, 0) == -1)91err(1, "lockf(%s, F_ULOCK)", file);92}9394int95setup(int nb)96{97int64_t bl;98int64_t in;99int64_t reserve_bl;100int64_t reserve_in;101102if (nb == 0) {103getdf(&bl, &in);104105/* Resource requirements: */106reserve_in = 1 * op->incarnations;107reserve_bl = 4096 * op->incarnations;108freespace = (reserve_bl <= bl && reserve_in <= in);109if (!freespace)110reserve_bl = reserve_in = 0;111112if (op->verbose > 1)113printf("lockf(incarnations=%d). Free(%jdk, %jd), reserve(%jdk, %jd)\n",114op->incarnations, bl/1024, in, reserve_bl/1024, reserve_in);115reservedf(reserve_bl, reserve_in);116putval(freespace);117} else {118freespace = getval();119}120if (!freespace)121exit(0);122123return (0);124}125126void127cleanup(void)128{129}130131int132test(void)133{134int i;135int sem = 0;136137sprintf(file, "lockf.0.%d", getpid());138if ((fd = open(file,O_CREAT | O_TRUNC | O_RDWR, 0600)) == -1) {139if (errno == ENOENT)140return (0);141else142err(1, "creat(%s) %s:%d", file, __FILE__, __LINE__);143}144if (write(fd, &sem, sizeof(sem)) != sizeof(sem))145err(1, "write");146if (lseek(fd, 0, SEEK_SET) == -1)147err(1, "lseek");148149pid = fork();150if (pid == -1) {151perror("fork");152exit(2);153}154155if (pid == 0) { /* child */156alarm(60);157for (i = 0; i < 100 && done_testing == 0; i++) {158while ((get() & 1) == 0 && done_testing == 0)159;160if (op->verbose > 3)161printf("Child %d, sem = %d\n", i, get()),162fflush(stdout);163incr();164}165_exit(0);166} else { /* parent */167for (i = 0; i < 100 && done_testing == 0; i++) {168while ((get() & 1) == 1 && done_testing == 0)169;170if (op->verbose > 3)171printf("Parent %d, sem = %d\n", i, get()),172fflush(stdout);173incr();174}175}176close(fd);177if (done_testing == 1)178kill(pid, SIGHUP);179waitpid(pid, &i, 0);180unlink(file);181182return (0);183}184185186