X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fnfsdcltrack%2Fnfsdcltrack.c;h=9801b9cd94a01d8041a78a532539ac62745e603d;hp=1d262a211cc77f0d86e2b5af688d51be670211a6;hb=79ff473c2a07078bde8900e66a6db1a17039a956;hpb=09cc3c831c8b1f27439fe09c951139bb6ec8e6c6 diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c index 1d262a2..9801b9c 100644 --- a/utils/nfsdcltrack/nfsdcltrack.c +++ b/utils/nfsdcltrack/nfsdcltrack.c @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef HAVE_SYS_CAPABILITY_H #include #include @@ -295,6 +296,48 @@ cltrack_remove(const char *id) return ret ? -EREMOTEIO : ret; } +static int +cltrack_check_legacy(const unsigned char *blob, const ssize_t len) +{ + int ret; + struct stat st; + char *recdir = getenv("NFSDCLTRACK_LEGACY_RECDIR"); + + if (!recdir) { + xlog(D_GENERAL, "No NFSDCLTRACK_LEGACY_RECDIR env var"); + return -EOPNOTSUPP; + } + + /* fail recovery on any stat failure */ + ret = stat(recdir, &st); + if (ret) { + xlog(D_GENERAL, "Unable to stat %s: %d", recdir, errno); + return -errno; + } + + /* fail if it isn't a directory */ + if (!S_ISDIR(st.st_mode)) { + xlog(D_GENERAL, "%s is not a directory: mode=0%o", recdir + , st.st_mode); + return -ENOTDIR; + } + + /* Dir exists, try to insert record into db */ + ret = sqlite_insert_client(blob, len); + if (ret) { + xlog(D_GENERAL, "Failed to insert client: %d", ret); + return -EREMOTEIO; + } + + /* remove the legacy recoverydir */ + ret = rmdir(recdir); + if (ret) { + xlog(D_GENERAL, "Failed to rmdir %s: %d", recdir, errno); + return -errno; + } + return 0; +} + static int cltrack_check(const char *id) { @@ -312,10 +355,50 @@ cltrack_check(const char *id) return (int)len; ret = sqlite_check_client(blob, len); + if (ret) + ret = cltrack_check_legacy(blob, len); return ret ? -EPERM : ret; } +/* Clean out the v4recoverydir -- best effort here */ +static void +cltrack_legacy_gracedone(void) +{ + DIR *v4recovery; + struct dirent *entry; + char *dirname = getenv("NFSDCLTRACK_LEGACY_TOPDIR"); + + if (!dirname) + return; + + v4recovery = opendir(dirname); + if (!v4recovery) + return; + + while ((entry = readdir(v4recovery))) { + int len; + + /* borrow the clientid blob for this */ + len = snprintf((char *)blob, sizeof(blob), "%s/%s", dirname, + entry->d_name); + + /* if there's a problem, then skip this entry */ + if (len < 0 || (size_t)len >= sizeof(blob)) { + xlog(L_WARNING, "%s: unable to build filename for %s!", + __func__, entry->d_name); + continue; + } + + len = rmdir((char *)blob); + if (len) + xlog(L_WARNING, "%s: unable to rmdir %s: %d", __func__, + (char *)blob, len); + } + + closedir(v4recovery); +} + static int cltrack_gracedone(const char *timestr) { @@ -343,6 +426,8 @@ cltrack_gracedone(const char *timestr) ret = sqlite_remove_unreclaimed(gracetime); + cltrack_legacy_gracedone(); + return ret ? -EREMOTEIO : ret; }