90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello/*
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * This file and its contents are supplied under the terms of the
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * Common Development and Distribution License ("CDDL"), version 1.0.
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * You may only use this file in accordance with the terms of version
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * 1.0 of the CDDL.
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello *
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * A full copy of the text of the CDDL should have accompanied this
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * source. A copy of the CDDL is also available via the Internet at
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * http://www.illumos.org/license/CDDL.
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello/*
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * Copyright 2016 Joyent, Inc.
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello/*
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * Validate various fcntl(2) and flock(3C) operations.
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include "util.h"
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <err.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <errno.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <fcntl.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <libgen.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <signal.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <stdlib.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <strings.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <sys/debug.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <sys/file.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <sys/stat.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <sys/wait.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#include <unistd.h>
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#define LOCKFILE_FMT "/tmp/.lockfile-%s-%ld"
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello#define LOCKDIR_FMT "/tmp/.lockdir-%s-%ld"
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellotypedef struct lockinfo {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello char *lf_name;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello char *lf_path;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello int lf_fd;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello} lockinfo_t;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void assert_write_locked_by(lockinfo_t *, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void assert_read_locked_by(lockinfo_t *, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void assert_unlocked(lockinfo_t *);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void assert_all_unlocked(void);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic int flock_copyfil(lockinfo_t *, lockinfo_t *);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic int flock_mkfil(lockinfo_t *);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic int flock_mkdir(lockinfo_t *);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void flock_rminfo(lockinfo_t *);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void flock_fcntl(lockinfo_t *lf, int cmd, struct flock *fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void flock_run(lock_style_t, boolean_t, lockinfo_t *,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello pid_t *, int[]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic int flock_wait(pid_t pid);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void flock_cleanup_child(pid_t, int []);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void flock_test_invalid(lockinfo_t *, int, short, short,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello off_t, off_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void flock_test_exclusive(lock_style_t, lock_style_t,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello lockinfo_t *, lockinfo_t *, boolean_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void flock_test_shared(lock_style_t, lock_style_t, lockinfo_t *,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello lockinfo_t *, boolean_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void flock_test_upgrade_downgrade(void);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic char *acqprog = NULL;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic lockinfo_t flock_fileA = { "a", NULL, -1 };
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic lockinfo_t flock_fileB = { "b", NULL, -1 };
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic lockinfo_t flock_dirA = { "a", NULL, -1 };
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic lockinfo_t flock_dirB = { "b", NULL, -1 };
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic short cmds[8] = {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello F_SETLK, F_SETLKW, F_GETLK,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello F_OFD_SETLK, F_OFD_SETLKW, F_OFD_GETLK,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello F_FLOCK, F_FLOCKW
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello};
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_kill(pid_t pid)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello while (kill(pid, SIGKILL) == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (errno == EINTR)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello continue;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE, "kill failed");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_fcntl(lockinfo_t *lf, int cmd, struct flock *fl)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (fcntl(lf->lf_fd, cmd, fl) == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE, "fcntl failed");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloassert_write_locked_by(lockinfo_t *lf, pid_t pid)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello struct flock fl;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_WRLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_WRLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, pid, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_WRLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_OFD_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_WRLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, pid, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_RDLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_WRLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, pid, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_RDLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_OFD_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_WRLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, pid, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloassert_read_locked_by(lockinfo_t *lf, pid_t pid)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello struct flock fl;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_WRLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_RDLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, pid, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_WRLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_OFD_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_RDLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, pid, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_RDLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_UNLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, 0, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_RDLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_OFD_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_UNLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, 0, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloassert_unlocked(lockinfo_t *lf)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello struct flock fl;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_WRLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_UNLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, 0, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_WRLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_OFD_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_UNLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, 0, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_RDLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_UNLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, 0, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_reinit(&fl, F_RDLCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_fcntl(lf, F_OFD_GETLK, &fl);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_type, ==, F_UNLCK, short);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_sysid, ==, 0, int);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(fl.l_pid, ==, 0, pid_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloassert_all_unlocked(void)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_unlocked(&flock_fileA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_unlocked(&flock_fileB);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_unlocked(&flock_dirA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_unlocked(&flock_dirB);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic int
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_copyfil(lockinfo_t *src, lockinfo_t *dst)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello dst->lf_name = NULL;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello dst->lf_path = NULL;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if ((dst->lf_fd = open(src->lf_path, O_RDWR)) == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello warn("Failed to open %s", src->lf_path);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (-1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic int
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_mkfil(lockinfo_t *lf)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (asprintf(&lf->lf_path, LOCKFILE_FMT, lf->lf_name, getpid()) < 0) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello warnx("Failed to generate lockfile name");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (-1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if ((lf->lf_fd = open(lf->lf_path, O_RDWR|O_CREAT, 0600)) == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello warn("Failed to open %s", lf->lf_path);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (-1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic int
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_mkdir(lockinfo_t *lf)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (asprintf(&lf->lf_path, LOCKDIR_FMT, lf->lf_name, getpid()) < 0) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello warnx("Failed to generate lockfile name");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (-1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (mkdir(lf->lf_path, 0700) == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello warn("Failed to make %s", lf->lf_path);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (-1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if ((lf->lf_fd = open(lf->lf_path, O_RDONLY)) == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello warn("Failed to open %s", lf->lf_path);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (-1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_rminfo(lockinfo_t *lf)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (lf->lf_fd != -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello (void) close(lf->lf_fd);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (lf->lf_path != NULL) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello (void) unlink(lf->lf_path);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello free(lf->lf_path);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_run(lock_style_t style, boolean_t is_exclusive, lockinfo_t *lf,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello pid_t *pid, int fds[])
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello char *stylestr = flock_stylestr(style);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello char *modestr = is_exclusive ? "exclusive" : "shared";
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello char *argv[5] = { acqprog, stylestr, modestr, lf->lf_path, NULL };
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello int ret = pipe(fds);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (ret == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE, "pipe failed");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello *pid = fork();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (*pid == (pid_t)-1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE, "fork failed");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello } else if (*pid == (pid_t)0) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Set up pipe for communicating with child */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello ret = dup2(fds[1], 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (ret == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE, "dup2 failed");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello ret = dup2(fds[1], 1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (ret == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE, "dup2 failed");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello closefrom(3);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello (void) execv(acqprog, argv);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE, "Failed to execute %s", acqprog);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic int
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_wait(pid_t pid)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello int childstat = 0;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello while (waitpid(pid, &childstat, 0) == -1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (errno == EINTR)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello continue;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE, "Failed to wait on child");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (WIFEXITED(childstat)) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (WEXITSTATUS(childstat));
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello } else if (WIFSIGNALED(childstat)) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello } else {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello abort();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_cleanup_child(pid_t pid, int fds[])
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello (void) flock_wait(pid);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello (void) close(fds[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello (void) close(fds[1]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_test_upgrade_downgrade(void)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello lockinfo_t afd1, afd2, afd3;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello pid_t pid;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello int fds[2];
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock_copyfil(&flock_fileA, &afd1), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock_copyfil(&flock_fileA, &afd2), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock_copyfil(&flock_fileA, &afd3), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Acquiring shared locks 1, 2 and 3...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd1.lf_fd, LOCK_SH), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd2.lf_fd, LOCK_SH), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd3.lf_fd, LOCK_SH), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_read_locked_by(&flock_fileA, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Upgrading lock 3 should fail w/ EWOULDBLOCK...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd3.lf_fd, LOCK_EX|LOCK_NB), ==, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3U(errno, ==, EWOULDBLOCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_read_locked_by(&flock_fileA, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Upgrading 3 should succeed after releasing locks 1 & 2...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd1.lf_fd, LOCK_UN), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd2.lf_fd, LOCK_UN), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd3.lf_fd, LOCK_EX), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_write_locked_by(&flock_fileA, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Starting up child, then downgrading lock 3 to shared...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_run(LSTYLE_FLOCK, B_FALSE, &flock_fileA, &pid, fds);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(flock_nodata(fds[0]), ==, B_TRUE, boolean_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd3.lf_fd, LOCK_SH), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_block(fds[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_read_locked_by(&flock_fileA, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Releasing child and upgrading...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_alert(fds[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_cleanup_child(pid, fds);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_read_locked_by(&flock_fileA, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd3.lf_fd, LOCK_EX), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_write_locked_by(&flock_fileA, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Releasing lock 3...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd3.lf_fd, LOCK_UN), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&afd1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&afd2);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&afd3);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_all_unlocked();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_test_invalid(lockinfo_t *lf, int cmd, short l_type, short l_whence,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello off_t l_start, off_t l_len)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello struct flock fl = {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello .l_type = l_type,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello .l_whence = l_whence,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello .l_start = l_start,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello .l_len = l_len
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello };
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("fcntl(fd, %s, { %hd, %hd, %ld, %ld, ... })...",
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_cmdname(cmd), l_type, l_whence, l_start, l_len);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(fcntl(lf->lf_fd, cmd, &fl), ==, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3U(errno, ==, EINVAL);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_test_exclusive(lock_style_t styleA, lock_style_t styleB,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello lockinfo_t *lock1, lockinfo_t *lock2, boolean_t kill_firstborn)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello pid_t pidA, pidB;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello int fdsA[2], fdsB[2];
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Running %s + %s tests (%s)...",
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_stylename(styleA), flock_stylename(styleB),
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello kill_firstborn ? "kill child" : "child exits");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Create child, and wait for it to acquire the lock */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_run(styleA, B_TRUE, lock1, &pidA, fdsA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_block(fdsA[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Create second child, which shouldn't acquire & signal */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_run(styleB, B_TRUE, lock1, &pidB, fdsB);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3_IMPL(flock_nodata(fdsB[0]), ==, B_TRUE, boolean_t);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* lock1 is blocked for reading and writing */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_write_locked_by(lock1, styleA == LSTYLE_POSIX ? pidA : -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_unlocked(lock2);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Tell pidA to exit */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (kill_firstborn) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_kill(pidA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello } else {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_alert(fdsA[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_cleanup_child(pidA, fdsA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Wait for pidB to signal us */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_block(fdsB[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* lock1 is blocked for reading and writing */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_write_locked_by(lock1, styleB == LSTYLE_POSIX ? pidB : -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_unlocked(lock2);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Tell pidB to exit */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_alert(fdsB[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_cleanup_child(pidB, fdsB);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /*
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * Tests after child has released lock
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_all_unlocked();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_test_shared(lock_style_t styleA, lock_style_t styleB,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello lockinfo_t *lock1, lockinfo_t *lock2, boolean_t kill_firstborn)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello pid_t pidA, pidB;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello int fdsA[2], fdsB[2];
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Running %s + %s tests (%s)...",
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_stylename(styleA), flock_stylename(styleB),
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello kill_firstborn ? "kill child" : "child exits");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Create children, and wait for it to acquire the lock */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_run(styleB, B_FALSE, lock1, &pidB, fdsB);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_block(fdsB[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_run(styleA, B_FALSE, lock1, &pidA, fdsA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_block(fdsA[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* testfileA is only blocked for writing */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_read_locked_by(lock1, styleA == LSTYLE_POSIX ? pidA : -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_unlocked(lock2);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Tell pidA to exit */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (kill_firstborn) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_kill(pidA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello } else {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_alert(fdsA[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_cleanup_child(pidA, fdsA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* testfileA is still blocked for writing by pidB */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_read_locked_by(lock1, styleB == LSTYLE_POSIX ? pidB : -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_unlocked(lock2);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Tell pidB to exit */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_alert(fdsB[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_cleanup_child(pidB, fdsB);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_all_unlocked();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_test_ofd_sameproc(void)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello lockinfo_t afd1, afd2, afd3;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock_copyfil(&flock_fileA, &afd1), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock_copyfil(&flock_fileA, &afd2), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock_copyfil(&flock_fileA, &afd3), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Acquiring first two shared locks...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd1.lf_fd, LOCK_SH), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd2.lf_fd, LOCK_SH), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_read_locked_by(&flock_fileA, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Acquiring an exclusive lock should fail w/ EWOULDBLOCK...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd3.lf_fd, LOCK_EX|LOCK_NB), ==, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3U(errno, ==, EWOULDBLOCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Releasing to acquire an exclusive lock...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd1.lf_fd, LOCK_UN), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd2.lf_fd, LOCK_UN), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Acquiring an exclusive lock...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd3.lf_fd, LOCK_EX), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_write_locked_by(&flock_fileA, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Acquiring a shared lock should fail w/ EWOULDBLOCK...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd1.lf_fd, LOCK_EX|LOCK_NB), ==, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3U(errno, ==, EWOULDBLOCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd2.lf_fd, LOCK_EX|LOCK_NB), ==, -1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3U(errno, ==, EWOULDBLOCK);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("Releasing exclusive lock...");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello VERIFY3S(flock(afd3.lf_fd, LOCK_UN), ==, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello assert_all_unlocked();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log(" ok\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&afd1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&afd2);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&afd3);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellostatic void
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloflock_runtests(void)
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello lock_style_t first, second;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello int i;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("# Exclusive lock tests\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello for (first = (lock_style_t)0; first < LSTYLE_LAST; first++) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello for (second = (lock_style_t)0; second < LSTYLE_LAST; second++) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_exclusive(first, second,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello &flock_fileA, &flock_fileB, B_TRUE);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_exclusive(first, second,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello &flock_fileA, &flock_fileB, B_FALSE);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("# Shared lock tests\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello for (first = (lock_style_t)0; first < LSTYLE_LAST; first++) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello for (second = (lock_style_t)0; second < LSTYLE_LAST; second++) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_shared(first, second,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello &flock_fileA, &flock_fileB, B_TRUE);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_shared(first, second,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello &flock_fileA, &flock_fileB, B_FALSE);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("# flock(3C) directory lock tests\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_exclusive(LSTYLE_FLOCK, LSTYLE_FLOCK,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello &flock_dirA, &flock_dirB, B_TRUE);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_exclusive(LSTYLE_FLOCK, LSTYLE_FLOCK,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello &flock_dirA, &flock_dirB, B_FALSE);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_shared(LSTYLE_FLOCK, LSTYLE_FLOCK,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello &flock_dirA, &flock_dirB, B_TRUE);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_shared(LSTYLE_FLOCK, LSTYLE_FLOCK,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello &flock_dirA, &flock_dirB, B_FALSE);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("# Invalid fcntl(2) parameters tests\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello for (i = 0; i < sizeof (cmds) / sizeof (short); i++) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_invalid(&flock_fileA, cmds[i], 200, 0, 0, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_invalid(&flock_fileA, cmds[i], -1, 0, 0, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello for (i = 3; i < sizeof (cmds) / sizeof (short); i++) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_invalid(&flock_fileA, cmds[i], F_WRLCK, 1, 0, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_invalid(&flock_fileA, cmds[i], F_WRLCK, 0, 1, 0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_invalid(&flock_fileA, cmds[i], F_WRLCK, 0, 0, 1);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("# Testing that multiple OFD locks work in a process\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_ofd_sameproc();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_log("# Testing flock(3C) upgrade/downgrade tests\n");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_test_upgrade_downgrade();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Melloint
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellomain(int argc, char *argv[])
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello{
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello char *basestr, *suffix, *dirstr, *dirpath;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello pid_t testrunner;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello int exval;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello LOG = B_TRUE;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (argc < 1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello errx(EXIT_FAILURE, "Can't find program name!");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello dirstr = strdup(argv[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello dirpath = dirname(dirstr);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello basestr = strdup(argv[0]);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello suffix = basename(basestr);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello while (*suffix != '.' && *suffix != '\0') {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello suffix += 1;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (asprintf(&acqprog, "%s/acquire-lock%s", dirpath, suffix) < 0) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello errx(EXIT_FAILURE,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello "Can't generate lock acquisition program name!");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (access(acqprog, X_OK) != 0) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE,
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello "Can't run lock acquisition program %s", acqprog);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /* Create several lockfiles for testing */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (flock_mkfil(&flock_fileA) != 0 ||
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_mkfil(&flock_fileB) != 0 ||
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_mkdir(&flock_dirA) != 0 ||
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_mkdir(&flock_dirB) != 0) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello exval = 1;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello goto cleanup;
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello /*
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * We run the tests in a child process so that when tests fail
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello * we can still clean up our temporary files.
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello */
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello testrunner = fork();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello if (testrunner == (pid_t)-1) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello err(EXIT_FAILURE, "Unable to fork to run tests");
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello } else if (testrunner == (pid_t)0) {
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_runtests();
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (0);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello }
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello exval = flock_wait(testrunner);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mellocleanup:
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello free(basestr);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello free(dirstr);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&flock_fileA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&flock_fileB);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&flock_dirA);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello flock_rminfo(&flock_dirB);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello return (exval);
90221f9148b67fdc90178b67f9600b7bd4e3bc7cCody Peter Mello}