X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fexportfs%2Fexportfs.c;fp=utils%2Fexportfs%2Fexportfs.c;h=a3323d733efb01c05a48c9bed8ae37f6dc40385d;hp=7432a6592c8d0e69c60dfc69ececec56e92b1f34;hb=adee9b7bddedcddb8de4e0b7c2f778148b1f4d2b;hpb=3ccd5e6e5c55c062c2bafb155fa54bad2cb1226a diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c index 7432a65..a3323d7 100644 --- a/utils/exportfs/exportfs.c +++ b/utils/exportfs/exportfs.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,41 @@ static void usage(const char *progname); static void validate_export(nfs_export *exp); static int matchhostname(const char *hostname1, const char *hostname2); static void export_d_read(const char *dname); +static void grab_lockfile(void); +static void release_lockfile(void); + +static const char *lockfile = EXP_LOCKFILE; +static int _lockfd = -1; + +/* + * If we aren't careful, changes made by exportfs can be lost + * when multiple exports process run at once: + * + * exportfs process 1 exportfs process 2 + * ------------------------------------------ + * reads etab version A reads etab version A + * adds new export B adds new export C + * writes A+B writes A+C + * + * The locking in support/export/xtab.c will prevent mountd from + * seeing a partially written version of etab, and will prevent + * the two writers above from writing simultaneously and + * corrupting etab, but to prevent problems like the above we + * need these additional lockfile() routines. + */ +static void +grab_lockfile() +{ + _lockfd = open(lockfile, O_CREAT|O_RDWR, 0666); + if (_lockfd != -1) + lockf(_lockfd, F_LOCK, 0); +} +static void +release_lockfile() +{ + if (_lockfd != -1) + lockf(_lockfd, F_ULOCK, 0); +} int main(int argc, char **argv) @@ -129,6 +165,13 @@ main(int argc, char **argv) return 0; } } + + /* + * Serialize things as best we can + */ + grab_lockfile(); + atexit(release_lockfile); + if (f_export && ! f_ignore) { export_read(_PATH_EXPORTS); export_d_read(_PATH_EXPORTS_D);