coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] tail should dereference watched file


From: Pádraig Brady
Subject: Re: [PATCH] tail should dereference watched file
Date: Fri, 22 Nov 2013 15:40:09 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130110 Thunderbird/17.0.2

On 11/22/2013 02:32 AM, Bernhard Voelker wrote:
> On 11/21/2013 06:01 PM, Pádraig Brady wrote:
>> On 09/16/2013 11:11 PM, Pádraig Brady wrote:
>>> On 09/15/2013 10:43 PM, Bernhard Voelker wrote:
>>>> On 09/15/2013 08:58 PM, Pádraig Brady wrote:
>>>>> True. Perhaps we should revert to polling for symlinks?
>>>>
>>>> That seems to be the safest way, yes.
>>>
>>> Though we'd have to be careful to handle the case
>>> where a file was replaced with a symlink.
>>
>> Hopefully the attached fixes up the common case of this,
>> and diagnose the edge case where a (missing) file appears
>> as a symlink, during inotify processing.
> 
> Hi Padraig,
> 
> Thanks for continue working on this - I almost forgot it.
> 
> The first part is minor nits in the test suite:
> 
>> --- /dev/null
>> +++ b/tests/tail-2/symlink.sh
> 
>> +
>> +# Ensure changing targets of cli specified symlinks are handled
> 
> s/$/./
> 
>> +# Prior to v8.22, inotify would fail to recognize changes in the targets
> 
> s/$/./
> 
>> +# Clear 'out' so that we can check its contents without races
> 
> s/$/./
> 
>> +:>out                           || framework_failure_
>> +ln -nsf target symlink          || framework_failure_
>> +timeout 10 tail -s.1 -F symlink >out 2>&1 & pid=$!
>> +retry_delay_ wait4lines_ .1 6 1 || fail=1  # Wait for "cannot open..."
>> +echo "X" > target               || fail=1
>> +retry_delay_ wait4lines_ .1 6 3 || fail=1  # Wait for the expected output.
>> +kill $pid
>> +wait $pid
>> +# Expect 3 lines in the output file.
>> +[ $( wc -l < out ) = 3 ]   || { fail=1; cat out; }
>> +grep -F 'cannot open' out  || { fail=1; cat out; }
>> +grep -F 'has appeared' out || { fail=1; cat out; }
>> +grep '^X$' out             || { fail=1; cat out; }
>> +rm -f target out           || framework_failure_
> 
> Looks good.
> 
>> +
>> +# Ensure we correctly handle the source symlink itself changing.
>> +# I.E. that we don't operate solely on the targets.
>> +# Clear 'out' so that we can check its contents without races
>> +:>out                           || framework_failure_
>> +touch target1                   || framework_failure_
> 
> Why not use ":>target1" here, too? ... or alternatively move
> the 'echo "X1" > target1' from 3 lines below to here?
> 
>> +ln -nsf target1 symlink         || framework_failure_
>> +timeout 10 tail -s.1 -F symlink >out 2>&1 & pid=$!
>> +echo "X1" > target1
>> +retry_delay_ wait4lines_ .1 6 1 || fail=1  # Wait for the expected output.
>> +ln -nsf target2 symlink         || framework_failure_
>> +retry_delay_ wait4lines_ .1 6 2 || fail=1  # Wait for "become inaccess..."
>> +echo "X2" > target2             || fail=1
>> +retry_delay_ wait4lines_ .1 6 4 || fail=1  # Wait for the expected output.
>> +kill $pid
>> +wait $pid
>> +# Expect 3 lines in the output file.
> 
> s/3/4/ ;-)
> 
>> +[ $( wc -l < out ) = 4 ]   || { fail=1; cat out; }
>> +grep -F 'become inaccessible' out  || { fail=1; cat out; }
>> +grep -F 'has appeared' out || { fail=1; cat out; }
>> +grep '^X[12]$' out             || { fail=1; cat out; }
> 
> Better to test for X1 and X2 separately, to avoid eclipsing to determine
> when one of the above wait4lines_ call ran into a timeout.
> 
> 
>> +rm -f target1 target2 out  || framework_failure_
>> +
>> +# Note other symlink edge cases are currently just diagnosed
>> +# rather than being handled. I.E. if you specify a missing item,
>> +# or existing file that later change to a symlink, if inotify
>> +# is in use, you'll get a diagnostic saying that link will
>> +# no longer be tailed.
>> +
>> +Exit $fail
> 
> 
> Now regarding the functionality change:
> I can't say what it is, but the previous behavior was somehow
> better in certain cases [*].
> 
> Compare the output of
>   tail -F -s1 symlink
> for the old (413a2415) and new program when executing the following
> in a 3rd terminal.
> 
> Preparation:
> 
>   echo X > target1
>   echo Y > target2
>   ln -nsf target1 symlink
> 
> Now start both tail-{old,new} and do the following:
> 
>   ln -nsf target2 symlink
>   ln -nsf target1 symlink
>   ln -nsf target2 symlink
>   rm symlink
>   mkdir symlink
>   rmdir symlink
>   ln -nsf target1 symlink
>   ln -nsf target2 symlink
>   rm symlink
>   echo Z > symlink
> 
> I didn't dig into what's going on, but from a certain
> point on, tail-new doesn't output anything anymore.
> Can you reproduce this?

So what's going on here is that in poll mode
we don't notice changes to the "symlink" name
after we give up on it.

So I suppose you could consider this a
limitation of poll mode but it is diagnosed
and a far out edge case.

You can get old and new to behave the same
for confirmation by running both with:

  tail -F -s.1 ---dis symlink

thanks,
Pádraig.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]