X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmountd%2Fcache.c;h=34f949c66b90200973856b6230f9095fe8675fcc;hp=3402d12b1e6468ebeaeb51c1fffa3fbc462daba8;hb=4929f11159f0e6568f13820f114594028fc81e2d;hpb=460ef2f898148fbc858cffe9d2ac12070131d5dd diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c index 3402d12..34f949c 100644 --- a/utils/mountd/cache.c +++ b/utils/mountd/cache.c @@ -67,6 +67,8 @@ void auth_unix_ip(FILE *f) if (inet_aton(ipaddr, &addr)==0) return; + auth_reload(); + /* addr is a valid, interesting address, find the domain name... */ client = client_compose(addr); @@ -78,6 +80,9 @@ void auth_unix_ip(FILE *f) qword_print(f, *client?client:"DEFAULT"); qword_eol(f); + if (client && strcmp(ipaddr, client)) + mountlist_add(ipaddr, *client?client:"DEFAULT"); + if (client) free(client); } @@ -114,7 +119,7 @@ void nfsd_fh(FILE *f) goto out; if (qword_get_int(&cp, &fsidtype) != 0) goto out; - if (fsidtype < 0 || fsidtype > 1) + if (fsidtype < 0 || fsidtype > 3) goto out; /* unknown type */ if ((fsidlen = qword_get(&cp, fsid, 32)) <= 0) goto out; @@ -133,26 +138,53 @@ void nfsd_fh(FILE *f) goto out; memcpy(&fsidnum, fsid, 4); break; + + case 2: /* 12 bytes: 4 major, 4 minor, 4 inode + * This format is never actually used but was + * an historical accident + */ + if (fsidlen != 12) + goto out; + memcpy(&dev, fsid, 4); major = ntohl(dev); + memcpy(&dev, fsid+4, 4); minor = ntohl(dev); + memcpy(&inode, fsid+8, 4); + break; + + case 3: /* 8 bytes: 4 byte packed device number, 4 inode */ + /* This is *host* endian, not net-byte-order, because + * no-one outside this host has any business interpreting it + */ + if (fsidlen != 8) + goto out; + memcpy(&dev, fsid, 4); + memcpy(&inode, fsid+4, 4); + major = (dev & 0xfff00) >> 8; + minor = (dev & 0xff) | ((dev >> 12) & 0xfff00); + break; + } + auth_reload(); + /* Now determine export point for this fsid/domain */ for (i=0 ; i < MCL_MAXTYPES; i++) { for (exp = exportlist[i]; exp; exp = exp->m_next) { + struct stat stb; + if (!client_member(dom, exp->m_client->m_hostname)) continue; + if (exp->m_export.e_mountpoint && + !is_mountpoint(exp->m_export.e_mountpoint[0]? + exp->m_export.e_mountpoint: + exp->m_export.e_path)) + dev_missing ++; + if (stat(exp->m_export.e_path, &stb) != 0) + continue; if (fsidtype == 1 && ((exp->m_export.e_flags & NFSEXP_FSID) == 0 || exp->m_export.e_fsid != fsidnum)) continue; - if (fsidtype == 0) { - struct stat stb; - if (exp->m_export.e_mountpoint && - !is_mountpoint(exp->m_export.e_mountpoint[0]? - exp->m_export.e_mountpoint: - exp->m_export.e_path)) - dev_missing ++; - if (stat(exp->m_export.e_path, &stb) != 0) - continue; + if (fsidtype != 1) { if (stb.st_ino != inode) continue; if (major != major(stb.st_dev) || @@ -233,6 +265,8 @@ void nfsd_export(FILE *f) if (qword_get(&cp, path, strlen(lbuf)) <= 0) goto out; + auth_reload(); + /* now find flags for this export point in this domain */ for (i=0 ; i < MCL_MAXTYPES; i++) { for (exp = exportlist[i]; exp; exp = exp->m_next) { @@ -258,6 +292,7 @@ void nfsd_export(FILE *f) qword_printint(f, found->m_export.e_anonuid); qword_printint(f, found->m_export.e_anongid); qword_printint(f, found->m_export.e_fsid); + mountlist_add(dom, path); } qword_eol(f); out: @@ -305,6 +340,7 @@ int cache_process_req(fd_set *readfds) FD_ISSET(fileno(cachelist[i].f), readfds)) { cnt++; cachelist[i].cache_handle(cachelist[i].f); + FD_CLR(fileno(cachelist[i].f), readfds); } } return cnt; @@ -320,7 +356,7 @@ int cache_process_req(fd_set *readfds) void cache_export_ent(char *domain, struct exportent *exp) { - FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "r+"); + FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w"); if (!f) return; @@ -334,13 +370,15 @@ void cache_export_ent(char *domain, struct exportent *exp) qword_eol(f); fclose(f); + + mountlist_add(domain, exp->e_path); } void cache_export(nfs_export *exp) { FILE *f; - f = fopen("/proc/net/rpc/auth.unix.ip/channel", "r+"); + f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w"); if (!f) return; @@ -352,6 +390,9 @@ void cache_export(nfs_export *exp) fclose(f); + if (strcmp(inet_ntoa(exp->m_client->m_addrlist[0]), exp->m_client->m_hostname)) + mountlist_add(inet_ntoa(exp->m_client->m_addrlist[0]), exp->m_client->m_hostname); + cache_export_ent(exp->m_client->m_hostname, &exp->m_export); } @@ -359,15 +400,19 @@ void cache_export(nfs_export *exp) * { * echo $domain $path $length * read filehandle <&0 - * } <> /proc/fs/nfs/filehandle + * } <> /proc/fs/nfsd/filehandle */ struct nfs_fh_len * cache_get_filehandle(nfs_export *exp, int len, char *p) { - FILE *f = fopen("/proc/fs/nfs/filehandle", "r+"); + FILE *f = fopen("/proc/fs/nfsd/filehandle", "r+"); char buf[200]; char *bp = buf; + int failed; static struct nfs_fh_len fh; + + if (!f) + f = fopen("/proc/fs/nfs/filehandle", "r+"); if (!f) return NULL; @@ -376,7 +421,9 @@ cache_get_filehandle(nfs_export *exp, int len, char *p) qword_printint(f, len); qword_eol(f); - if (fgets(buf, sizeof(buf), f) == NULL) + failed = (fgets(buf, sizeof(buf), f) == NULL); + fclose(f); + if (failed) return NULL; memset(fh.fh_handle, 0, sizeof(fh.fh_handle)); fh.fh_size = qword_get(&bp, fh.fh_handle, NFS3_FHSIZE);