#include "xio.h"
#include "xlog.h"
+static void cond_rename(char *newfile, char *oldfile);
+
static int
xtab_read(char *xtab, int is_export)
{
+ /* is_export == 0 => reading /proc/fs/nfs/exports - we know these things are exported to kernel
+ * is_export == 1 => reading /var/lib/nfs/etab - these things are allowed to be exported
+ * is_export == 2 => reading /var/lib/nfs/xtab - these things might be known to kernel
+ */
struct exportent *xp;
nfs_export *exp;
int lockid;
if ((lockid = xflock(xtab, "r")) < 0)
return 0;
setexportent(xtab, "r");
- while ((xp = getexportent()) != NULL) {
- if (!(exp = export_lookup(xp->e_hostname, xp->e_path)) &&
- !(exp = export_create(xp))) {
+ while ((xp = getexportent(is_export==0, 0)) != NULL) {
+ if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
+ !(exp = export_create(xp, is_export!=1))) {
continue;
}
- if (is_export) {
+ switch (is_export) {
+ case 0:
+ exp->m_exported = 1;
+ break;
+ case 1:
exp->m_xtabent = 1;
exp->m_mayexport = 1;
- } else
- exp->m_exported = 1;
+ break;
+ case 2:
+ exp->m_exported = -1;/* may be exported */
+ break;
+ }
}
endexportent();
xfunlock(lockid);
if ((fd=open(_PATH_PROC_EXPORTS, O_RDONLY))>=0) {
close(fd);
return xtab_read(_PATH_PROC_EXPORTS, 0);
+ } else if ((fd=open(_PATH_PROC_EXPORTS_ALT, O_RDONLY) >= 0)) {
+ close(fd);
+ return xtab_read(_PATH_PROC_EXPORTS_ALT, 0);
} else
- return xtab_read(_PATH_XTAB, 0);
+ return xtab_read(_PATH_XTAB, 2);
}
int
}
endexportent();
- rename(xtabtmp, xtab);
+ cond_rename(xtabtmp, xtab);
xfunlock(lockid);
exp->m_xtabent = 1;
}
+/*
+ * rename newfile onto oldfile unless
+ * they are identical
+ */
+static void cond_rename(char *newfile, char *oldfile)
+{
+ int nfd, ofd;
+ char nbuf[4096], obuf[4096];
+ int ncnt, ocnt;
+
+ nfd = open(newfile, 0);
+ if (nfd < 0)
+ return;
+ ofd = open(oldfile, 0);
+ if (ofd < 0) {
+ close(nfd);
+ rename(newfile, oldfile);
+ return;
+ }
+
+ do {
+ ncnt = read(nfd, nbuf, sizeof(nbuf));
+ if (ncnt < 0)
+ break;
+ ocnt = read(ofd, obuf, sizeof(obuf));
+ if (ocnt < 0)
+ break;
+ if (ncnt != ocnt)
+ break;
+ if (ncnt == 0) {
+ close(nfd);
+ close(ofd);
+ unlink(newfile);
+ return;
+ }
+ } while (memcmp(obuf, nbuf, ncnt) == 0);
+
+ /* some mis-match */
+ close(nfd);
+ close(ofd);
+ rename(newfile, oldfile);
+ return;
+}