directory change notification patch
Mark Weaver
mark-clist at npsl.co.uk
Sat Mar 26 04:09:03 GMT 2005
> Ok, a few comments. You're changing lib/select.c. This makes me very
> nervous. This is critical code, tested on millions of systems and took
> us a long time to get right. Are you sure your changes are correct ? Why
> do you need them ?
>
I mentioned this in my first message -- basically it's as follows:
- smbd code assumes that (change notify) signals are delivered via EINTR
when calling select. Since notification polling is disabled in the
present code if kernel change notification is active, the assumption
would seem to be that the notification is reliable. The mechanism for
signal delivery is to write to a pipe in select.c (via
sys_select_signal()) and report it later in sys_select.
- When a signal is delivered and any other fd is ready then sys_select
does not return -1/EINTR, but yet reads from the pipe. This leads to
signal notifications being lost. I chose to report EINTR in preference
to any fds being ready (alternatively, you could not read from the pipe
and report EINTR later -- this is simply a priority preference). Note
that I am assuming that the caller of sys_select is ready to deal with
EINTR.
- sys_select_intr is a wrapper function for sys_select that eats EINTR.
This also looses signals. I changed this function to simply call
select() directly and copied other wrapper code from sys_select. The
rational was that there there is no point waiting on the signal pipe if
the result is going to be tossed anyway.
The intention of the changes is to make signal delivery via sys_select
reliable. This appears to be fine in smbd, which calls sys_select in
either oplock.c or process.c (when not running as a listener; the other
call in server.c is not important). The call in oplock.c is in
receive_local_message; called via async_processing which deals with the
change notify signals anyway. The call in process.c just calls
async_processing (hence deals with the notify signals). The only other
calls to sys_select in smbd are via sys_select_intr, which if signals
are not eaten, is fine.
Thus, I think it is OK in smbd. However, I agree that it may have
unintended side effects. I don't think that the change is wrong (if the
code matches the intention at least :) -- but it is possible that other
code that calls sys_select may be broken by the changes. Wider
review/testing would be in order.
In summary (and I probably should have said this at the start), the
change is simply a fix to what appears to be the intended mechanism of
signal delivery, which is currently broken. You can test this quite
easily for change notify by having a script change a directory
repeatedly and observing that "kernel change notify on" is missing from
the logs on occasion. Since change notify is one-shot, this is somewhat
of a disaster.
> Secondly, you're mixing direct POSIX calls (eg. open()) with Samba VFS
> calls. You can't do that. All calls touching the filesystem *must* go
> via the VFS calls.
>
I can see one open call (change_notify_file_data_exists), which can
trivially be changed (this is from the original patch).
I also have sys_getwd()/chdir(). I could not find a wrapper (e.g.
sys_chdir()) for chdir() that would be a reversal of sys_getwd(). The
intent is to ensure that the working directory is the same as when the
change notification was posted, as the code that looks for changes
relies on the this being the case. Would SMB_VFS_GETWD/SMB_VFS_CHDIR be
the more appropriate choice here? My problem was that in the case that
process_pending_change_notify_queue is called, I wished to save and
restore the working directory. Thus, for the first sys_getwd() call, I
have no active connection to rely on. Possibly that means is not
necessary to save the working directory, but the function is called from
a number of different locations, and I did not want to break existing code.
Finally, I have unlink. This is used for deleting temporary TDB files
when the "disk" method is used, and I could not find a wrapper for
unlink. These files all live in tmpdir(), and as such, have no
relevance to the smbd client -- they should be a straight POSIX path.
> Just my first thoughts as I looked over it.
>
I hope I've answered your questions. Let me know wrt to the above and
I'll try to make further improvements.
Thanks,
Mark
More information about the samba-technical
mailing list