mirror of
https://github.com/samba-team/samba.git
synced 2025-02-26 21:57:41 +03:00
utils🏓 add a -c switch to check the lock before reading/writing
This is to verify that the fcntl F_GETLK call reports F_UNLCK if called from a process already holding a lock. This is for example used by samba's strict locking code in combination with "posix locking = true". Signed-off-by: Michael Adam <obnox@samba.org> (This used to be ctdb commit 4f42d17b74ce891691eee1cead498959cc8e4837)
This commit is contained in:
parent
8732e2356f
commit
05cf7bce49
@ -2,6 +2,7 @@
|
||||
A ping-pong fcntl byte range lock test
|
||||
|
||||
Copyright (C) Andrew Tridgell 2002
|
||||
Copyright (C) Michael Adam 2012
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -41,7 +42,7 @@
|
||||
|
||||
static struct timeval tp1,tp2;
|
||||
|
||||
static int do_reads, do_writes, use_mmap;
|
||||
static int do_reads, do_writes, use_mmap, do_check;
|
||||
|
||||
static void start_timer(void)
|
||||
{
|
||||
@ -69,6 +70,36 @@ static int lock_range(int fd, int offset, int len)
|
||||
return fcntl(fd,F_SETLKW,&lock);
|
||||
}
|
||||
|
||||
/* check whether we could place a lock */
|
||||
int check_lock(int fd, int offset, int len)
|
||||
{
|
||||
struct flock lock;
|
||||
int ret;
|
||||
|
||||
lock.l_type = F_WRLCK;
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = offset;
|
||||
lock.l_len = len;
|
||||
lock.l_pid = 0;
|
||||
|
||||
ret = fcntl(fd, F_GETLK, &lock);
|
||||
if (ret != 0) {
|
||||
printf("error calling fcntl F_GETLCK: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lock.l_type == F_UNLCK) {
|
||||
/* we would be able to place the lock */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we would not be able to place lock */
|
||||
printf("check_lock failed: lock held: "
|
||||
"pid='%d', type='%d', start='%d', len='%d'\n",
|
||||
(int)lock.l_pid, (int)lock.l_type, (int)lock.l_start, (int)lock.l_len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* unlock a byte range in a open file */
|
||||
static int unlock_range(int fd, int offset, int len)
|
||||
{
|
||||
@ -123,6 +154,9 @@ static void ping_pong(int fd, int num_locks)
|
||||
printf("lock at %d failed! - %s\n",
|
||||
(i+1) % num_locks, strerror(errno));
|
||||
}
|
||||
if (do_check) {
|
||||
ret = check_lock(fd, i, 1);
|
||||
}
|
||||
if (do_reads) {
|
||||
unsigned char c;
|
||||
if (use_mmap) {
|
||||
@ -169,7 +203,7 @@ int main(int argc, char *argv[])
|
||||
int fd, num_locks;
|
||||
int c;
|
||||
|
||||
while ((c = getopt(argc, argv, "rwm")) != -1) {
|
||||
while ((c = getopt(argc, argv, "rwmc")) != -1) {
|
||||
switch (c){
|
||||
case 'w':
|
||||
do_writes = 1;
|
||||
@ -180,6 +214,9 @@ int main(int argc, char *argv[])
|
||||
case 'm':
|
||||
use_mmap = 1;
|
||||
break;
|
||||
case 'c':
|
||||
do_check = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown option '%c'\n", c);
|
||||
exit(1);
|
||||
@ -194,6 +231,7 @@ int main(int argc, char *argv[])
|
||||
printf(" -r do reads\n");
|
||||
printf(" -w do writes\n");
|
||||
printf(" -m use mmap\n");
|
||||
printf(" -c check locks\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user