static gid_t *groups = NULL;
static int groups_len = 0;
gid_t *more_groups;
- int ngroups = 0;
+ int ngroups;
int rv, i;
char *cp;
if (!groups)
return;
- groups_len = ngroups = INITIAL_MANAGED_GROUPS;
+ groups_len = INITIAL_MANAGED_GROUPS;
}
+ ngroups = groups_len;
+
if (readline(fileno(f), &lbuf, &lbuflen) != 1)
return;
return me->mnt_dir;
}
+/* True iff e1 is a child of e2 and e2 has crossmnt set: */
+static bool subexport(struct exportent *e1, struct exportent *e2)
+{
+ char *p1 = e1->e_path, *p2 = e2->e_path;
+ int l2 = strlen(p2);
+
+ return e2->e_flags & NFSEXP_CROSSMOUNT
+ && strncmp(p1, p2, l2) == 0
+ && p1[l2] == '/';
+}
+
static void nfsd_fh(FILE *f)
{
/* request are:
if (!client_check(exp->m_client, ai))
continue;
}
- /* It's a match !! */
- if (!found) {
+ if (!found || subexport(&exp->m_export, found)) {
found = &exp->m_export;
+ free(found_path);
found_path = strdup(path);
if (found_path == NULL)
goto out;
- } else if (strcmp(found->e_path, exp->m_export.e_path)!= 0)
+ } else if (strcmp(found->e_path, exp->m_export.e_path)
+ && !subexport(found, &exp->m_export))
{
xlog(L_WARNING, "%s and %s have same filehandle for %s, using first",
found_path, path, dom);
char *cache_name;
void (*cache_handle)(FILE *f);
FILE *f;
+ char vbuf[RPC_CHAN_BUF_SIZE];
} cachelist[] = {
- { "auth.unix.ip", auth_unix_ip, NULL},
- { "auth.unix.gid", auth_unix_gid, NULL},
- { "nfsd.export", nfsd_export, NULL},
- { "nfsd.fh", nfsd_fh, NULL},
- { NULL, NULL, NULL }
+ { "auth.unix.ip", auth_unix_ip, NULL, ""},
+ { "auth.unix.gid", auth_unix_gid, NULL, ""},
+ { "nfsd.export", nfsd_export, NULL, ""},
+ { "nfsd.fh", nfsd_fh, NULL, ""},
+ { NULL, NULL, NULL, ""}
};
extern int manage_gids;
continue;
sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name);
cachelist[i].f = fopen(path, "r+");
+ if (cachelist[i].f != NULL) {
+ setvbuf(cachelist[i].f, cachelist[i].vbuf, _IOLBF,
+ RPC_CHAN_BUF_SIZE);
+ }
}
}