views:

259

answers:

5

I'm archiving a directory. This directory has a file that is being written by another process. When I tar this using Linux tar/Perl Tar module, in the archive the entry for the file is there but the contents are null.

Before tarring the files are...

-rw-r--r--  1 irraju dba 28 Feb 18 02:22 a
-rw-r--r--  1 irraju dba 25 Feb 18 02:23 b
-rw-r--r--  1 irraju dba 29 Feb 18 03:38 c

After untarring

-rw-r--r-- irraju/dba       28 2009-02-18 02:22:58 a
-rw-r--r-- irraju/dba       25 2009-02-18 02:23:17 b
-rw-r--r-- irraju/dba        0 2009-02-18 03:33:12 c

How can I fix this problem? I want the file to be in the archive with the contents it has at the instant it is archived. This file can be a log file and assume that we can not close the file handle before tarring.

+3  A: 

Try copying the files first...

cp a a.tmp
cp b b.tmp
cp c c.tmp

...then tarball everything together...

tar *.tmp abc.tar

...and clean up:

rm *.tmp

If that doesn't work then the process holding the file handle doesn't want to share read access...

John Leidegren
Copying the files before tar can be extremely expensive, especially if these are big files, or if there isn't enough room in the filesystem for a copy of all the files.
Tom Feiner
I'm thinking it's not going to be a problem, but I don't know everything, clearly you know what you're talking about. However, that copy thing, it's a neat trick.
John Leidegren
+2  A: 

You may find that this depends on the filesystem used and the application that is accessing the file. The closest to a generic solution is to use a filesystem that supports snapshots and create a snapshot before running tar.

Ronny Vindenes
+2  A: 

Your second output is made after your first, that can't be right. I'm guessing that tar is right here: when it was doing its job, the file was empty. You may be dealing with a race condition here.

Leon Timmermans
+4  A: 

As you tagged the question with "Linux" there's a chance you're using an LVM partition. If indeed you're running on an LVM partition, you can use the LVM snapshot feature.

Here's a link to the relevant LVM documentation on how to perform the operation.

Here's a part of the LVM snapshot intro:

A wonderful facility provided by LVM is 'snapshots'. This allows the administrator to create a new block device which presents an exact copy of a logical volume, frozen at some point in time. Typically this would be used when some batch processing, a backup for instance, needs to be performed on the logical volume, but you don't want to halt a live system that is changing the data. When the snapshot device has been finished with the system administrator can just remove the device. This facility does require that the snapshot be made at a time when the data on the logical volume is in a consistent state - the VFS-lock patch for LVM1 makes sure that some filesystems do this automatically when a snapshot is created, and many of the filesystems in the 2.6 kernel do this automatically when a snapshot is created without patching.

Tom Feiner
A: 

As others have said, it depends on the file system & OS being used. sync first (or whatever the equivalent is on your file system), copy the files to a temp directory and then tar them up. If the file system won't allow you to copy an opened file, then you're SOL; Perl can't get around file system limitations.

Joe Casadonte