Question

I am struggling to understand what is going on in a test I am running. Test is two shell scripts running on the same machine.

A:

    #!/bin/bash
    touch target;
    for ((i=0; i < 1000; i=i+1)); do
        echo "snafu$i" > $1/file$i;
        mv -f $1/file$i $1/target; 
    done; 

B:

    #!/bin/bash
    while(true);do 
        cat $1/target; 
    done

So I run A /ext3_dir, then run B /ext3_dir > out (so only errors go to std out).

This all works fine and as expected according to the POSIX spec for 'rename':

If the link named by the new argument exists, it shall be removed and old renamed to new. In this case, a link named new shall remain visible to other processes throughout the renaming operation and refer either to the file referred to by new or old before the operation began.

However if I add a hard-link to the temporary file before doing the move:

    #!/bin/bash
    touch target;
    for ((i=0; i < 1000; i=i+1)); do
        echo "snafu$i" > $1/file$i;
        ln $1/file$i $1/link$i
        mv -f $1/file$i $1/target; 
    done; 

I get "No such file or directory" errors on the reading side - seemingly in contravention of the POSIX spec.

Can anyone shed any light on this behaviour? Is the test valid? I can't figure out why creating an extra link to the file I'm moving should impact the ability to read from the move destination.

Was it helpful?

Solution

It turns out this was a known problem on some redhat versions:

https://bugzilla.redhat.com/show_bug.cgi?id=438076

OTHER TIPS

I have run it on Debian, and it worked fine on EXT3 file system. I see nothing here that should not work. I rewrote the loop for SH shell, to test it with a minimal script.

#!/bin/sh
    touch target
    for i in $(seq 1 999) do
            echo "snafu$i" > $1/file$i;
            ln $1/file$i $1/link$i
            mv -f $1/file$i $1/target
    done

Anyway, that touch target shouldn't be touch $1/target?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top