Results 1 to 3 of 3

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

  1. #1

    Default 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
    Code:
    #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 "\n",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)\n",program);
    	fprintf(stderr,"Usage : %s [-sxu] [-f] filename\n",program);
    	fprintf(stderr,"        %s [-sxu] [-d] file descriptor\n",program);
    	fprintf(stderr,"        %s -h help\n",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
    Code:
    #!/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.

  2. #2
    Join Date
    Jun 2008
    Location
    Netherlands
    Posts
    16,048

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

    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
    Henk van Velden

  3. #3

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

    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.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •