On 07/16/2012 02:36 PM, Chuck Lever wrote:
> When a POLLHUP event is received on a pipe file descriptor, that
> means the other side has closed its end of the pipe. If the
> receiver does not close its end of the pipe, the pipe is left in an
> open-but-unlinked state.
>
> For a "gssd" upcall pipe, the kernel may close its end, removing the
> directory entry for it, and then later create a fresh pipe named
> "gssd" in the same directory. In this case, rpc.gssd continues to
> listen on the open-but-unlinked previous "gssd" pipe. Thus upcalls
> on the new "gssd" pipe are left unanswered.
>
> In addition, poll(2) continues to return POLLHUP on the old pipe.
> Since there is no logic to close the pipe in rpc.gssd, poll(2) always
> returns immediately, and rpc.gssd goes into a tight loop.
>
> Typically, the kernel closes upcall pipes and destroys their
> parent directory at the same time. When an RPC client's directory
> vanishes, rpc.gssd sees the change via dnotify and eventually
> invokes destroy_client() which closes the user-space end of the
> pipes.
>
> However, if the kernel wants to switch authentication flavors (say
> from AUTH_KRB5 to AUTH_UNIX) on an RPC client without destroying it,
> the upcall pipes go away, but the RPC client's directory remains.
> rpc.gssd invokes update_client_list(), but that logic never closes
> upcall pipes if the client directory is still in place.
>
> After a POLLHUP on a pipe, close it when rpc.gssd reconstructs its
> list of upcall clients.
>
> Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
Committed....
steved.
> ---
>
> I know folks are probably on vacation this week, so this is only a
> request for comments.
>
> utils/gssd/gssd.h | 2 ++
> utils/gssd/gssd_main_loop.c | 8 ++++++--
> utils/gssd/gssd_proc.c | 19 +++++++++++++++++++
> 3 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
> index e0a2b7b..ec81beb 100644
> --- a/utils/gssd/gssd.h
> +++ b/utils/gssd/gssd.h
> @@ -82,8 +82,10 @@ struct clnt_info {
> char *protocol;
> int krb5_fd;
> int krb5_poll_index;
> + int krb5_close_me;
> int gssd_fd;
> int gssd_poll_index;
> + int gssd_close_me;
> struct sockaddr_storage addr;
> };
>
> diff --git a/utils/gssd/gssd_main_loop.c b/utils/gssd/gssd_main_loop.c
> index 187954c..6480390 100644
> --- a/utils/gssd/gssd_main_loop.c
> +++ b/utils/gssd/gssd_main_loop.c
> @@ -78,8 +78,10 @@ scan_poll_results(int ret)
> {
> i = clp->gssd_poll_index;
> if (i >= 0 && pollarray[i].revents) {
> - if (pollarray[i].revents & POLLHUP)
> + if (pollarray[i].revents & POLLHUP) {
> + clp->gssd_close_me = 1;
> dir_changed = 1;
> + }
> if (pollarray[i].revents & POLLIN)
> handle_gssd_upcall(clp);
> pollarray[clp->gssd_poll_index].revents = 0;
> @@ -89,8 +91,10 @@ scan_poll_results(int ret)
> }
> i = clp->krb5_poll_index;
> if (i >= 0 && pollarray[i].revents) {
> - if (pollarray[i].revents & POLLHUP)
> + if (pollarray[i].revents & POLLHUP) {
> + clp->krb5_close_me = 1;
> dir_changed = 1;
> + }
> if (pollarray[i].revents & POLLIN)
> handle_krb5_upcall(clp);
> pollarray[clp->krb5_poll_index].revents = 0;
> diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
> index fed2886..5e33379 100644
> --- a/utils/gssd/gssd_proc.c
> +++ b/utils/gssd/gssd_proc.c
> @@ -339,6 +339,25 @@ process_clnt_dir_files(struct clnt_info * clp)
> char gname[PATH_MAX];
> char info_file_name[PATH_MAX];
>
> + if (clp->gssd_close_me) {
> + printerr(2, "Closing 'gssd' pipe for %s\n", clp->dirname);
> + close(clp->gssd_fd);
> + memset(&pollarray[clp->gssd_poll_index], 0,
> + sizeof(struct pollfd));
> + clp->gssd_fd = -1;
> + clp->gssd_poll_index = -1;
> + clp->gssd_close_me = 0;
> + }
> + if (clp->krb5_close_me) {
> + printerr(2, "Closing 'krb5' pipe for %s\n", clp->dirname);
> + close(clp->krb5_fd);
> + memset(&pollarray[clp->krb5_poll_index], 0,
> + sizeof(struct pollfd));
> + clp->krb5_fd = -1;
> + clp->krb5_poll_index = -1;
> + clp->krb5_close_me = 0;
> + }
> +
> if (clp->gssd_fd == -1) {
> snprintf(gname, sizeof(gname), "%s/gssd", clp->dirname);
> clp->gssd_fd = open(gname, O_RDWR);
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Linux USB Development]
[Linux Media Development]
[Video for Linux]
[Linux NILFS]
[Linux Audio Users]
[Photo]
[Yosemite Info]
[Yosemite Photos]
[POF Sucks]
[Linux Kernel]
[Linux SCSI]
[XFree86]