Getting flock(2) working across parent and child process sle11sp1

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.

While neither C nor bash are very much dependant on the OS you use and thus sound advice may come forward, I nevertheless want to point you to the fact that these are the openSUSE forums. When you say “sle11sp1"” in your title, I assume you mean SLED/S SP 1, which are not openSUSE and have their own forums at SUSE Forums

Same thing works as expected in openSuse.
SuSE-release: openSUSE 11.4 (x86_64) VERSION = 11.4 CODENAME = Celadon

Thanks for reply I will look in respective forums.