summaryrefslogtreecommitdiffstats
path: root/utils/gssd/gssd_main_loop.c
diff options
context:
space:
mode:
authorOlga Kornievskaia <aglo@citi.umich.edu>2009-11-16 09:15:25 -0500
committerSteve Dickson <steved@redhat.com>2009-11-16 09:15:25 -0500
commit24de786ec7e7a70e0587b0656a31f309b3b5eb65 (patch)
tree30fa2fb161681a3118028afc662adfa99e339a5d /utils/gssd/gssd_main_loop.c
parent99ed8de8261beb580c0ab9543ea7f2c8e16c9306 (diff)
downloadnfs-utils-24de786ec7e7a70e0587b0656a31f309b3b5eb65.tar.gz
nfs-utils-24de786ec7e7a70e0587b0656a31f309b3b5eb65.tar.xz
nfs-utils-24de786ec7e7a70e0587b0656a31f309b3b5eb65.zip
gssd: add upcall support for callback authentication
Change the processing so that all subdirectories within the rpc_pipefs directory are treated equally. Any "clnt" directories that show up within any of them are processed. (As suggested by Bruce Fields.) Note that the callback authentication will create a new "nfs4d_cb" subdirectory. Only new kernels (2.6.29) will create this new directory. (The need for this directory will go away with NFSv4.1 where the callback can be done on the same connection as the fore-channel.) Signed-off-by: Kevin Coffman <kwc@citi.umich.edu> Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'utils/gssd/gssd_main_loop.c')
-rw-r--r--utils/gssd/gssd_main_loop.c88
1 files changed, 79 insertions, 9 deletions
diff --git a/utils/gssd/gssd_main_loop.c b/utils/gssd/gssd_main_loop.c
index 397fd14..b5117c5 100644
--- a/utils/gssd/gssd_main_loop.c
+++ b/utils/gssd/gssd_main_loop.c
@@ -49,6 +49,7 @@
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
+#include <dirent.h>
#include "gssd.h"
#include "err_util.h"
@@ -98,12 +99,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 +191,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 +219,7 @@ gssd_run()
scan_poll_results(ret);
}
}
- close(fd);
+ topdirs_free_list();
+
return;
}