All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] RFC: Reexport state database backend plugin support
@ 2022-05-18 23:05 Richard Weinberger
  0 siblings, 0 replies; only message in thread
From: Richard Weinberger @ 2022-05-18 23:05 UTC (permalink / raw)
  To: linux-nfs
  Cc: david, bfields, luis.turcitu, david.young, david.oberhollenzer,
	trond.myklebust, anna.schumaker, chris.chilvers, steved,
	Richard Weinberger

Since I talked about the feature already I though it is time to show some code.

sqlite is not a perfect fit for everyone.
Especially when the re-exporting NFS server is part of a load balancer,
a more sophisticated distributed database is preferable.
This RFC patch implements support for different databases using a simple
plugin interface on top of my previous patch series.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 support/reexport/Makefile.am        |   7 +
 support/reexport/backend_sqlite.c   | 251 ++++++++++++++++++++++++++++
 support/reexport/reexport.c         | 237 +++-----------------------
 support/reexport/reexport_backend.h |  48 ++++++
 systemd/Makefile.am                 |   2 +-
 systemd/nfs.conf.man                |   5 +-
 utils/exportd/Makefile.am           |   2 +-
 utils/exportfs/Makefile.am          |   2 +-
 utils/mount/Makefile.am             |   4 +-
 utils/mountd/Makefile.am            |   2 +-
 10 files changed, 335 insertions(+), 225 deletions(-)
 create mode 100644 support/reexport/backend_sqlite.c
 create mode 100644 support/reexport/reexport_backend.h

diff --git a/support/reexport/Makefile.am b/support/reexport/Makefile.am
index 9d544a8f..d45007be 100644
--- a/support/reexport/Makefile.am
+++ b/support/reexport/Makefile.am
@@ -3,4 +3,11 @@
 noinst_LIBRARIES = libreexport.a
 libreexport_a_SOURCES = reexport.c
 
+pkgplugindir=$(libdir)/libnfsreexport_backends/
+pkgplugin_LTLIBRARIES = sqlite.la
+
+sqlite_la_SOURCES = backend_sqlite.c
+sqlite_la_LDFLAGS = -module -avoid-version
+sqlite_la_LIBADD = ../../support/nfs/libnfsconf.la $(LIBSQLITE)
+
 MAINTAINERCLEANFILES = Makefile.in
diff --git a/support/reexport/backend_sqlite.c b/support/reexport/backend_sqlite.c
new file mode 100644
index 00000000..a54d64ea
--- /dev/null
+++ b/support/reexport/backend_sqlite.c
@@ -0,0 +1,251 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sqlite3.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/random.h>
+#include <unistd.h>
+
+#include "conffile.h"
+#include "reexport_backend.h"
+#include "xlog.h"
+
+#define REEXPDB_DBFILE NFS_STATEDIR "/reexpdb.sqlite3"
+#define REEXPDB_DBFILE_WAIT_USEC (5000)
+
+static sqlite3 *db;
+static int init_done;
+
+static int prng_init(void)
+{
+	int seed;
+
+	if (getrandom(&seed, sizeof(seed), 0) != sizeof(seed)) {
+		xlog(L_ERROR, "Unable to obtain seed for PRNG via getrandom()");
+		return -1;
+	}
+
+	srand(seed);
+	return 0;
+}
+
+static void wait_for_dbaccess(void)
+{
+	usleep(REEXPDB_DBFILE_WAIT_USEC + (rand() % REEXPDB_DBFILE_WAIT_USEC));
+}
+
+static bool sqlite_plug_init(void)
+{
+	char *sqlerr;
+	int ret;
+
+	if (init_done)
+		return true;
+
+	if (prng_init() != 0)
+		return false;
+
+	ret = sqlite3_open_v2(conf_get_str_with_def("reexport", "sqlitedb", REEXPDB_DBFILE),
+			      &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX,
+			      NULL);
+	if (ret != SQLITE_OK) {
+		xlog(L_ERROR, "Unable to open reexport database: %s", sqlite3_errstr(ret));
+		return false;
+	}
+
+again:
+	ret = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS fsidnums (num INTEGER PRIMARY KEY CHECK (num > 0 AND num < 4294967296), path TEXT UNIQUE); CREATE INDEX IF NOT EXISTS idx_ids_path ON fsidnums (path);", NULL, NULL, &sqlerr);
+	switch (ret) {
+	case SQLITE_OK:
+		init_done = 1;
+		ret = 0;
+		break;
+	case SQLITE_BUSY:
+	case SQLITE_LOCKED:
+		wait_for_dbaccess();
+		goto again;
+	default:
+		xlog(L_ERROR, "Unable to init reexport database: %s", sqlite3_errstr(ret));
+		sqlite3_free(sqlerr);
+		sqlite3_close_v2(db);
+		ret = -1;
+	}
+
+	return ret == 0 ? true : false;
+}
+
+static void sqlite_plug_destroy(void)
+{
+	if (!init_done)
+		return;
+
+	sqlite3_close_v2(db);
+}
+
+static bool get_fsidnum_by_path(char *path, uint32_t *fsidnum)
+{
+	static const char fsidnum_by_path_sql[] = "SELECT num FROM fsidnums WHERE path = ?1;";
+	sqlite3_stmt *stmt = NULL;
+	bool found = false;
+	int ret;
+
+	ret = sqlite3_prepare_v2(db, fsidnum_by_path_sql, sizeof(fsidnum_by_path_sql), &stmt, NULL);
+	if (ret != SQLITE_OK) {
+		xlog(L_WARNING, "Unable to prepare SQL query '%s': %s", fsidnum_by_path_sql, sqlite3_errstr(ret));
+		goto out;
+	}
+
+	ret = sqlite3_bind_text(stmt, 1, path, -1, NULL);
+	if (ret != SQLITE_OK) {
+		xlog(L_WARNING, "Unable to bind SQL query '%s': %s", fsidnum_by_path_sql, sqlite3_errstr(ret));
+		goto out;
+	}
+
+again:
+	ret = sqlite3_step(stmt);
+	switch (ret) {
+	case SQLITE_ROW:
+		*fsidnum = sqlite3_column_int(stmt, 0);
+		found = true;
+		break;
+	case SQLITE_DONE:
+		/* No hit */
+		found = false;
+		break;
+	case SQLITE_BUSY:
+	case SQLITE_LOCKED:
+		wait_for_dbaccess();
+		goto again;
+	default:
+		xlog(L_WARNING, "Error while looking up '%s' in database: %s", path, sqlite3_errstr(ret));
+	}
+
+out:
+	sqlite3_finalize(stmt);
+	return found;
+}
+
+static bool sqlite_plug_path_by_fsidnum(uint32_t fsidnum, char **path)
+{
+	static const char path_by_fsidnum_sql[] = "SELECT path FROM fsidnums WHERE num = ?1;";
+	sqlite3_stmt *stmt = NULL;
+	bool found = false;
+	int ret;
+
+	ret = sqlite3_prepare_v2(db, path_by_fsidnum_sql, sizeof(path_by_fsidnum_sql), &stmt, NULL);
+	if (ret != SQLITE_OK) {
+		xlog(L_WARNING, "Unable to prepare SQL query '%s': %s", path_by_fsidnum_sql, sqlite3_errstr(ret));
+		goto out;
+	}
+
+	ret = sqlite3_bind_int(stmt, 1, fsidnum);
+	if (ret != SQLITE_OK) {
+		xlog(L_WARNING, "Unable to bind SQL query '%s': %s", path_by_fsidnum_sql, sqlite3_errstr(ret));
+		goto out;
+	}
+
+again:
+	ret = sqlite3_step(stmt);
+	switch (ret) {
+	case SQLITE_ROW:
+		*path = strdup((char *)sqlite3_column_text(stmt, 0));
+		if (*path)
+			found = true;
+		break;
+	case SQLITE_DONE:
+		/* No hit */
+		found = false;
+		break;
+	case SQLITE_BUSY:
+	case SQLITE_LOCKED:
+		wait_for_dbaccess();
+		goto again;
+	default:
+		xlog(L_WARNING, "Error while looking up '%i' in database: %s", fsidnum, sqlite3_errstr(ret));
+	}
+
+out:
+	sqlite3_finalize(stmt);
+	return found;
+}
+
+static bool new_fsidnum_by_path(char *path, uint32_t *fsidnum)
+{
+	/*
+	 * This query is a little tricky. We use SQL to find and claim the smallest free fsid number.
+	 * To find a free fsid the fsidnums is left joined to itself but with an offset of 1.
+	 * Everything after the UNION statement is to handle the corner case where fsidnums
+	 * is empty. In this case we want 1 as first fsid number.
+	 */
+	static const char new_fsidnum_by_path_sql[] = "INSERT INTO fsidnums VALUES ((SELECT ids1.num + 1 FROM fsidnums AS ids1 LEFT JOIN fsidnums AS ids2 ON ids2.num = ids1.num + 1 WHERE ids2.num IS NULL UNION SELECT 1 WHERE NOT EXISTS (SELECT NULL FROM fsidnums WHERE num = 1) LIMIT 1), ?1) RETURNING num;";
+
+	sqlite3_stmt *stmt = NULL;
+	int ret, check = 0;
+	bool found = false;
+
+	ret = sqlite3_prepare_v2(db, new_fsidnum_by_path_sql, sizeof(new_fsidnum_by_path_sql), &stmt, NULL);
+	if (ret != SQLITE_OK) {
+		xlog(L_WARNING, "Unable to prepare SQL query '%s': %s", new_fsidnum_by_path_sql, sqlite3_errstr(ret));
+		goto out;
+	}
+
+	ret = sqlite3_bind_text(stmt, 1, path, -1, NULL);
+	if (ret != SQLITE_OK) {
+		xlog(L_WARNING, "Unable to bind SQL query '%s': %s", new_fsidnum_by_path_sql, sqlite3_errstr(ret));
+		goto out;
+	}
+
+again:
+	ret = sqlite3_step(stmt);
+	switch (ret) {
+	case SQLITE_ROW:
+		*fsidnum = sqlite3_column_int(stmt, 0);
+		found = true;
+		break;
+	case SQLITE_CONSTRAINT:
+		/* Maybe we lost the race against another writer and the path is now present. */
+		check = 1;
+		break;
+	case SQLITE_BUSY:
+	case SQLITE_LOCKED:
+		wait_for_dbaccess();
+		goto again;
+	default:
+		xlog(L_WARNING, "Error while looking up '%s' in database: %s", path, sqlite3_errstr(ret));
+	}
+
+out:
+	sqlite3_finalize(stmt);
+
+	if (check) {
+		found = get_fsidnum_by_path(path, fsidnum);
+		if (!found)
+			xlog(L_WARNING, "SQLITE_CONSTRAINT error while inserting '%s' in database", path);
+	}
+
+	return found;
+}
+
+static bool sqlite_plug_fsidnum_by_path(char *path, uint32_t *fsidnum, int may_create)
+{
+	bool found;
+
+	found = get_fsidnum_by_path(path, fsidnum);
+
+	if (!found && may_create)
+		found = new_fsidnum_by_path(path, fsidnum);
+
+	return found;
+}
+
+struct reexpdb_backend_plugin plug_ops = {
+	.fsidnum_by_path = sqlite_plug_fsidnum_by_path,
+	.path_by_fsidnum = sqlite_plug_path_by_fsidnum,
+	.initdb = sqlite_plug_init,
+	.destroydb = sqlite_plug_destroy,
+};
+
diff --git a/support/reexport/reexport.c b/support/reexport/reexport.c
index 61574fc5..112fcfb9 100644
--- a/support/reexport/reexport.c
+++ b/support/reexport/reexport.c
@@ -2,7 +2,7 @@
 #include <config.h>
 #endif
 
-#include <sqlite3.h>
+#include <dlfcn.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <sys/random.h>
@@ -15,228 +15,38 @@
 #include "conffile.h"
 #include "nfslib.h"
 #include "reexport.h"
+#include "reexport_backend.h"
 #include "xcommon.h"
 #include "xlog.h"
 
-#define REEXPDB_DBFILE NFS_STATEDIR "/reexpdb.sqlite3"
-#define REEXPDB_DBFILE_WAIT_USEC (5000)
+struct reexpdb_backend_plugin *plg;
+static void *backend_dl;
 
-static sqlite3 *db;
-static int init_done;
-
-static int prng_init(void)
-{
-	int seed;
-
-	if (getrandom(&seed, sizeof(seed), 0) != sizeof(seed)) {
-		xlog(L_ERROR, "Unable to obtain seed for PRNG via getrandom()");
-		return -1;
-	}
-
-	srand(seed);
-	return 0;
-}
-
-static void wait_for_dbaccess(void)
-{
-	usleep(REEXPDB_DBFILE_WAIT_USEC + (rand() % REEXPDB_DBFILE_WAIT_USEC));
-}
-
-/*
- * reexpdb_init - Initialize reexport database
- */
 int reexpdb_init(void)
 {
-	char *sqlerr;
-	int ret;
-
-	if (init_done)
-		return 0;
+	char *sofile = conf_get_str_with_def("reexport", "backend_plugin", REEXPDB_BACKEND_DEFAULT);
 
-	if (prng_init() != 0)
-		return -1;
-
-	ret = sqlite3_open_v2(conf_get_str_with_def("reexport", "sqlitedb", REEXPDB_DBFILE),
-			      &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX,
-			      NULL);
-	if (ret != SQLITE_OK) {
-		xlog(L_ERROR, "Unable to open reexport database: %s", sqlite3_errstr(ret));
+	backend_dl = dlopen(sofile, RTLD_NOW | RTLD_LOCAL);
+	if (!backend_dl) {
+		xlog(L_WARNING, "Unable to open %s: %s", sofile, dlerror());
 		return -1;
 	}
 
-again:
-	ret = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS fsidnums (num INTEGER PRIMARY KEY CHECK (num > 0 AND num < 4294967296), path TEXT UNIQUE); CREATE INDEX IF NOT EXISTS idx_ids_path ON fsidnums (path);", NULL, NULL, &sqlerr);
-	switch (ret) {
-	case SQLITE_OK:
-		init_done = 1;
-		ret = 0;
-		break;
-	case SQLITE_BUSY:
-	case SQLITE_LOCKED:
-		wait_for_dbaccess();
-		goto again;
-	default:
-		xlog(L_ERROR, "Unable to init reexport database: %s", sqlite3_errstr(ret));
-		sqlite3_free(sqlerr);
-		sqlite3_close_v2(db);
-		ret = -1;
+	plg = (struct reexpdb_backend_plugin *)dlsym(backend_dl, REEXPDB_BACKEND_OPS);
+	if (plg == NULL) {
+		xlog(L_WARNING, "Unable to locate plug_ops in %s: %s", sofile, dlerror());
+		dlclose(backend_dl);
+		return -1;
 	}
 
-	return ret;
+	return plg->initdb() == true;
 }
 
-/*
- * reexpdb_destroy - Undo reexpdb_init().
- */
 void reexpdb_destroy(void)
 {
-	if (!init_done)
-		return;
-
-	sqlite3_close_v2(db);
-}
-
-static int get_fsidnum_by_path(char *path, uint32_t *fsidnum)
-{
-	static const char fsidnum_by_path_sql[] = "SELECT num FROM fsidnums WHERE path = ?1;";
-	sqlite3_stmt *stmt = NULL;
-	int found = 0;
-	int ret;
-
-	ret = sqlite3_prepare_v2(db, fsidnum_by_path_sql, sizeof(fsidnum_by_path_sql), &stmt, NULL);
-	if (ret != SQLITE_OK) {
-		xlog(L_WARNING, "Unable to prepare SQL query '%s': %s", fsidnum_by_path_sql, sqlite3_errstr(ret));
-		goto out;
-	}
-
-	ret = sqlite3_bind_text(stmt, 1, path, -1, NULL);
-	if (ret != SQLITE_OK) {
-		xlog(L_WARNING, "Unable to bind SQL query '%s': %s", fsidnum_by_path_sql, sqlite3_errstr(ret));
-		goto out;
-	}
-
-again:
-	ret = sqlite3_step(stmt);
-	switch (ret) {
-	case SQLITE_ROW:
-		*fsidnum = sqlite3_column_int(stmt, 0);
-		found = 1;
-		break;
-	case SQLITE_DONE:
-		/* No hit */
-		found = 0;
-		break;
-	case SQLITE_BUSY:
-	case SQLITE_LOCKED:
-		wait_for_dbaccess();
-		goto again;
-	default:
-		xlog(L_WARNING, "Error while looking up '%s' in database: %s", path, sqlite3_errstr(ret));
-	}
-
-out:
-	sqlite3_finalize(stmt);
-	return found;
-}
-
-static int get_path_by_fsidnum(uint32_t fsidnum, char **path)
-{
-	static const char path_by_fsidnum_sql[] = "SELECT path FROM fsidnums WHERE num = ?1;";
-	sqlite3_stmt *stmt = NULL;
-	int found = 0;
-	int ret;
-
-	ret = sqlite3_prepare_v2(db, path_by_fsidnum_sql, sizeof(path_by_fsidnum_sql), &stmt, NULL);
-	if (ret != SQLITE_OK) {
-		xlog(L_WARNING, "Unable to prepare SQL query '%s': %s", path_by_fsidnum_sql, sqlite3_errstr(ret));
-		goto out;
-	}
-
-	ret = sqlite3_bind_int(stmt, 1, fsidnum);
-	if (ret != SQLITE_OK) {
-		xlog(L_WARNING, "Unable to bind SQL query '%s': %s", path_by_fsidnum_sql, sqlite3_errstr(ret));
-		goto out;
-	}
-
-again:
-	ret = sqlite3_step(stmt);
-	switch (ret) {
-	case SQLITE_ROW:
-		*path = xstrdup((char *)sqlite3_column_text(stmt, 0));
-		found = 1;
-		break;
-	case SQLITE_DONE:
-		/* No hit */
-		found = 0;
-		break;
-	case SQLITE_BUSY:
-	case SQLITE_LOCKED:
-		wait_for_dbaccess();
-		goto again;
-	default:
-		xlog(L_WARNING, "Error while looking up '%i' in database: %s", fsidnum, sqlite3_errstr(ret));
-	}
-
-out:
-	sqlite3_finalize(stmt);
-	return found;
-}
-
-static int new_fsidnum_by_path(char *path, uint32_t *fsidnum)
-{
-	/*
-	 * This query is a little tricky. We use SQL to find and claim the smallest free fsid number.
-	 * To find a free fsid the fsidnums is left joined to itself but with an offset of 1.
-	 * Everything after the UNION statement is to handle the corner case where fsidnums
-	 * is empty. In this case we want 1 as first fsid number.
-	 */
-	static const char new_fsidnum_by_path_sql[] = "INSERT INTO fsidnums VALUES ((SELECT ids1.num + 1 FROM fsidnums AS ids1 LEFT JOIN fsidnums AS ids2 ON ids2.num = ids1.num + 1 WHERE ids2.num IS NULL UNION SELECT 1 WHERE NOT EXISTS (SELECT NULL FROM fsidnums WHERE num = 1) LIMIT 1), ?1) RETURNING num;";
-
-	sqlite3_stmt *stmt = NULL;
-	int found = 0, check = 0;
-	int ret;
-
-	ret = sqlite3_prepare_v2(db, new_fsidnum_by_path_sql, sizeof(new_fsidnum_by_path_sql), &stmt, NULL);
-	if (ret != SQLITE_OK) {
-		xlog(L_WARNING, "Unable to prepare SQL query '%s': %s", new_fsidnum_by_path_sql, sqlite3_errstr(ret));
-		goto out;
-	}
-
-	ret = sqlite3_bind_text(stmt, 1, path, -1, NULL);
-	if (ret != SQLITE_OK) {
-		xlog(L_WARNING, "Unable to bind SQL query '%s': %s", new_fsidnum_by_path_sql, sqlite3_errstr(ret));
-		goto out;
-	}
-
-again:
-	ret = sqlite3_step(stmt);
-	switch (ret) {
-	case SQLITE_ROW:
-		*fsidnum = sqlite3_column_int(stmt, 0);
-		found = 1;
-		break;
-	case SQLITE_CONSTRAINT:
-		/* Maybe we lost the race against another writer and the path is now present. */
-		check = 1;
-		break;
-	case SQLITE_BUSY:
-	case SQLITE_LOCKED:
-		wait_for_dbaccess();
-		goto again;
-	default:
-		xlog(L_WARNING, "Error while looking up '%s' in database: %s", path, sqlite3_errstr(ret));
-	}
-
-out:
-	sqlite3_finalize(stmt);
-
-	if (check) {
-		found = get_fsidnum_by_path(path, fsidnum);
-		if (!found)
-			xlog(L_WARNING, "SQLITE_CONSTRAINT error while inserting '%s' in database", path);
-	}
-
-	return found;
+	plg->destroydb();
+	plg = NULL;
+	dlclose(backend_dl);
 }
 
 /*
@@ -249,14 +59,7 @@ out:
  */
 int reexpdb_fsidnum_by_path(char *path, uint32_t *fsidnum, int may_create)
 {
-	int found;
-
-	found = get_fsidnum_by_path(path, fsidnum);
-
-	if (!found && may_create)
-		found = new_fsidnum_by_path(path, fsidnum);
-
-	return found;
+	return plg->fsidnum_by_path(path, fsidnum, may_create);
 }
 
 /*
@@ -278,7 +81,7 @@ void reexpdb_uncover_subvolume(uint32_t fsidnum)
 	char *path = NULL;
 	int ret;
 
-	if (get_path_by_fsidnum(fsidnum, &path)) {
+	if (plg->path_by_fsidnum(fsidnum, &path)) {
 		ret = nfsd_path_statfs64(path, &st);
 		if (ret == -1)
 			xlog(L_WARNING, "statfs() failed");
@@ -300,7 +103,7 @@ void reexpdb_uncover_subvolume(uint32_t fsidnum)
 int reexpdb_apply_reexport_settings(struct exportent *ep, char *flname, int flline)
 {
 	uint32_t fsidnum;
-	int found;
+	bool found;
 	int ret = 0;
 
 	if (ep->e_reexport == REEXP_NONE)
diff --git a/support/reexport/reexport_backend.h b/support/reexport/reexport_backend.h
new file mode 100644
index 00000000..9e5e5c43
--- /dev/null
+++ b/support/reexport/reexport_backend.h
@@ -0,0 +1,48 @@
+#ifndef REEXPORT_BACKEND_H
+#define REEXPORT_BACKEND_H
+
+#define REEXPDB_BACKEND_DEFAULT "sqlite.so"
+#define REEXPDB_BACKEND_OPS "plug_ops"
+
+struct reexpdb_backend_plugin {
+	/*
+	 * Find or allocate a fsidnum for a given path.
+	 *
+	 * @path: Path to look for
+	 * @fsidnum: Pointer to an uint32_t variable
+	 * @may_create: If non-zero, a fsidnum will be allocated if none was found
+	 *
+	 * Returns true if either an fsidnum was found or successfully allocated,
+	 * false otherwise.
+	 * On success, the fsidnum will be stored into @fsidnum.
+	 * Upon errors, false is returned and errors are logged.
+	 */
+	bool (*fsidnum_by_path)(char *path, uint32_t *fsidnum, int may_create);
+
+	/*
+	 * Lookup path by a given fsidnum
+	 *
+	 * @fsidnum: fsidnum to look for
+	 * @path: address of a char pointer
+	 *
+	 * Returns true if a path was found, false otherwise.
+	 * Upon errors, false is returned and errors are logged.
+	 * In case of success, the function returns the found path
+	 * via @path, @path will point to a freshly allocated buffer
+	 * which is free()'able.
+	 */
+	bool (*path_by_fsidnum)(uint32_t fsidnum, char **path);
+
+	/*
+	 * Init database connection, can get called multiple times.
+	 * Returns true on success, false otherwise.
+	 */
+	bool (*initdb)(void);
+
+	/*
+	 * Undoes initdb().
+	 */
+	void (*destroydb)(void);
+};
+
+#endif /* REEXPORT_BACKEND_H */
diff --git a/systemd/Makefile.am b/systemd/Makefile.am
index f254b218..70182600 100644
--- a/systemd/Makefile.am
+++ b/systemd/Makefile.am
@@ -70,7 +70,7 @@ nfs_server_generator_LDADD = ../support/export/libexport.a \
 			     $(LIBPTHREAD)
 
 if CONFIG_REEXPORT
-nfs_server_generator_LDADD += ../support/reexport/libreexport.a $(LIBSQLITE) -lrt
+nfs_server_generator_LDADD += ../support/reexport/libreexport.a -ldl
 endif
 
 rpc_pipefs_generator_LDADD = ../support/nfs/libnfs.la
diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man
index afd2b3f8..0d083171 100644
--- a/systemd/nfs.conf.man
+++ b/systemd/nfs.conf.man
@@ -297,9 +297,10 @@ is recognized.
 
 .TP
 .B reexport
-Only
 .B sqlitedb=
-is recognized, path to the state database.
+, path to the state database, if sqlite backend is used.
+.B backend_plugin=
+, path to database backend plugin, default is sqlite.so.
 
 .SH FILES
 .TP 10n
diff --git a/utils/exportd/Makefile.am b/utils/exportd/Makefile.am
index b0ec9034..6f23ed97 100644
--- a/utils/exportd/Makefile.am
+++ b/utils/exportd/Makefile.am
@@ -19,7 +19,7 @@ exportd_LDADD = ../../support/export/libexport.a \
 			$(OPTLIBS) $(LIBBLKID) $(LIBPTHREAD) \
 			-luuid
 if CONFIG_REEXPORT
-exportd_LDADD += ../../support/reexport/libreexport.a $(LIBSQLITE) -lrt
+exportd_LDADD += ../../support/reexport/libreexport.a -ldl
 endif
 
 exportd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \
diff --git a/utils/exportfs/Makefile.am b/utils/exportfs/Makefile.am
index 451637a0..a17ed130 100644
--- a/utils/exportfs/Makefile.am
+++ b/utils/exportfs/Makefile.am
@@ -13,7 +13,7 @@ exportfs_LDADD = ../../support/export/libexport.a \
 		 $(LIBWRAP) $(LIBNSL) $(LIBPTHREAD)
 
 if CONFIG_REEXPORT
-exportfs_LDADD += ../../support/reexport/libreexport.a $(LIBSQLITE) -lrt
+exportfs_LDADD += ../../support/reexport/libreexport.a -ldl
 endif
 
 exportfs_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) -I$(top_srcdir)/support/reexport
diff --git a/utils/mount/Makefile.am b/utils/mount/Makefile.am
index 0268488c..d569b127 100644
--- a/utils/mount/Makefile.am
+++ b/utils/mount/Makefile.am
@@ -33,9 +33,9 @@ mount_nfs_LDADD = ../../support/nfs/libnfs.la \
 		  $(LIBTIRPC)
 
 if CONFIG_REEXPORT
-mount_nfs_LDADD += ../../support/reexport/libreexport.a \
+mount_nfs_LDADD += ../../support/reexport/libreexport.a -ldl \
 		   ../../support/misc/libmisc.a \
-		   $(LIBSQLITE) -lrt $(LIBPTHREAD)
+		   -lrt $(LIBPTHREAD)
 endif
 
 
diff --git a/utils/mountd/Makefile.am b/utils/mountd/Makefile.am
index 569d335a..d9a5c374 100644
--- a/utils/mountd/Makefile.am
+++ b/utils/mountd/Makefile.am
@@ -21,7 +21,7 @@ mountd_LDADD = ../../support/export/libexport.a \
 	       $(LIBBSD) $(LIBWRAP) $(LIBNSL) $(LIBBLKID) -luuid $(LIBTIRPC) \
 	       $(LIBPTHREAD)
 if CONFIG_REEXPORT
-mountd_LDADD += ../../support/reexport/libreexport.a $(LIBSQLITE) -lrt
+mountd_LDADD += ../../support/reexport/libreexport.a -ldl
 endif
 
 mountd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \
-- 
2.31.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-18 23:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-18 23:05 [PATCH] RFC: Reexport state database backend plugin support Richard Weinberger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.