X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fexportfs%2Fexportfs.c;h=fe0f6bac5e188d302ec2b40bc2e862ed8dc855df;hp=c012961871cd86bc4d96d9d4d992c986c47780a9;hb=3094278cd11c3c18d5426210e09e3c903a7a41a3;hpb=4d961554071d2308017062c8bc39f37f5de55b5f diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c index c012961..fe0f6ba 100644 --- a/utils/exportfs/exportfs.c +++ b/utils/exportfs/exportfs.c @@ -24,7 +24,6 @@ #include "xlog.h" static void export_all(int verbose); -static void unexport_all(int verbose); static void exportfs(char *arg, char *options, int verbose); static void unexportfs(char *arg, int verbose); static void exports_update(int verbose); @@ -43,10 +42,14 @@ main(int argc, char **argv) int f_reexport = 0; int f_ignore = 0; int i, c; + int new_cache = 0; + int force_flush = 0; xlog_open("exportfs"); - while ((c = getopt(argc, argv, "aio:ruv")) != EOF) { + export_errno = 0; + + while ((c = getopt(argc, argv, "aio:ruvf")) != EOF) { switch(c) { case 'a': f_all = 1; @@ -67,6 +70,9 @@ main(int argc, char **argv) case 'v': f_verbose = 1; break; + case 'f': + force_flush = 1; + break; default: usage(); break; @@ -86,10 +92,15 @@ main(int argc, char **argv) return 1; } if (optind == argc && ! f_all) { - xtab_export_read(); - dump(f_verbose); - return 0; + if (force_flush) { + cache_flush(1); + } else { + xtab_export_read(); + dump(f_verbose); + return 0; + } } + new_cache = check_new_cache(); if (f_export && ! f_ignore) export_read(_PATH_EXPORTS); @@ -100,25 +111,32 @@ main(int argc, char **argv) for (i = optind; i < argc ; i++) exportfs(argv[i], options, f_verbose); } - /* note: xtab_*_read does not update entries if they already exist, - * so this will not lose new options + /* If we are unexporting everything, then + * don't care about what should be exported, as that + * may require DNS lookups.. */ - if (!f_reexport) - xtab_export_read(); - if (!f_export) { - if (f_all) - unexport_all(f_verbose); - else + if (! ( !f_export && f_all)) { + /* note: xtab_*_read does not update entries if they already exist, + * so this will not lose new options + */ + if (!f_reexport) + xtab_export_read(); + if (!f_export) for (i = optind ; i < argc ; i++) unexportfs(argv[i], f_verbose); + rmtab_read(); + } + if (!new_cache) { + xtab_mount_read(); + exports_update(f_verbose); } - rmtab_read(); - xtab_mount_read(); - exports_update(f_verbose); xtab_export_write(); - xtab_mount_write(); + if (new_cache) + cache_flush(force_flush); + if (!new_cache) + xtab_mount_write(); - return 0; + return export_errno; } /* we synchronise intention with reality. @@ -132,6 +150,16 @@ exports_update(int verbose) nfs_export *exp; for (exp = exportlist[MCL_FQDN]; exp; exp=exp->m_next) { + /* 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", @@ -174,38 +202,6 @@ export_all(int verbose) } } } -/* - * unexport_all finds all entries that are mayexport, and - * marks them not xtabent and not mayexport - */ -static void -unexport_all(int verbose) -{ - nfs_export *exp; - int i; - - for (i = 0; i < MCL_MAXTYPES; i++) { - for (exp = exportlist[i]; exp; exp = exp->m_next) - if (exp->m_mayexport) { - if (verbose) { - if (exp->m_exported) { - printf("unexporting %s:%s from kernel\n", - exp->m_client->m_hostname, - exp->m_export.e_path); - } - else { - printf("unexporting %s:%s\n", - exp->m_client->m_hostname, - exp->m_export.e_path); - } - } - if (exp->m_exported && !export_unexport(exp)) - error(exp, errno); - exp->m_xtabent = 0; - exp->m_mayexport = 0; - } - } -} static void @@ -237,13 +233,14 @@ exportfs(char *arg, char *options, int verbose) } else hp = hp2; exp = export_find(hp, path); + hname = hp->h_name; } else { - exp = export_lookup(hname, path); + exp = export_lookup(hname, path, 0); } if (!exp) { if (!(eep = mkexportent(hname, path, options)) || - !(exp = export_create(eep))) { + !(exp = export_create(eep, 0))) { if (hp) free (hp); return; } @@ -289,25 +286,32 @@ unexportfs(char *arg, int verbose) for (exp = exportlist[htype]; exp; exp = exp->m_next) { if (path && strcmp(path, exp->m_export.e_path)) continue; - if (htype != exp->m_client->m_type - || (htype == MCL_FQDN - && !matchhostname(exp->m_export.e_hostname, - hname))) + if (htype != exp->m_client->m_type) + continue; + if (htype == MCL_FQDN + && !matchhostname(exp->m_export.e_hostname, + hname)) + continue; + if (htype != MCL_FQDN + && strcasecmp(exp->m_export.e_hostname, hname)) continue; if (verbose) { +#if 0 if (exp->m_exported) { printf("unexporting %s:%s from kernel\n", exp->m_client->m_hostname, exp->m_export.e_path); } - else { + else +#endif printf("unexporting %s:%s\n", exp->m_client->m_hostname, exp->m_export.e_path); - } } +#if 0 if (exp->m_exported && !export_unexport(exp)) error(exp, errno); +#endif exp->m_xtabent = 0; exp->m_mayexport = 0; } @@ -361,8 +365,10 @@ dump(int verbose) c = dumpopt(c, "async"); if (ep->e_flags & NFSEXP_GATHERED_WRITES) c = dumpopt(c, "wdelay"); - if (ep->e_flags & NFSEXP_CROSSMNT) + if (ep->e_flags & NFSEXP_NOHIDE) c = dumpopt(c, "nohide"); + if (ep->e_flags & NFSEXP_CROSSMNT) + c = dumpopt(c, "crossmnt"); if (ep->e_flags & NFSEXP_INSECURE_PORT) c = dumpopt(c, "insecure"); if (ep->e_flags & NFSEXP_ROOTSQUASH) @@ -375,6 +381,12 @@ dump(int verbose) c = dumpopt(c, "no_subtree_check"); if (ep->e_flags & NFSEXP_NOAUTHNLM) c = dumpopt(c, "insecure_locks"); + if (ep->e_flags & NFSEXP_FSID) + c = dumpopt(c, "fsid=%d", ep->e_fsid); + if (ep->e_mountpoint) + c = dumpopt(c, "mountpoint%s%s", + ep->e_mountpoint[0]?"=":"", + ep->e_mountpoint); if (ep->e_maptype == CLE_MAP_UGIDD) c = dumpopt(c, "mapping=ugidd"); else if (ep->e_maptype == CLE_MAP_FILE)