193 lines
4.5 KiB
Diff
193 lines
4.5 KiB
Diff
|
Commits:
|
||
|
2f669b6f NFS server should enable RDMA by default
|
||
|
d77ece22 mountd/exportd: only log confirmed clients, and poll for updates
|
||
|
ac266e2e exportfs: fix unexporting of '/'
|
||
|
|
||
|
diff --git a/nfs.conf b/nfs.conf
|
||
|
index 9042d27d..31994f61 100644
|
||
|
--- a/nfs.conf
|
||
|
+++ b/nfs.conf
|
||
|
@@ -72,9 +72,9 @@
|
||
|
# vers4.0=y
|
||
|
# vers4.1=y
|
||
|
# vers4.2=y
|
||
|
-# rdma=n
|
||
|
-# rdma-port=20049
|
||
|
-#
|
||
|
+rdma=y
|
||
|
+rdma-port=20049
|
||
|
+
|
||
|
[statd]
|
||
|
# debug=0
|
||
|
# port=0
|
||
|
diff --git a/support/export/v4clients.c b/support/export/v4clients.c
|
||
|
index 056ddc9b..dd985463 100644
|
||
|
--- a/support/export/v4clients.c
|
||
|
+++ b/support/export/v4clients.c
|
||
|
@@ -48,12 +48,15 @@ void v4clients_set_fds(fd_set *fdset)
|
||
|
}
|
||
|
|
||
|
static void *tree_root;
|
||
|
+static int have_unconfirmed;
|
||
|
|
||
|
struct ent {
|
||
|
unsigned long num;
|
||
|
char *clientid;
|
||
|
char *addr;
|
||
|
int vers;
|
||
|
+ int unconfirmed;
|
||
|
+ int wid;
|
||
|
};
|
||
|
|
||
|
static int ent_cmp(const void *av, const void *bv)
|
||
|
@@ -89,15 +92,14 @@ static char *dup_line(char *line)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
-static void add_id(int id)
|
||
|
+static void read_info(struct ent *key)
|
||
|
{
|
||
|
char buf[2048];
|
||
|
- struct ent **ent;
|
||
|
- struct ent *key;
|
||
|
char *path;
|
||
|
+ int was_unconfirmed = key->unconfirmed;
|
||
|
FILE *f;
|
||
|
|
||
|
- if (asprintf(&path, "/proc/fs/nfsd/clients/%d/info", id) < 0)
|
||
|
+ if (asprintf(&path, "/proc/fs/nfsd/clients/%lu/info", key->num) < 0)
|
||
|
return;
|
||
|
|
||
|
f = fopen(path, "r");
|
||
|
@@ -105,35 +107,64 @@ static void add_id(int id)
|
||
|
free(path);
|
||
|
return;
|
||
|
}
|
||
|
- key = calloc(1, sizeof(*key));
|
||
|
- if (!key) {
|
||
|
- fclose(f);
|
||
|
- free(path);
|
||
|
- return;
|
||
|
- }
|
||
|
- key->num = id;
|
||
|
+ if (key->wid < 0)
|
||
|
+ key->wid = inotify_add_watch(clients_fd, path, IN_MODIFY);
|
||
|
+
|
||
|
while (fgets(buf, sizeof(buf), f)) {
|
||
|
- if (strncmp(buf, "clientid: ", 10) == 0)
|
||
|
+ if (strncmp(buf, "clientid: ", 10) == 0) {
|
||
|
+ free(key->clientid);
|
||
|
key->clientid = dup_line(buf+10);
|
||
|
- if (strncmp(buf, "address: ", 9) == 0)
|
||
|
+ }
|
||
|
+ if (strncmp(buf, "address: ", 9) == 0) {
|
||
|
+ free(key->addr);
|
||
|
key->addr = dup_line(buf+9);
|
||
|
+ }
|
||
|
if (strncmp(buf, "minor version: ", 15) == 0)
|
||
|
key->vers = atoi(buf+15);
|
||
|
+ if (strncmp(buf, "status: ", 8) == 0 &&
|
||
|
+ strstr(buf, " unconfirmed") != NULL) {
|
||
|
+ key->unconfirmed = 1;
|
||
|
+ have_unconfirmed = 1;
|
||
|
+ }
|
||
|
+ if (strncmp(buf, "status: ", 8) == 0 &&
|
||
|
+ strstr(buf, " confirmed") != NULL)
|
||
|
+ key->unconfirmed = 0;
|
||
|
}
|
||
|
fclose(f);
|
||
|
free(path);
|
||
|
|
||
|
- xlog(L_NOTICE, "v4.%d client attached: %s from %s",
|
||
|
- key->vers, key->clientid, key->addr);
|
||
|
+ if (was_unconfirmed && !key->unconfirmed)
|
||
|
+ xlog(L_NOTICE, "v4.%d client attached: %s from %s",
|
||
|
+ key->vers, key->clientid ?: "-none-",
|
||
|
+ key->addr ?: "-none-");
|
||
|
+ if (!key->unconfirmed && key->wid >= 0) {
|
||
|
+ inotify_rm_watch(clients_fd, key->wid);
|
||
|
+ key->wid = -1;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void add_id(int id)
|
||
|
+{
|
||
|
+ struct ent **ent;
|
||
|
+ struct ent *key;
|
||
|
+
|
||
|
+ key = calloc(1, sizeof(*key));
|
||
|
+ if (!key) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ key->num = id;
|
||
|
+ key->wid = -1;
|
||
|
|
||
|
ent = tsearch(key, &tree_root, ent_cmp);
|
||
|
|
||
|
if (!ent || *ent != key)
|
||
|
/* Already existed, or insertion failed */
|
||
|
free_ent(key);
|
||
|
+ else
|
||
|
+ read_info(key);
|
||
|
}
|
||
|
|
||
|
-static void del_id(int id)
|
||
|
+static void del_id(unsigned long id)
|
||
|
{
|
||
|
struct ent key = {.num = id};
|
||
|
struct ent **e, *ent;
|
||
|
@@ -143,11 +174,27 @@ static void del_id(int id)
|
||
|
return;
|
||
|
ent = *e;
|
||
|
tdelete(ent, &tree_root, ent_cmp);
|
||
|
- xlog(L_NOTICE, "v4.%d client detached: %s from %s",
|
||
|
- ent->vers, ent->clientid, ent->addr);
|
||
|
+ if (!ent->unconfirmed)
|
||
|
+ xlog(L_NOTICE, "v4.%d client detached: %s from %s",
|
||
|
+ ent->vers, ent->clientid, ent->addr);
|
||
|
+ if (ent->wid >= 0)
|
||
|
+ inotify_rm_watch(clients_fd, ent->wid);
|
||
|
free_ent(ent);
|
||
|
}
|
||
|
|
||
|
+static void check_id(unsigned long id)
|
||
|
+{
|
||
|
+ struct ent key = {.num = id};
|
||
|
+ struct ent **e, *ent;
|
||
|
+
|
||
|
+ e = tfind(&key, &tree_root, ent_cmp);
|
||
|
+ if (!e || !*e)
|
||
|
+ return;
|
||
|
+ ent = *e;
|
||
|
+ if (ent->unconfirmed)
|
||
|
+ read_info(ent);
|
||
|
+}
|
||
|
+
|
||
|
int v4clients_process(fd_set *fdset)
|
||
|
{
|
||
|
char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event))));
|
||
|
@@ -172,8 +219,9 @@ int v4clients_process(fd_set *fdset)
|
||
|
add_id(id);
|
||
|
if (ev->mask & IN_DELETE)
|
||
|
del_id(id);
|
||
|
+ if (ev->mask & IN_MODIFY)
|
||
|
+ check_id(id);
|
||
|
}
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
-
|
||
|
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
|
||
|
index 262dd19a..25d757d8 100644
|
||
|
--- a/utils/exportfs/exportfs.c
|
||
|
+++ b/utils/exportfs/exportfs.c
|
||
|
@@ -383,7 +383,7 @@ unexportfs_parsed(char *hname, char *path, int verbose)
|
||
|
* so need to deal with it.
|
||
|
*/
|
||
|
size_t nlen = strlen(path);
|
||
|
- while (path[nlen - 1] == '/')
|
||
|
+ while ((nlen > 1) && (path[nlen - 1] == '/'))
|
||
|
nlen--;
|
||
|
|
||
|
for (exp = exportlist[htype].p_head; exp; exp = exp->m_next) {
|