From: Masatake YAMATO Date: Tue, 4 Jul 2023 16:58:24 +0000 (+0900) Subject: test: (mkfds::make-regular-file) add a parameter for file locking X-Git-Tag: v2.40-rc1~345^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3e451d006ff356adfa129d6ce4544da13ccb1058;p=thirdparty%2Futil-linux.git test: (mkfds::make-regular-file) add a parameter for file locking Signed-off-by: Masatake YAMATO --- diff --git a/tests/helpers/test_mkfds.c b/tests/helpers/test_mkfds.c index a71eaea68f..d17e6f7cf9 100644 --- a/tests/helpers/test_mkfds.c +++ b/tests/helpers/test_mkfds.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -390,6 +391,190 @@ static void unlink_and_close_fdesc(int fd, void *data) close(fd); } +typedef void (*lockFn)(int fd, const char *fname); + +static void lock_fn_none(int fd _U_, const char *fname _U_) +{ + /* Do nothing */ +} + +static void lock_fn_flock_sh(int fd, const char *fname) +{ + if (flock(fd, LOCK_SH) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock"); + } +} + +static void lock_fn_flock_ex(int fd, const char *fname) +{ + if (flock(fd, LOCK_EX) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock"); + } +} + +static void lock_fn_posix_r_(int fd, const char *fname) +{ + struct flock r = { + .l_type = F_RDLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 1, + }; + if (fcntl(fd, F_SETLK, &r) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock"); + } +} + +static void lock_fn_posix__w(int fd, const char *fname) +{ + struct flock w = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 1, + }; + if (fcntl(fd, F_SETLK, &w) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock"); + } +} + +static void lock_fn_posix_rw(int fd, const char *fname) +{ + struct flock r = { + .l_type = F_RDLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 1, + }; + struct flock w = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 2, + .l_len = 1, + }; + if (fcntl(fd, F_SETLK, &r) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock(read)"); + } + if (fcntl(fd, F_SETLK, &w) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock(write)"); + } +} + +static void lock_fn_ofd_r_(int fd, const char *fname) +{ + struct flock r = { + .l_type = F_RDLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 1, + .l_pid = 0, + }; + if (fcntl(fd, F_OFD_SETLK, &r) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock"); + } +} + +static void lock_fn_ofd__w(int fd, const char *fname) +{ + struct flock w = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 1, + .l_pid = 0, + }; + if (fcntl(fd, F_OFD_SETLK, &w) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock"); + } +} + +static void lock_fn_ofd_rw(int fd, const char *fname) +{ + struct flock r = { + .l_type = F_RDLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 1, + .l_pid = 0, + }; + struct flock w = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 2, + .l_len = 1, + .l_pid = 0, + }; + if (fcntl(fd, F_OFD_SETLK, &r) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock(read)"); + } + if (fcntl(fd, F_OFD_SETLK, &w) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to lock(write)"); + } +} + +static void lock_fn_lease_w(int fd, const char *fname) +{ + if (fcntl(fd, F_SETLEASE, F_WRLCK) < 0) { + int e = errno; + close(fd); + if (fname) + unlink(fname); + errno = e; + err(EXIT_FAILURE, "failed to take out a write lease"); + } +} + + static void *make_w_regular_file(const struct factory *factory, struct fdesc fdescs[], int argc, char ** argv) { @@ -407,9 +592,53 @@ static void *make_w_regular_file(const struct factory *factory, struct fdesc fde struct arg readable = decode_arg("readable", factory->params, argc, argv); bool bReadable = ARG_BOOLEAN(readable); + struct arg lock = decode_arg("lock", factory->params, argc, argv); + const char *sLock = ARG_STRING(lock); + lockFn lock_fn; + if (iWrite_bytes < 0) - err(EXIT_FAILURE, "write-bytes must be a positive number or zero."); + errx(EXIT_FAILURE, "write-bytes must be a positive number or zero."); + + if (strcmp(sLock, "none") == 0) + lock_fn = lock_fn_none; + else if (strcmp(sLock, "flock-sh") == 0) + lock_fn = lock_fn_flock_sh; + else if (strcmp(sLock, "flock-ex") == 0) + lock_fn = lock_fn_flock_ex; + else if (strcmp(sLock, "posix-r-") == 0) { + bReadable = true; + if (iWrite_bytes < 1) + iWrite_bytes = 1; + lock_fn = lock_fn_posix_r_; + } else if (strcmp(sLock, "posix--w") == 0) { + if (iWrite_bytes < 1) + iWrite_bytes = 1; + lock_fn = lock_fn_posix__w; + } else if (strcmp(sLock, "posix-rw") == 0) { + bReadable = true; + if (iWrite_bytes < 3) + iWrite_bytes = 3; + lock_fn = lock_fn_posix_rw; + } else if (strcmp(sLock, "ofd-r-") == 0) { + bReadable = true; + if (iWrite_bytes < 1) + iWrite_bytes = 1; + lock_fn = lock_fn_ofd_r_; + } else if (strcmp(sLock, "ofd--w") == 0) { + if (iWrite_bytes < 1) + iWrite_bytes = 1; + lock_fn = lock_fn_ofd__w; + } else if (strcmp(sLock, "ofd-rw") == 0) { + bReadable = true; + if (iWrite_bytes < 3) + iWrite_bytes = 3; + lock_fn = lock_fn_ofd_rw; + } else if (strcmp(sLock, "lease-w") == 0) + lock_fn = lock_fn_lease_w; + else + errx(EXIT_FAILURE, "unexpected value for lock parameter: %s", sLock); + free_arg(&lock); free_arg(&readable); free_arg(&write_bytes); free_arg(&delete); @@ -454,6 +683,8 @@ static void *make_w_regular_file(const struct factory *factory, struct fdesc fde } } + lock_fn(fd, fname); + fdescs[0] = (struct fdesc){ .fd = fdescs[0].fd, .close = bDelete? close_fdesc: unlink_and_close_fdesc, @@ -2661,6 +2892,12 @@ static const struct factory factories[] = { .desc = "open the new file readable way", .defv.string = false, }, + { + .name = "lock", + .type = PTYPE_STRING, + .desc = "the way for file locking: [none]|flock-sh|flock-ex|posix-r-|posix--w|posix-rw|ofd-r-|ofd--w|ofd-rw|lease-w", + .defv.string = "none", + }, PARAM_END }, },