diff --git a/Makefile.am b/Makefile.am index c9e9f87..6f3f3d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,34 +9,6 @@ MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = \ autogen.sh \ \ - debian/changelog \ - debian/control \ - debian/copyright \ - debian/etc.exports \ - debian/idmapd.conf \ - debian/nfs-common.conffiles \ - debian/nfs-common.default \ - debian/nfs-common.dirs \ - debian/nfs-common.files \ - debian/nfs-common.init \ - debian/nfs-common.install \ - debian/nfs-common.postinst \ - debian/nfs-common.postrm \ - debian/nfs-common.prerm \ - debian/nfs-kernel-server.NEWS \ - debian/nfs-kernel-server.conffiles \ - debian/nfs-kernel-server.default \ - debian/nfs-kernel-server.dirs \ - debian/nfs-kernel-server.init \ - debian/nfs-kernel-server.postinst \ - debian/nfs-kernel-server.postrm \ - debian/nfs-kernel-server.prerm \ - debian/nhfsstone.dirs \ - debian/nhfsstone.files \ - debian/nhfsstone.postinst \ - debian/nhfsstone.prerm \ - debian/rules \ - \ aclocal/bsdsignals.m4 \ aclocal/nfs-utils.m4 \ aclocal/kerberos5.m4 \ diff --git a/support/include/Makefile.am b/support/include/Makefile.am index 4b33ee9..5c80c8b 100644 --- a/support/include/Makefile.am +++ b/support/include/Makefile.am @@ -3,6 +3,7 @@ SUBDIRS = nfs rpcsvc sys noinst_HEADERS = \ + cld.h \ exportfs.h \ ha-callout.h \ misc.h \ @@ -10,9 +11,13 @@ noinst_HEADERS = \ nfs_paths.h \ nfslib.h \ nfsrpc.h \ + nls.h \ nsm.h \ + pseudoflavors.h \ rpcmisc.h \ + sockaddr.h \ tcpwrapper.h \ + v4root.h \ xio.h \ xlog.h \ xmalloc.h \ diff --git a/tests/Makefile.am b/tests/Makefile.am index faa8197..1f96264 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -11,3 +11,4 @@ SUBDIRS = nsm_client MAINTAINERCLEANFILES = Makefile.in TESTS = t0001-statd-basic-mon-unmon.sh +EXTRA_DIST = test-lib.sh $(TESTS) diff --git a/tests/nsm_client/Makefile.am b/tests/nsm_client/Makefile.am index 4c15346..a8fc131 100644 --- a/tests/nsm_client/Makefile.am +++ b/tests/nsm_client/Makefile.am @@ -7,6 +7,7 @@ GENFILES_H = nlm_sm_inter.h GENFILES = $(GENFILES_CLNT) $(GENFILES_SVC) $(GENFILES_XDR) $(GENFILES_H) +EXTRA_DIST = nlm_sm_inter.x check_PROGRAMS = nsm_client nsm_client_SOURCES = $(GENFILES) nsm_client.c diff --git a/utils/gssd/Makefile.am b/utils/gssd/Makefile.am index af59791..a4e9c56 100644 --- a/utils/gssd/Makefile.am +++ b/utils/gssd/Makefile.am @@ -8,7 +8,6 @@ sbin_PREFIXED = gssd svcgssd sbin_PROGRAMS = $(sbin_PREFIXED) EXTRA_DIST = \ - gss_destroy_creds \ $(man8_MANS) COMMON_SRCS = \ diff --git a/utils/idmapd/Makefile.am b/utils/idmapd/Makefile.am index 58b33ec..c2f8ba1 100644 --- a/utils/idmapd/Makefile.am +++ b/utils/idmapd/Makefile.am @@ -7,8 +7,7 @@ KPREFIX = @kprefix@ sbin_PROGRAMS = idmapd EXTRA_DIST = \ - $(man8_MANS) \ - idmapd.conf + $(man8_MANS) idmapd_SOURCES = \ idmapd.c \ diff --git a/utils/mount/Makefile.am b/utils/mount/Makefile.am index 5810936..e24f3bd 100644 --- a/utils/mount/Makefile.am +++ b/utils/mount/Makefile.am @@ -8,19 +8,21 @@ man8_MANS = mount.nfs.man umount.nfs.man man5_MANS = nfs.man sbin_PROGRAMS = mount.nfs -EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS) +EXTRA_DIST = nfsmount.conf $(man8_MANS) $(man5_MANS) mount_common = error.c network.c token.c \ parse_opt.c parse_dev.c \ nfsmount.c nfs4mount.c stropts.c\ mount_constants.h error.h network.h token.h \ parse_opt.h parse_dev.h \ - nfs4_mount.h nfs_mount4.h stropts.h version.h \ - mount_config.h utils.c utils.h + nfs4_mount.h stropts.h version.h \ + mount_config.h utils.c utils.h \ + nfs_mount.h if MOUNT_CONFIG mount_common += configfile.c man5_MANS += nfsmount.conf.man -EXTRA_DIST += nfsmount.conf +else +EXTRA_DIST += nfsmount.conf.man endif mount_nfs_LDADD = ../../support/nfs/libnfs.a \ diff --git a/utils/mountd/Makefile.am b/utils/mountd/Makefile.am index 7db968b..9e1ab5c 100644 --- a/utils/mountd/Makefile.am +++ b/utils/mountd/Makefile.am @@ -7,6 +7,7 @@ RPCPREFIX = rpc. KPREFIX = @kprefix@ sbin_PROGRAMS = mountd +noinst_HEADERS = fsloc.h mountd_SOURCES = mountd.c mount_dispatch.c auth.c rmtab.c cache.c \ svc_run.c fsloc.c v4root.c mountd.h mountd_LDADD = ../../support/export/libexport.a \ diff --git a/utils/nfsd/Makefile.am b/utils/nfsd/Makefile.am index 1536065..39a6e6f 100644 --- a/utils/nfsd/Makefile.am +++ b/utils/nfsd/Makefile.am @@ -7,6 +7,7 @@ RPCPREFIX = rpc. KPREFIX = @kprefix@ sbin_PROGRAMS = nfsd +noinst_HEADERS = nfssvc.h nfsd_SOURCES = nfsd.c nfssvc.c nfsd_LDADD = ../../support/nfs/libnfs.a $(LIBTIRPC) diff --git a/utils/nfsdcltrack/Makefile.am b/utils/nfsdcltrack/Makefile.am index a860ffb..d603f92 100644 --- a/utils/nfsdcltrack/Makefile.am +++ b/utils/nfsdcltrack/Makefile.am @@ -6,6 +6,8 @@ EXTRA_DIST = $(man8_MANS) AM_CFLAGS += -D_LARGEFILE64_SOURCE sbin_PROGRAMS = nfsdcltrack +noinst_HEADERS = sqlite.h + nfsdcltrack_SOURCES = nfsdcltrack.c sqlite.c nfsdcltrack_LDADD = ../../support/nfs/libnfs.a $(LIBSQLITE) $(LIBCAP) diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c index 4334340..fcdda7f 100644 --- a/utils/nfsdcltrack/nfsdcltrack.c +++ b/utils/nfsdcltrack/nfsdcltrack.c @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef HAVE_SYS_CAPABILITY_H #include #include @@ -49,6 +50,8 @@ #define CLD_DEFAULT_STORAGEDIR NFS_STATEDIR "/nfsdcltrack" #endif +#define NFSD_END_GRACE_FILE "/proc/fs/nfsd/v4_end_grace" + /* defined by RFC 3530 */ #define NFS4_OPAQUE_LIMIT 1024 @@ -210,6 +213,64 @@ cltrack_set_caps(void) return ret; } +/* Inform the kernel that it's OK to lift nfsd's grace period */ +static void +cltrack_lift_grace_period(void) +{ + int fd; + + fd = open(NFSD_END_GRACE_FILE, O_WRONLY); + if (fd < 0) { + /* Don't warn if file isn't present */ + if (errno != ENOENT) + xlog(L_WARNING, "Unable to open %s: %m", + NFSD_END_GRACE_FILE); + return; + } + + if (write(fd, "Y", 1) < 0) + xlog(L_WARNING, "Unable to write to %s: %m", + NFSD_END_GRACE_FILE); + + close(fd); + return; +} + +/* + * Fetch the contents of the NFSDCLTRACK_GRACE_START env var. If it's not set + * or there's an error converting it to time_t, then return LONG_MAX. + */ +static time_t +cltrack_get_grace_start(void) +{ + time_t grace_start; + char *end; + char *grace_start_str = getenv("NFSDCLTRACK_GRACE_START"); + + if (!grace_start_str) + return LONG_MAX; + + errno = 0; + grace_start = strtol(grace_start_str, &end, 0); + /* Problem converting or value is too large? */ + if (errno) + return LONG_MAX; + + return grace_start; +} + +static bool +cltrack_reclaims_complete(void) +{ + time_t grace_start = cltrack_get_grace_start(); + + /* Don't query DB if we didn't get a valid boot time */ + if (grace_start == LONG_MAX) + return false; + + return !sqlite_query_reclaiming(grace_start); +} + static int cltrack_init(const char __attribute__((unused)) *unused) { @@ -241,7 +302,7 @@ cltrack_init(const char __attribute__((unused)) *unused) } /* set up storage db */ - ret = sqlite_maindb_init(storagedir); + ret = sqlite_prepare_dbh(storagedir); if (ret) { xlog(L_ERROR, "Failed to init database: %d", ret); /* @@ -250,15 +311,36 @@ cltrack_init(const char __attribute__((unused)) *unused) * stop upcalling until the problem is resolved. */ ret = -EACCES; + } else { + if (cltrack_reclaims_complete()) + cltrack_lift_grace_period(); } + return ret; } +/* + * Fetch the contents of the NFSDCLTRACK_CLIENT_HAS_SESSION env var. If + * it's set and the first character is 'Y' then return true. Otherwise + * return false. + */ +static bool +cltrack_client_has_session(void) +{ + char *has_session = getenv("NFSDCLTRACK_CLIENT_HAS_SESSION"); + + if (has_session && *has_session == 'Y') + return true; + + return false; +} + static int cltrack_create(const char *id) { int ret; ssize_t len; + bool has_session; xlog(D_GENERAL, "%s: create client record.", __func__); @@ -270,7 +352,12 @@ cltrack_create(const char *id) if (len < 0) return (int)len; - ret = sqlite_insert_client(blob, len); + has_session = cltrack_client_has_session(); + + ret = sqlite_insert_client(blob, len, has_session, false); + + if (!ret && has_session && cltrack_reclaims_complete()) + cltrack_lift_grace_period(); return ret ? -EREMOTEIO : ret; } @@ -297,7 +384,8 @@ cltrack_remove(const char *id) } static int -cltrack_check_legacy(const unsigned char *blob, const ssize_t len) +cltrack_check_legacy(const unsigned char *blob, const ssize_t len, + bool has_session) { int ret; struct stat st; @@ -323,7 +411,7 @@ cltrack_check_legacy(const unsigned char *blob, const ssize_t len) } /* Dir exists, try to insert record into db */ - ret = sqlite_insert_client(blob, len); + ret = sqlite_insert_client(blob, len, has_session, has_session); if (ret) { xlog(D_GENERAL, "Failed to insert client: %d", ret); return -EREMOTEIO; @@ -343,6 +431,7 @@ cltrack_check(const char *id) { int ret; ssize_t len; + bool has_session; xlog(D_GENERAL, "%s: check client record", __func__); @@ -354,9 +443,11 @@ cltrack_check(const char *id) if (len < 0) return (int)len; - ret = sqlite_check_client(blob, len); + has_session = cltrack_client_has_session(); + + ret = sqlite_check_client(blob, len, has_session); if (ret) - ret = cltrack_check_legacy(blob, len); + ret = cltrack_check_legacy(blob, len, has_session); return ret ? -EPERM : ret; } diff --git a/utils/nfsdcltrack/sqlite.c b/utils/nfsdcltrack/sqlite.c index bac6789..eb1711a 100644 --- a/utils/nfsdcltrack/sqlite.c +++ b/utils/nfsdcltrack/sqlite.c @@ -21,17 +21,15 @@ * Explanation: * * This file contains the code to manage the sqlite backend database for the - * clstated upcall daemon. + * nfsdcltrack usermodehelper upcall program. * * The main database is called main.sqlite and contains the following tables: * * parameters: simple key/value pairs for storing database info * - * clients: one column containing a BLOB with the as sent by the client - * and a timestamp (in epoch seconds) of when the record was - * established - * - * FIXME: should we also record the fsid being accessed? + * clients: an "id" column containing a BLOB with the long-form clientid as + * sent by the client, a "time" column containing a timestamp (in + * epoch seconds) of when the record was last updated. */ #ifdef HAVE_CONFIG_H @@ -52,10 +50,10 @@ #include "xlog.h" -#define CLD_SQLITE_SCHEMA_VERSION 1 +#define CLTRACK_SQLITE_LATEST_SCHEMA_VERSION 1 /* in milliseconds */ -#define CLD_SQLITE_BUSY_TIMEOUT 10000 +#define CLTRACK_SQLITE_BUSY_TIMEOUT 10000 /* private data structures */ @@ -90,135 +88,192 @@ mkdir_if_not_exist(const char *dirname) return ret; } -/* Open the database and set up the database handle for it */ -int -sqlite_prepare_dbh(const char *topdir) +static int +sqlite_query_schema_version(void) { int ret; + sqlite3_stmt *stmt = NULL; - /* Do nothing if the database handle is already set up */ - if (dbh) - return 0; - - ret = snprintf(buf, PATH_MAX - 1, "%s/main.sqlite", topdir); - if (ret < 0) - return ret; - - buf[PATH_MAX - 1] = '\0'; - - ret = sqlite3_open(buf, &dbh); + /* prepare select query */ + ret = sqlite3_prepare_v2(dbh, + "SELECT value FROM parameters WHERE key == \"version\";", + -1, &stmt, NULL); if (ret != SQLITE_OK) { - xlog(L_ERROR, "Unable to open main database: %d", ret); - dbh = NULL; - return ret; + xlog(L_ERROR, "Unable to prepare select statement: %s", + sqlite3_errmsg(dbh)); + ret = 0; + goto out; } - ret = sqlite3_busy_timeout(dbh, CLD_SQLITE_BUSY_TIMEOUT); - if (ret != SQLITE_OK) { - xlog(L_ERROR, "Unable to set sqlite busy timeout: %d", ret); - sqlite3_close(dbh); - dbh = NULL; + /* query schema version */ + ret = sqlite3_step(stmt); + if (ret != SQLITE_ROW) { + xlog(L_ERROR, "Select statement execution failed: %s", + sqlite3_errmsg(dbh)); + ret = 0; + goto out; } + ret = sqlite3_column_int(stmt, 0); +out: + sqlite3_finalize(stmt); return ret; } /* - * Open the "main" database, and attempt to initialize it by creating the - * parameters table and inserting the schema version into it. Ignore any errors - * from that, and then attempt to select the version out of it again. If the - * version appears wrong, then assume that the DB is corrupt or has been - * upgraded, and return an error. If all of that works, then attempt to create - * the "clients" table. + * Start an exclusive transaction and recheck the DB schema version. If it's + * still zero (indicating a new database) then set it up. If that all works, + * then insert schema version into the parameters table and commit the + * transaction. On any error, rollback the transaction. */ int -sqlite_maindb_init(const char *topdir) +sqlite_maindb_init_v1(void) { int ret; char *err = NULL; - sqlite3_stmt *stmt = NULL; - ret = mkdir_if_not_exist(topdir); - if (ret) + /* Start a transaction */ + ret = sqlite3_exec(dbh, "BEGIN EXCLUSIVE TRANSACTION;", NULL, NULL, + &err); + if (ret != SQLITE_OK) { + xlog(L_ERROR, "Unable to begin transaction: %s", err); return ret; + } - ret = sqlite_prepare_dbh(topdir); - if (ret) - return ret; + /* + * Check schema version again. This time, under an exclusive + * transaction to guard against racing DB setup attempts + */ + ret = sqlite_query_schema_version(); + switch (ret) { + case 0: + /* Query failed again -- set up DB */ + break; + case CLTRACK_SQLITE_LATEST_SCHEMA_VERSION: + /* Someone else raced in and set it up */ + ret = 0; + goto rollback; + default: + /* Something went wrong -- fail! */ + ret = -EINVAL; + goto rollback; + } - /* Try to create table */ - ret = sqlite3_exec(dbh, "CREATE TABLE IF NOT EXISTS parameters " + ret = sqlite3_exec(dbh, "CREATE TABLE parameters " "(key TEXT PRIMARY KEY, value TEXT);", NULL, NULL, &err); if (ret != SQLITE_OK) { - xlog(L_ERROR, "Unable to create parameter table: %d", ret); - goto out_err; + xlog(L_ERROR, "Unable to create parameter table: %s", err); + goto rollback; } - /* insert version into table -- ignore error if it fails */ - ret = snprintf(buf, sizeof(buf), - "INSERT OR IGNORE INTO parameters values (\"version\", " - "\"%d\");", CLD_SQLITE_SCHEMA_VERSION); + /* create the "clients" table */ + ret = sqlite3_exec(dbh, "CREATE TABLE clients (id BLOB PRIMARY KEY, " + "time INTEGER);", + NULL, NULL, &err); + if (ret != SQLITE_OK) { + xlog(L_ERROR, "Unable to create clients table: %s", err); + goto rollback; + } + + + /* insert version into parameters table */ + ret = snprintf(buf, sizeof(buf), "INSERT OR FAIL INTO parameters " + "values (\"version\", \"%d\");", + CLTRACK_SQLITE_LATEST_SCHEMA_VERSION); if (ret < 0) { - goto out_err; + xlog(L_ERROR, "sprintf failed!"); + goto rollback; } else if ((size_t)ret >= sizeof(buf)) { + xlog(L_ERROR, "sprintf output too long! (%d chars)", ret); ret = -EINVAL; - goto out_err; + goto rollback; } ret = sqlite3_exec(dbh, (const char *)buf, NULL, NULL, &err); if (ret != SQLITE_OK) { - xlog(L_ERROR, "Unable to insert into parameter table: %d", - ret); - goto out_err; + xlog(L_ERROR, "Unable to insert into parameter table: %s", err); + goto rollback; } - ret = sqlite3_prepare_v2(dbh, - "SELECT value FROM parameters WHERE key == \"version\";", - -1, &stmt, NULL); + ret = sqlite3_exec(dbh, "COMMIT TRANSACTION;", NULL, NULL, &err); if (ret != SQLITE_OK) { - xlog(L_ERROR, "Unable to prepare select statement: %d", ret); - goto out_err; + xlog(L_ERROR, "Unable to commit transaction: %s", err); + goto rollback; } +out: + sqlite3_free(err); + return ret; - /* check schema version */ - ret = sqlite3_step(stmt); - if (ret != SQLITE_ROW) { - xlog(L_ERROR, "Select statement execution failed: %s", +rollback: + /* Attempt to rollback the transaction */ + sqlite3_exec(dbh, "ROLLBACK TRANSACTION;", NULL, NULL, &err); + goto out; +} + +/* Open the database and set up the database handle for it */ +int +sqlite_prepare_dbh(const char *topdir) +{ + int ret; + + /* Do nothing if the database handle is already set up */ + if (dbh) + return 0; + + ret = snprintf(buf, PATH_MAX - 1, "%s/main.sqlite", topdir); + if (ret < 0) + return ret; + + buf[PATH_MAX - 1] = '\0'; + + /* open a new DB handle */ + ret = sqlite3_open(buf, &dbh); + if (ret != SQLITE_OK) { + /* try to create the dir */ + ret = mkdir_if_not_exist(topdir); + if (ret) + goto out_close; + + /* retry open */ + ret = sqlite3_open(buf, &dbh); + if (ret != SQLITE_OK) + goto out_close; + } + + /* set busy timeout */ + ret = sqlite3_busy_timeout(dbh, CLTRACK_SQLITE_BUSY_TIMEOUT); + if (ret != SQLITE_OK) { + xlog(L_ERROR, "Unable to set sqlite busy timeout: %s", sqlite3_errmsg(dbh)); - goto out_err; + goto out_close; } - /* process SELECT result */ - ret = sqlite3_column_int(stmt, 0); - if (ret != CLD_SQLITE_SCHEMA_VERSION) { + ret = sqlite_query_schema_version(); + switch (ret) { + case CLTRACK_SQLITE_LATEST_SCHEMA_VERSION: + /* DB is already set up. Do nothing */ + ret = 0; + break; + case 0: + /* Query failed -- try to set up new DB */ + ret = sqlite_maindb_init_v1(); + if (ret) + goto out_close; + break; + default: + /* Unknown DB version -- downgrade? Fail */ xlog(L_ERROR, "Unsupported database schema version! " "Expected %d, got %d.", - CLD_SQLITE_SCHEMA_VERSION, ret); + CLTRACK_SQLITE_LATEST_SCHEMA_VERSION, ret); ret = -EINVAL; - goto out_err; - } - - /* now create the "clients" table */ - ret = sqlite3_exec(dbh, "CREATE TABLE IF NOT EXISTS clients " - "(id BLOB PRIMARY KEY, time INTEGER);", - NULL, NULL, &err); - if (ret != SQLITE_OK) { - xlog(L_ERROR, "Unable to create clients table: %s", err); - goto out_err; + goto out_close; } - sqlite3_free(err); - sqlite3_finalize(stmt); - return 0; - -out_err: - if (err) { - xlog(L_ERROR, "sqlite error: %s", err); - sqlite3_free(err); - } - sqlite3_finalize(stmt); + return ret; +out_close: sqlite3_close(dbh); + dbh = NULL; return ret; } @@ -228,14 +283,20 @@ out_err: * Returns a non-zero sqlite error code, or SQLITE_OK (aka 0) */ int -sqlite_insert_client(const unsigned char *clname, const size_t namelen) +sqlite_insert_client(const unsigned char *clname, const size_t namelen, + const bool has_session, const bool zerotime) { int ret; sqlite3_stmt *stmt = NULL; - ret = sqlite3_prepare_v2(dbh, "INSERT OR REPLACE INTO clients VALUES " - "(?, strftime('%s', 'now'));", -1, - &stmt, NULL); + if (zerotime) + ret = sqlite3_prepare_v2(dbh, "INSERT OR REPLACE INTO clients " + "VALUES (?, 0, ?);", -1, &stmt, NULL); + else + ret = sqlite3_prepare_v2(dbh, "INSERT OR REPLACE INTO clients " + "VALUES (?, strftime('%s', 'now'), ?);", -1, + &stmt, NULL); + if (ret != SQLITE_OK) { xlog(L_ERROR, "%s: insert statement prepare failed: %s", __func__, sqlite3_errmsg(dbh)); @@ -250,6 +311,13 @@ sqlite_insert_client(const unsigned char *clname, const size_t namelen) goto out_err; } + ret = sqlite3_bind_int(stmt, 2, (int)has_session); + if (ret != SQLITE_OK) { + xlog(L_ERROR, "%s: bind int failed: %s", __func__, + sqlite3_errmsg(dbh)); + goto out_err; + } + ret = sqlite3_step(stmt); if (ret == SQLITE_DONE) ret = SQLITE_OK; @@ -305,7 +373,8 @@ out_err: * return an error. */ int -sqlite_check_client(const unsigned char *clname, const size_t namelen) +sqlite_check_client(const unsigned char *clname, const size_t namelen, + const bool has_session) { int ret; sqlite3_stmt *stmt = NULL; @@ -340,6 +409,12 @@ sqlite_check_client(const unsigned char *clname, const size_t namelen) goto out_err; } + /* Only update timestamp for v4.0 clients */ + if (has_session) { + ret = SQLITE_OK; + goto out_err; + } + sqlite3_finalize(stmt); stmt = NULL; ret = sqlite3_prepare_v2(dbh, "UPDATE OR FAIL clients SET " @@ -398,3 +473,43 @@ sqlite_remove_unreclaimed(time_t grace_start) sqlite3_free(err); return ret; } + +/* + * Are there any clients that are possibly still reclaiming? Return a positive + * integer (usually number of clients) if so. If not, then return 0. On any + * error, return non-zero. + */ +int +sqlite_query_reclaiming(const time_t grace_start) +{ + int ret; + sqlite3_stmt *stmt = NULL; + + ret = sqlite3_prepare_v2(dbh, "SELECT count(*) FROM clients WHERE " + "time < ? OR has_session != 1", -1, &stmt, NULL); + if (ret != SQLITE_OK) { + xlog(L_ERROR, "%s: unable to prepare select statement: %s", + __func__, sqlite3_errmsg(dbh)); + return ret; + } + + ret = sqlite3_bind_int64(stmt, 1, (sqlite3_int64)grace_start); + if (ret != SQLITE_OK) { + xlog(L_ERROR, "%s: bind int64 failed: %s", + __func__, sqlite3_errmsg(dbh)); + return ret; + } + + ret = sqlite3_step(stmt); + if (ret != SQLITE_ROW) { + xlog(L_ERROR, "%s: unexpected return code from select: %s", + __func__, sqlite3_errmsg(dbh)); + return ret; + } + + ret = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + xlog(D_GENERAL, "%s: there are %d clients that have not completed " + "reclaim", __func__, ret); + return ret; +} diff --git a/utils/nfsdcltrack/sqlite.h b/utils/nfsdcltrack/sqlite.h index ebf04c3..06e7c04 100644 --- a/utils/nfsdcltrack/sqlite.h +++ b/utils/nfsdcltrack/sqlite.h @@ -21,10 +21,12 @@ #define _SQLITE_H_ int sqlite_prepare_dbh(const char *topdir); -int sqlite_maindb_init(const char *topdir); -int sqlite_insert_client(const unsigned char *clname, const size_t namelen); +int sqlite_insert_client(const unsigned char *clname, const size_t namelen, + const bool has_session, const bool zerotime); int sqlite_remove_client(const unsigned char *clname, const size_t namelen); -int sqlite_check_client(const unsigned char *clname, const size_t namelen); +int sqlite_check_client(const unsigned char *clname, const size_t namelen, + const bool has_session); int sqlite_remove_unreclaimed(const time_t grace_start); +int sqlite_query_reclaiming(const time_t grace_start); #endif /* _SQLITE_H */ diff --git a/utils/nfsidmap/Makefile.am b/utils/nfsidmap/Makefile.am index 737a219..91cedfd 100644 --- a/utils/nfsidmap/Makefile.am +++ b/utils/nfsidmap/Makefile.am @@ -7,4 +7,4 @@ nfsidmap_SOURCES = nfsidmap.c nfsidmap_LDADD = $(LIBNFSIDMAP) -lkeyutils ../../support/nfs/libnfs.a MAINTAINERCLEANFILES = Makefile.in -EXTRA_DIST = id_resolver.conf +EXTRA_DIST = id_resolver.conf $(man8_MANS) diff --git a/utils/osd_login/Makefile.am b/utils/osd_login/Makefile.am index 20c2d8c..ded1fd3 100644 --- a/utils/osd_login/Makefile.am +++ b/utils/osd_login/Makefile.am @@ -4,6 +4,6 @@ # overridden at config time. sbindir = /sbin -sbin_SCRIPTS = osd_login +dist_sbin_SCRIPTS = osd_login MAINTAINERCLEANFILES = Makefile.in diff --git a/utils/statd/Makefile.am b/utils/statd/Makefile.am index dc2bfc4..152b680 100644 --- a/utils/statd/Makefile.am +++ b/utils/statd/Makefile.am @@ -8,7 +8,7 @@ sbin_PROGRAMS = statd sm-notify dist_sbin_SCRIPTS = start-statd statd_SOURCES = callback.c notlist.c misc.c monitor.c hostname.c \ simu.c stat.c statd.c svc_run.c rmtcall.c \ - notlist.h statd.h system.h version.h + notlist.h statd.h system.h sm_notify_SOURCES = sm-notify.c BUILT_SOURCES = $(GENFILES) @@ -20,7 +20,7 @@ sm_notify_LDADD = ../../support/nsm/libnsm.a \ ../../support/nfs/libnfs.a \ $(LIBNSL) $(LIBCAP) $(LIBTIRPC) -EXTRA_DIST = sim_sm_inter.x $(man8_MANS) COPYRIGHT simulate.c +EXTRA_DIST = sim_sm_inter.x $(man8_MANS) simulate.c if CONFIG_RPCGEN RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen