One method to create locks is to use 'mkdir' within an 'if' statement (something
like):
if mkdir lockdir 2>/dev/null
then
    echo lock created
else
    echo lock no created
fi

You can also use the same technique with a 'while' (but you should put a sleep
within the loop).

To, unlock, just 'rmdir lockdir'.

You can put these statements within any (bourne or korn) shell script you'd
like.

Noel




[EMAIL PROTECTED] on 2000.07.07 17:04:24

Please respond to [EMAIL PROTECTED]

To:   [EMAIL PROTECTED]
cc:   (bcc: Noel L Yap)
Subject:  locking with rsync




Hello,

First, thanks for rsync.  I'm planning on using it to
keep large subdirectories of two web servers synchronized,
and it sure will be cheaper than fancy redundant storage.
It will also keep down our traffic, of course, which will
save us money, too.  So thanks again.

Towards that end, I need to get rsync to cooperate with
a perl script.  The perl script may attempt to update a file at the
same time that rsync is trying to read from it or write
to it.  Since I am the author of the perl script, I am trying
to adapt my script to rsync rather than the reverse.

I wrote a short perl script to figure out how to go about it.
The test script uses fcntl locking.  But even though the destination
(a single file) of the rsync copy is locked, rsync ignores
the lock and overwrites the contents file.  I chose fcntl because that I

found it used in util.c and mentioned in the rsync documentation.
However, my C skills are not good enough to decipher the
rsync source as a whole.  I've also never used fcntl or similar
locking before and the topic in general is new to me.

So I can't tell whether the behavior is because of a problem with
the way I am locking the destination file, a feature in
perl or rsync, or a bug somewhere.

I did test my perl script to be sure it respects its own
locking.  This makes me think I'm doing the locking correctly.

I am using:
  rsync-2.4.1-2 installed from an rpm.
  perl-5.00503-10 installed from an rpm.
  red hat linux 6.2 on i386

Thanks,
Olaf

==================================================================
Gory Details:

Here is my script and the testing I have done.  If there
is something else I should look for or do, tell me and I'll
do it and reply.

When the perl script is invoked, it locks the file
/home/olaf/junk/test.out, then checks whether it
was passed an argument.  If so it sleeps for 10 sec.
Then it unlocks the file and exits.

To test rsync I do:

  olaf 09:50:12 > ./lock_file.pl sleep &
  olaf 09:50:13 > rsync t1 test.out
  olaf 09:50:14 >

rsync copies t1 to test.out (overwriting test.out) and
returns immediately, even though lock_file.pl has locked test.out.

To test my perl script I do:

  olaf 09:48:47 > ./lock_file.pl sleep >> lock.log  &
  olaf 09:48:49 > ./lock_file.pl  >> lock.log &
  olaf 09:48:57 >

lock.log contains:

  (./lock_file.pl sleep)  run at 9:48:47
  Process 752 locking file...  Fri Jul  7 09:48:47 PDT 2000
  Process 752 got lock...      Fri Jul  7 09:48:47 PDT 2000
  Process 752 sleeping ...     Fri Jul  7 09:48:47 PDT 2000
  Process 752 unlocking file...Fri Jul  7 09:48:57 PDT 2000

  (./lock_file.pl)        run at 9:48:49
  Process 756 locking file...  Fri Jul  7 09:48:49 PDT 2000
  Process 756 got lock...      Fri Jul  7 09:48:57 PDT 2000
  Process 756 unlocking file...Fri Jul  7 09:48:57 PDT 2000

Note that the second process, 756, doesn't actually get the
lock until 9:48:57, when the first process releases it.  That
is how I know the lock is taking effect.

lock_file.pl is listed below:

----------- cut here --------------------
#!/usr/bin/perl -w

open(TEST, ">>/home/olaf/junk/test.out");
my $old = select(TEST); $| = 1;
select($old);       $| = 1;

print "Process $$ locking file...  ",`date`;
of_lock(TEST,"lock");
seek(TEST, 0, 2);

print  "Process $$ got lock...  ",`date`;
print TEST "Hi There I am $$\n\n";
if (@ARGV > 0) {
          print  "Process $$ sleeping ...     ",`date`;
          sleep 10;
}

print "Process $$ unlocking file...",`date`;
of_lock(TEST,"unlock");
close(TEST);

# Subroutines

sub of_lock
{
     #usage: of_lock(TEST,"unlock");
     my ($fh, $request) = @_;
     my $action;

     use Fcntl;          # import all Fcntl constants

     #for some reason 'use Fcntl' does not get SEEK #defines
     my $SEEK_SET = 0;       # Seek from beginning of file.
     my $SEEK_CUR = 1;       # Seek from current position.
     my $SEEK_END = 2 ;      # Seek from end of file.

     ## example from rsync
     #struct flock lock;
     #lock.l_type = F_WRLCK;
     #lock.l_whence = $SEEK_SET;
     #lock.l_start = offset;
     #lock.l_len = len;
     #lock.l_pid = 0;

     if ($request eq "lock") { $action = Fcntl::F_WRLCK }
     else           { $action = Fcntl::F_UNLCK }

     my $fcntl_args_t = "sslli";  # two shorts, two longs, one int
     my @fcntl_args = ( $action , $SEEK_SET, 0,1,0);
     my $fcntl_args = pack($fcntl_args_t,@fcntl_args);

     fcntl( $fh, F_SETLKW, $fcntl_args ) || die "Lock failed: $!";
}
----------- cut here --------------------


Olaf Faaland
Manager - Technical Support
======================================
Sovran Inc.    voice:  510-645-9377
155 Filbert Suite 102    email: [EMAIL PROTECTED]
Oakland, CA 94607   fax:     510-645-9379








This communication is for informational purposes only.  It is not intended as
an offer or solicitation for the purchase or sale of any financial instrument
or as an official confirmation of any transaction. All market prices, data
and other information are not warranted as to completeness or accuracy and
are subject to change without notice. Any comments or statements made herein
do not necessarily reflect those of J.P. Morgan & Co. Incorporated, its
subsidiaries and affiliates.

Reply via email to