git » nmdb » commit e54a300

nmdb: Implement read-only mode

author Alberto Bertogli
2010-04-19 04:47:25 UTC
committer Alberto Bertogli
2010-04-19 04:47:25 UTC
parent d8f7901063552dcc433414fe35b3365e51036417

nmdb: Implement read-only mode

This patch implements a read-only mode in the server, selectable via
command-line only (at the moment).

It will become more useful in the future, for replication purposes.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>

doc/network.rst +1 -0
nmdb/common.h +1 -0
nmdb/main.c +6 -1
nmdb/net-const.h +1 -0
nmdb/nmdb.1 +4 -0
nmdb/parse.c +20 -0

diff --git a/doc/network.rst b/doc/network.rst
index 13f0d36..735e591 100644
--- a/doc/network.rst
+++ b/doc/network.rst
@@ -174,6 +174,7 @@ ERR_BROKEN   0x103  Broken request
 ERR_UNKREQ   0x104  Unknown request
 ERR_MEM      0x105  Memory allocation error
 ERR_DB       0x106  Database error
+ERR_RO       0x107  Server in read-only mode
 ============ ====== =========================
 
 
diff --git a/nmdb/common.h b/nmdb/common.h
index 53b17ed..3c66fc0 100644
--- a/nmdb/common.h
+++ b/nmdb/common.h
@@ -26,6 +26,7 @@ struct settings {
 	int numobjs;
 	int foreground;
 	int passive;
+	int read_only;
 	char *dbname;
 	char *logfname;
 	enum backend_type backend;
diff --git a/nmdb/main.c b/nmdb/main.c
index b638c26..2790112 100644
--- a/nmdb/main.c
+++ b/nmdb/main.c
@@ -43,6 +43,7 @@ static void help(void) {
 	  "  -o fname	log to the given file (stdout).\n"
 	  "  -f		don't fork and stay in the foreground\n"
 	  "  -p		enable passive mode, for redundancy purposes (read docs.)\n"
+	  "  -r		read-only mode\n"
 	  "  -h		show this help\n"
 	  "\n"
 	  "Available backends: " SUPPORTED_BE "\n"
@@ -68,6 +69,7 @@ static int load_settings(int argc, char **argv)
 	settings.numobjs = -1;
 	settings.foreground = 0;
 	settings.passive = 0;
+	settings.read_only = 0;
 	settings.logfname = "-";
 	settings.backend = DEFAULT_BE;
 
@@ -75,7 +77,7 @@ static int load_settings(int argc, char **argv)
 	strcpy(settings.dbname, DEFDBNAME);
 
 	while ((c = getopt(argc, argv,
-				"b:d:l:L:t:T:u:U:s:S:c:o:fph?")) != -1) {
+				"b:d:l:L:t:T:u:U:s:S:c:o:fprh?")) != -1) {
 		switch(c) {
 		case 'b':
 			settings.backend = be_type_from_str(optarg);
@@ -129,6 +131,9 @@ static int load_settings(int argc, char **argv)
 		case 'p':
 			settings.passive = 1;
 			break;
+		case 'r':
+			settings.read_only = 1;
+			break;
 
 		case 'h':
 		case '?':
diff --git a/nmdb/net-const.h b/nmdb/net-const.h
index 290ab90..69aeddb 100644
--- a/nmdb/net-const.h
+++ b/nmdb/net-const.h
@@ -53,6 +53,7 @@
 #define ERR_UNKREQ		0x104	/* Unknown request */
 #define ERR_MEM			0x105	/* Memory allocation error */
 #define ERR_DB			0x106	/* Database error */
+#define ERR_RO			0x107	/* Server in read-only mode */
 
 
 #endif
diff --git a/nmdb/nmdb.1 b/nmdb/nmdb.1
index 31c061d..e6d08a0 100644
--- a/nmdb/nmdb.1
+++ b/nmdb/nmdb.1
@@ -88,6 +88,10 @@ tested (although it should work fine), and do
 start an active and a passive server in the same machine (it misbehaves under
 some circumstances, and doesn't make much sense anyway).
 .TP
+.B "-r"
+Read-only mode. The server will refuse any request that would alter the
+database and/or cache. Useful for redundancy and replication.
+.TP
 .B "-h"
 Show a brief help.
 
diff --git a/nmdb/parse.c b/nmdb/parse.c
index 64ef588..c475f36 100644
--- a/nmdb/parse.c
+++ b/nmdb/parse.c
@@ -303,6 +303,11 @@ static void parse_set(struct req_info *req)
 		return;
 	}
 
+	if (settings.read_only) {
+		req->reply_err(req, ERR_RO);
+		return;
+	}
+
 	FILL_CACHE_FLAG(set);
 	FILL_SYNC_FLAG();
 
@@ -349,6 +354,11 @@ static void parse_del(struct req_info *req)
 		return;
 	}
 
+	if (settings.read_only) {
+		req->reply_err(req, ERR_RO);
+		return;
+	}
+
 	FILL_CACHE_FLAG(del);
 	FILL_SYNC_FLAG();
 
@@ -414,6 +424,11 @@ static void parse_cas(struct req_info *req)
 		return;
 	}
 
+	if (settings.read_only) {
+		req->reply_err(req, ERR_RO);
+		return;
+	}
+
 	FILL_CACHE_FLAG(cas);
 
 	key = req->payload + sizeof(uint32_t) * 3;
@@ -482,6 +497,11 @@ static void parse_incr(struct req_info *req)
 		return;
 	}
 
+	if (settings.read_only) {
+		req->reply_err(req, ERR_RO);
+		return;
+	}
+
 	FILL_CACHE_FLAG(incr);
 
 	key = req->payload + sizeof(uint32_t);