Flock in suse is not same as fedora. Exclusive lock is grated across same parent child processes.
what I want is no matter who is flock calling (parent child or some relative :)) it should not give flock (exclusive) to caller if ANY other process is holding lock in ex mode. same as fedora behaves. I had written some program which works on fedora but not on SEL11sp1. question is what I need to do to get expected result.
my_flock.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#define ERR_EXIT_INVALID_INPUT 1
#define ERR_INVALID_FILE 2
#define ERR_INVALID_FD 3
#define ERR_FCNTL_FAILED 4
#define ERR_FLOCK_FAILED 5
#define Log(format, arg...) \
do { \
fprintf(stderr,"%s,%s,%d: " format "
",program, __FUNCTION__,__LINE__, ##arg); \
} while (0)
static char *program = NULL;
static int type = -1;
static int type2 = -1;
static int fd = -1;
static char *file_name = NULL;
static void print_usage(int exit_code)
{
fprintf(stderr,"%s (non blocking only)
",program);
fprintf(stderr,"Usage : %s -sxu] -f] filename
",program);
fprintf(stderr," %s -sxu] -d] file descriptor
",program);
fprintf(stderr," %s -h help
",program);
exit(exit_code);
}
static void parse_args(int argc,char *argv])
{
int op;
optopt = 0;
program = argv[0];
if(argc < 2)
print_usage(ERR_EXIT_INVALID_INPUT);
while((op = getopt(argc,argv,"sxuf:d:h?")) != -1)
{
switch(op)
{
case 's':
if(type != -1) print_usage(ERR_EXIT_INVALID_INPUT);
type = F_RDLCK;
type2 = LOCK_SH|LOCK_NB;
break;
case 'x':
if(type != -1) print_usage(ERR_EXIT_INVALID_INPUT);
type = F_WRLCK;
type2 = LOCK_EX|LOCK_NB;
break;
case 'u':
if(type != -1) print_usage(ERR_EXIT_INVALID_INPUT);
type = F_ULOCK;
type2 = LOCK_UN;
break;
case 'f':
if(file_name != NULL) print_usage(ERR_EXIT_INVALID_INPUT);
file_name = optarg;
break;
case 'd':
if(fd != -1) print_usage(ERR_EXIT_INVALID_INPUT);
fd = atoi(optarg);
break;
default:
print_usage(optopt ? ERR_EXIT_INVALID_INPUT : 0);
}
}
if((type == -1) || ((file_name == NULL) && (fd == -1)))
print_usage(ERR_EXIT_INVALID_INPUT);
if((file_name != NULL) && (fd != -1))
print_usage(ERR_EXIT_INVALID_INPUT);
if(file_name)
{
fd = open(file_name,O_CREAT|O_RDWR|O_SYNC,S_IRWXU|S_IXGRP|S_IRGRP|S_IROTH);
if(fd < 0)
{
perror("File open failed");
exit(ERR_INVALID_FILE);
}
}
}
int main(int argc,char *argv])
{
struct flock stflock = {0};
parse_args(argc,argv);
if(type != F_ULOCK)
{
stflock.l_type = type;
stflock.l_whence = SEEK_SET;
stflock.l_start = 0;
stflock.l_len = 10;
if(fcntl(fd,F_SETLK,&stflock) == -1)
{
Log("SYNC Lock Failed: %s",strerror(errno));
exit(ERR_FCNTL_FAILED);
}
//Log("First lock success sleep 10");
//sleep(10);
}
if(flock(fd,type2))
{
Log("flock Failed: %s",strerror(errno));
exit(ERR_FLOCK_FAILED);
}
exit(0);
return 0;
}
fcntl lock is just added for testing, any way it will not allow 2 live process to execute flock at same moment. (I will remove it later)
Test Script
#!/bin/bash
LN_SYNC_LOCKFILE="/tmp/tushar.lock"
function check_fd_open
{
ls "/proc/$$/fd/210" &> /dev/null &&
{
echo "$$ : FD is already open"
return 0
}
echo "$$ : FD not open"
return 1
}
function my_lock
{
if ls "/proc/$$/fd/210" &> /dev/null
then
echo "$$ : Failed to get lock parent process tree is holding lock"
#exit 1
#return 1
fi
echo "Calling lock from script"
exec 210>$LN_SYNC_LOCKFILE
./my_lock -x -d 210
if $? -ne 0 ]
then
echo "Calling lock from script FAILED"
exit 1
return 1
fi
echo "Calling lock from script SUCCESS"
return 0
}
function my_unlock
{
echo "Calling unlock from script"
./my_lock -u -d 210
if $? -eq 0 ]
then
echo "Calling unlock from script SUCCESS"
else
echo "Calling unlock from script FAILED"
fi
rm -f $LN_SYNC_LOCKFILE
}
echo "$$ : Taking lock"
my_lock $LN_SYNC_LOCKFILE
echo "$$ : Success"
sleep 10
echo "Forking myself"
"./test.sh"
echo "$$ : Releasing lock"
my_unlock
echo "$$ : Success"
exit 0
Please help me.