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