[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#26363: [PATCH] tail: 'tail -F dir/file' reverts to polling mode if '
From: |
Pádraig Brady |
Subject: |
bug#26363: [PATCH] tail: 'tail -F dir/file' reverts to polling mode if 'dir' is removed |
Date: |
Tue, 4 Apr 2017 19:16:28 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 |
On 04/04/17 09:47, Sebastian Kisela wrote:
> * src/tail.c (tail_forever_inotify): Add the IN_DELETE_SELF flag when
> creating watch for the parent directory. After the parent directory
> is removed, an event is caught and then we switch from inotify to
> polling mode. Till now, inotify has always frozen because it waited for
> an event from a watched dir, which has been already deleted and was not
> added again.
> * tests/tail-2/inotify-dir-recreate.sh: Add a test case.
> * tests/local.mk: Reference the new test.
> * NEWS: Mention the bug fix.
>
> Reported at https://bugzilla.redhat.com/1283760
Excellent. That looks like a fine fall back.
Not having looked at the C code,
have you considered if another dir/files are already setup with inotify watches,
and if files are deleted but still open?
Other comments below...
> @@ -1628,6 +1629,24 @@ tail_forever_inotify (int wd, struct File_spec *f,
> size_t n_files,
> ev = void_ev;
> evbuf_off += sizeof (*ev) + ev->len;
>
> + /* If a directory is deleted, IN_DELETE_SELF is emmited
> + with ev->name of length 0.
> + We need to catch it, otherwise it would wait forever,
> + as wd for directory becomes inactive. Revert to polling now. */
> + if ((ev->mask & IN_DELETE_SELF) && !ev->len)
> + {
> + for (i = 0; i < n_files; i++)
> + {
> + if (ev->wd == f[i].parent_wd)
> + {
> + hash_free (wd_to_name);
> + error (0, 0,
> + _("directory containing watched file was removed"));
> + return true;
> + }
> + }
> + }
> +
> if (ev->len) /* event on ev->name in watched directory. */
> {
> size_t j;
> +
> +# Check for existence of the important message
> +check_tail_output_ ()
> +{
> + grep "$1" out &>/dev/null || fail=1
> +}
> +
> +# Prepare the file to be watched
> +mkdir dir && touch dir/file
> +sleep 1
Why this sleep?
> +timeout 60 tail --follow=name --retry dir/file &>out & pid=$!
> +sleep 1
We can't depend on absolute sleeps like this. See:
http://www.pixelbeat.org/docs/coreutils-testing.html#backoff
or the existing tail-2/ tests
cheers,
Pádraig