static void exports_update_one(nfs_export *exp, int verbose) { /* check mountpoint option */ if (exp->m_mayexport && exp->m_export.e_mountpoint && !is_mountpoint(exp->m_export.e_mountpoint[0]? exp->m_export.e_mountpoint: exp->m_export.e_path)) { printf("%s not exported as %s not a mountpoint.\n", exp->m_export.e_path, exp->m_export.e_mountpoint); exp->m_mayexport = 0; } if (exp->m_mayexport && ((exp->m_exported<1) || exp->m_changed)) { if (verbose) printf("%sexporting %s:%s to kernel\n", exp->m_exported ?"re":"", exp->m_client->m_hostname, exp->m_export.e_path); if (!export_export(exp)) error(exp, errno); } if (exp->m_exported && ! exp->m_mayexport) { if (verbose) printf("unexporting %s:%s from kernel\n", exp->m_client->m_hostname, exp->m_export.e_path); if (!export_unexport(exp)) error(exp, errno); } }
static struct nfs_fh_len * get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret, mountstat3 *error, int v3) { struct sockaddr_in *sin = nfs_getrpccaller_in(rqstp->rq_xprt); struct stat stb, estb; nfs_export *exp; struct nfs_fh_len *fh; char rpath[MAXPATHLEN+1]; char *p = *path; if (*p == '\0') p = "/"; /* Reload /var/lib/nfs/etab if necessary */ auth_reload(); /* Resolve symlinks */ if (realpath(p, rpath) != NULL) { rpath[sizeof (rpath) - 1] = '\0'; p = rpath; } /* Now authenticate the intruder... */ exp = auth_authenticate("mount", sin, p); if (!exp) { *error = NFSERR_ACCES; return NULL; } if (stat(p, &stb) < 0) { xlog(L_WARNING, "can't stat exported dir %s: %s", p, strerror(errno)); if (errno == ENOENT) *error = NFSERR_NOENT; else *error = NFSERR_ACCES; return NULL; } if (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) { xlog(L_WARNING, "%s is not a directory or regular file", p); *error = NFSERR_NOTDIR; return NULL; } if (stat(exp->m_export.e_path, &estb) < 0) { xlog(L_WARNING, "can't stat export point %s: %s", p, strerror(errno)); *error = NFSERR_NOENT; return NULL; } if (estb.st_dev != stb.st_dev && (!new_cache || !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT))) { xlog(L_WARNING, "request to export directory %s below nearest filesystem %s", p, exp->m_export.e_path); *error = NFSERR_ACCES; return NULL; } if (exp->m_export.e_mountpoint && !is_mountpoint(exp->m_export.e_mountpoint[0]? exp->m_export.e_mountpoint: exp->m_export.e_path)) { xlog(L_WARNING, "request to export an unmounted filesystem: %s", p); *error = NFSERR_NOENT; return NULL; } if (new_cache) { /* This will be a static private nfs_export with just one * address. We feed it to kernel then extract the filehandle, * */ if (cache_export(exp, p)) { *error = NFSERR_ACCES; return NULL; } fh = cache_get_filehandle(exp, v3?64:32, p); if (fh == NULL) { *error = NFSERR_ACCES; return NULL; } } else { int did_export = 0; retry: if (exp->m_exported<1) { export_export(exp); did_export = 1; } if (!exp->m_xtabent) xtab_append(exp); if (v3) fh = getfh_size ((struct sockaddr *) sin, p, 64); if (!v3 || (fh == NULL && errno == EINVAL)) { /* We first try the new nfs syscall. */ fh = getfh ((struct sockaddr *) sin, p); if (fh == NULL && errno == EINVAL) /* Let's try the old one. */ fh = getfh_old ((struct sockaddr *) sin, stb.st_dev, stb.st_ino); } if (fh == NULL && !did_export) { exp->m_exported = 0; goto retry; } if (fh == NULL) { xlog(L_WARNING, "getfh failed: %s", strerror(errno)); *error = NFSERR_ACCES; return NULL; } } *error = NFS_OK; mountlist_add(inet_ntoa(sin->sin_addr), p); if (expret) *expret = exp; return fh; }