X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=utils%2Fgssd%2Fgssd_main_loop.c;h=b06c223294f2f0aadc928ba8d73d6b711e164ba0;hb=24d0b823f10f9cae2eba9b22fb830dd8dc3fb15a;hp=397fd1461f3c873077ecbd7c2f78548bf8b0ea9e;hpb=99ed8de8261beb580c0ab9543ea7f2c8e16c9306;p=nfs-utils.git diff --git a/utils/gssd/gssd_main_loop.c b/utils/gssd/gssd_main_loop.c index 397fd14..b06c223 100644 --- a/utils/gssd/gssd_main_loop.c +++ b/utils/gssd/gssd_main_loop.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "gssd.h" #include "err_util.h" @@ -62,6 +63,8 @@ static volatile int dir_changed = 1; static void dir_notify_handler(int sig, siginfo_t *si, void *data) { + printerr(2, "dir_notify_handler: sig %d si %p data %p\n", sig, si, data); + dir_changed = 1; } @@ -73,6 +76,17 @@ scan_poll_results(int ret) for (clp = clnt_list.tqh_first; clp != NULL; clp = clp->list.tqe_next) { + i = clp->gssd_poll_index; + if (i >= 0 && pollarray[i].revents) { + if (pollarray[i].revents & POLLHUP) + dir_changed = 1; + if (pollarray[i].revents & POLLIN) + handle_gssd_upcall(clp); + pollarray[clp->gssd_poll_index].revents = 0; + ret--; + if (!ret) + break; + } i = clp->krb5_poll_index; if (i >= 0 && pollarray[i].revents) { if (pollarray[i].revents & POLLHUP) @@ -98,12 +112,85 @@ scan_poll_results(int ret) } }; +static int +topdirs_add_entry(struct dirent *dent) +{ + struct topdirs_info *tdi; + + tdi = calloc(sizeof(struct topdirs_info), 1); + if (tdi == NULL) { + printerr(0, "ERROR: Couldn't allocate struct topdirs_info\n"); + return -1; + } + tdi->dirname = malloc(PATH_MAX); + if (tdi->dirname == NULL) { + printerr(0, "ERROR: Couldn't allocate directory name\n"); + free(tdi); + return -1; + } + snprintf(tdi->dirname, PATH_MAX, "%s/%s", pipefs_dir, dent->d_name); + tdi->fd = open(tdi->dirname, O_RDONLY); + if (tdi->fd != -1) { + fcntl(tdi->fd, F_SETSIG, DNOTIFY_SIGNAL); + fcntl(tdi->fd, F_NOTIFY, + DN_CREATE|DN_DELETE|DN_MODIFY|DN_MULTISHOT); + } + + TAILQ_INSERT_HEAD(&topdirs_list, tdi, list); + return 0; +} + +static void +topdirs_free_list(void) +{ + struct topdirs_info *tdi; + + TAILQ_FOREACH(tdi, &topdirs_list, list) { + free(tdi->dirname); + if (tdi->fd != -1) + close(tdi->fd); + TAILQ_REMOVE(&topdirs_list, tdi, list); + free(tdi); + } +} + +static int +topdirs_init_list(void) +{ + DIR *pipedir; + struct dirent *dent; + int ret; + + TAILQ_INIT(&topdirs_list); + + pipedir = opendir(pipefs_dir); + if (pipedir == NULL) { + printerr(0, "ERROR: could not open rpc_pipefs directory '%s': " + "%s\n", pipefs_dir, strerror(errno)); + return -1; + } + for (dent = readdir(pipedir); dent != NULL; dent = readdir(pipedir)) { + if (dent->d_type != DT_DIR || + strcmp(dent->d_name, ".") == 0 || + strcmp(dent->d_name, "..") == 0) { + continue; + } + ret = topdirs_add_entry(dent); + if (ret) + goto out_err; + } + closedir(pipedir); + return 0; +out_err: + topdirs_free_list(); + return -1; +} + void gssd_run() { int ret; struct sigaction dn_act; - int fd; sigset_t set; /* Taken from linux/Documentation/dnotify.txt: */ @@ -117,13 +204,8 @@ gssd_run() sigaddset(&set, DNOTIFY_SIGNAL); sigprocmask(SIG_UNBLOCK, &set, NULL); - if ((fd = open(pipefs_nfsdir, O_RDONLY)) == -1) { - printerr(0, "ERROR: failed to open %s: %s\n", - pipefs_nfsdir, strerror(errno)); - exit(1); - } - fcntl(fd, F_SETSIG, DNOTIFY_SIGNAL); - fcntl(fd, F_NOTIFY, DN_CREATE|DN_DELETE|DN_MODIFY|DN_MULTISHOT); + if (topdirs_init_list() != 0) + return; init_client_list(); @@ -150,6 +232,7 @@ gssd_run() scan_poll_results(ret); } } - close(fd); + topdirs_free_list(); + return; }