Bug 811976

Summary: [6a995ab3300a5ee0ee79a4d7d75281a79deec96e] zero byte files when a file is replaced with the same string in a loop
Product: [Community] GlusterFS Reporter: Anush Shetty <ashetty>
Component: quick-readAssignee: Raghavendra G <rgowdapp>
Status: CLOSED CURRENTRELEASE QA Contact:
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: mainlineCC: gluster-bugs, rfortier, shaines
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: glusterfs-3.4.0 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-07-24 17:42:03 UTC Type: Bug
Regression: --- Mount Type: fuse
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 817967    

Description Anush Shetty 2012-04-12 12:50:58 UTC
Description of problem: When the contents in a file was replaced with the same string using perl script, it resulted in a zero byte file after a few iterations

Version-Release number of selected component (if applicable): Upstream


How reproducible: Consistently


Steps to Reproduce:
1. echo 'test' > dot
2. while true; do perl -i -pe 's/test/test/' dot; done
3. cat dot
  
Actual results: Returns ENOENT

# ls -lh dot
-rw-r--r-- 1 root root 0 2012-04-12 18:19 dot


Additional info:

This issue was not seen when quick-read was disabled.

Comment 1 Raghavendra G 2012-04-14 14:07:47 UTC
This is most likely not a bug. Following is the strace output of perl string replacement in action:

17197 open("file", O_RDONLY)            = 3
17197 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffb4696cd8) = -1 ENOSYS (Function not implemented)
17197 lseek(3, 0, SEEK_CUR)             = 0
17197 fstat(3, {st_mode=S_IFREG|0600, st_size=5, ...}) = 0
17197 fcntl(3, F_SETFD, FD_CLOEXEC)     = 0
17197 unlink("file")                    = 0
17197 open("file", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
17197 ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffb4696cd8) = -1 ENOSYS (Function not implemented)
17197 lseek(4, 0, SEEK_CUR)             = 0
17197 fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
17197 fcntl(4, F_SETFD, FD_CLOEXEC)     = 0
17197 fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
17197 fchmod(4, 0100600)                = 0
17197 read(3, "test\n", 4096)           = 5
17197 read(3, "", 4096)                 = 0
17197 write(4, "test\n", 5)             = 5
17197 close(4)                          = 0
17197 close(3)                          = 0

As can be seen, original file is unlinked and a new file is created and original file content after replacement is written into new file. However if the perl is interrupted between the window where a new file is created and content is written to it, we might see a file with no content. I am assuming that this is what has happened in this case. 

Anush,

Are you sure that you interrupted the infinite loop doing string replacement only after perl completes its execution?

regards,
Raghavendra

Comment 2 Anush Shetty 2012-04-15 02:50:20 UTC
I didn't interrupt the infinite loop in which the perl script was being executed. The perl script errored out with ENOENT after a while. When I checked the size, it was zero bytes.

Comment 3 Anand Avati 2012-04-18 07:00:28 UTC
CHANGE: http://review.gluster.com/3151 (performance/quick-read: disable reading from cache if unlink has happened after fd was opened.) merged in master by Vijay Bellur (vijay)

Comment 4 Anush Shetty 2012-04-18 12:00:48 UTC
Verified with 7ef32ae76d1c1e4a5ff47899d175be9fdeb73bc8. Don't see this issue now.