An open file handle is a link; when creating a file with open you actually have 
two links to the file - one for the directory's link to it, and one for the 
process's link to it.

Therefore unlinking the file from the file system simply reduces its link count 
to 1, and it will stay around, writable on disk but not in any directories, 
until it is closed, at which time it will automatically disappear.  

This is great for temporary files because you can take care of the extra 
directory entry right up front, no cleanup special required beyond closing the 
filehandle.

I don't believe that the problem you are having is that the file is unlinked 
from the filesystem.  That would not stop it from being writable.  The problem 
may be that the file is inappropriately closed later before its fseek'd back to 
the beginning to operate on the temp contents, thus causing it to really 
disappear.

David


-----Original Message-----
From: mjurgens [mailto:mjurg...@edcint.co.nz] 
Sent: Tuesday, March 30, 2010 12:08 AM
To: modperl@perl.apache.org
Subject: Intermittent File Upload Failures - CGI tmpfile unlinked


I need some help trying to work out why CGI.pm (guessing at the module)
appears to unlink a temporary file just after opening it and before writing
some uploaded file content to it.

I use <input type=file> in a form which I POST to a modperl Apache server
(version 2.2.14) on Fedora 10.
Intermittently the perl script is unable to access the CGItemp file. Here's
what I have found:

A network/packet trace shows the correct transmission of the HTTP and file
each time.

A Data::Dumper of the CGI variable instance shows the form variable has been
set to a file handle like this
'config_file' => [
$VAR1->{'.tmpfiles'}{'*Fh::fh00013Smartmon_Initial_Config_Export.txt'}{'hndl'}
]

However when the program goes to access the temporary file eg
/usr/tmp/45632, it does not exist.
I started printing the httpd PID in the HTTP output and found that some of
the processes consistently failed and others would consistently work. 

I ran an strace on each of the httpd processes (running with 5 children) and
found that the failing processes would unlink the CGItemp file just after
opening it - so this is why it is unavailable to the perl script later on. A
good processes would open the CGItemp file and then start writing to it.

GOOD PROCESS (strace output):
-------------------------------
open("/usr/tmp/CGItemp45478", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 22
ioctl(22, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfcc4e08) = -1 ENOTTY
(Inappropriate ioctl for device)
_llseek(22, 0, [0], SEEK_CUR)           = 0
fstat64(22, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fcntl64(22, F_SETFD, FD_CLOEXEC)        = 0
write(22, "[MonsvrConfig]\r\nmonsvr_protocol="..., 3464) = 3464

BAD PROCESS (strace output):
-----------------------------
open("/usr/tmp/CGItemp45481", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 21
ioctl(21, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfcc4e08) = -1 ENOTTY
(Inappropriate ioctl for device)
_llseek(21, 0, [0], SEEK_CUR)           = 0
fstat64(21, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fcntl64(21, F_SETFD, FD_CLOEXEC)        = 0
unlink("/usr/tmp/CGItemp45481")         = 0

Why does it get unlinked just after opening and before the uploaded content
can be written to it?
-- 
View this message in context: 
http://old.nabble.com/Intermittent-File-Upload-Failures---CGI-tmpfile-unlinked-tp28078476p28078476.html
Sent from the mod_perl - General mailing list archive at Nabble.com.

Reply via email to