Autodir and backup locks


Here is the example code to be used by recovery and backup programs.

For creating exclusive locks:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>

/*
 * name: 	name of the directory for which lockfile to be created
 * lockdir: 	base directory for creating lock files in it
 * strpid: 	pid of the process creating lock file in string format
 * spidlen: 	length of the string contained in strpid
 *
 * Return -1 if failed to create or else lockfile fd -- if successful.
 *
*/

int lockfile_create( const char *name, const char *lockdir,
                                  const char *strpid, int spidlen )

{
        int fd = -1;
        int i;
        char path[ PATH_MAX + 1 ];
        struct flock lk;
        struct stat st;

        if( ! name || ! *name )
        {
                fprintf( stderr, "lockfile_create: invalid name\n" );
                return -1;
        }

        snprintf( path, sizeof(path), "%s/%s.lock", lockdir, name );

        /*get exclusive lock and lock whole file*/
        lk.l_type = F_WRLCK;
        lk.l_start = 0;
        lk.l_whence = SEEK_SET;
        lk.l_len = 0;

        /*loop until we get rid of dead files*/
        for( i = 0 ; i < 10 ; i++ )
        {
                if( ( fd = open( path, O_RDWR | O_CREAT, 0644 ) ) == -1 )
                {
                        fprintf( stderr, "open %s: %s\n", path,
					strerror( errno ) );
                        return -1;
                }

		/*We get blocked here*/
                if( fcntl( fd, F_SETLKW, &lk ) == -1 )
                {
                        fprintf( stderr, "fcntl F_SETLKW %s: %s\n",
                                        path, strerror( errno ) );
                        close( fd );
                        return -1;
                }

                if( fstat( fd, &st ) )
                {
                        fprintf( stderr, "fstat %s: %s\n", path,
					strerror( errno ) );
                        close( fd );
                        return -1;
                }

                /*not dead file?*/
                if( st.st_nlink )
                        break;

                close(fd);
        }

        /*We do not operate on dead file whose hard link count is zero*/
        if( i >= 10 )
        {
                fprintf( stderr, "Giving up on dead file %s\n", path );
                return -1;
        }

        if( write( fd, strpid, spidlen ) == -1 )
        {
                fprintf( stderr, "write %s: %s\n", path,
					strerror( errno ) );
                unlink( path );
                close( fd );
                return -1;
        }

        return fd;
}

For removing exclusive locks.

/*
 * lock_file: path to the lock file.
 * lock_fd: lock file descriptor
 *
*/
static void lockfile_remove( const char *lock_file, int lock_fd )
{
        struct flock lk;

        /*unlock whole file*/
        lk.l_type = F_WRLCK;
        lk.l_start = 0;
        lk.l_whence = SEEK_SET;
        lk.l_len = 0;

        if( unlink( lock_file ) == -1 )
                fprintf( stderr, "unlink %s: %s\n", lock_file,
					strerror( errno ) );

        if( fcntl( lock_fd, F_UNLCK, &lk ) == -1 )
                fprintf( stderr, "fcntl F_UNLCK: %s: %s\n", lock_file,
					strerror( errno ) );

        close( lock_fd );
}

extralinux.com Logo SourceForge.net Logo