[commits] [alfred] master: alfred: Allow to switch daemon between slave and master (06ce1cc)

postmaster at open-mesh.org postmaster at open-mesh.org
Mon Sep 9 19:19:38 CEST 2013


Repository : ssh://git@open-mesh.org/alfred

On branch  : master

>---------------------------------------------------------------

commit 06ce1ccfd08c200f65cddac45e83b3d357c0b4ac
Author: Sven Eckelmann <sven at open-mesh.com>
Date:   Mon Sep 9 17:46:07 2013 +0200

    alfred: Allow to switch daemon between slave and master
    
    The running daemon may need to be switched between from master to slave mode or
    from slave to master mode to increase the efficiency of the data distribution
    network. This must be possible during runtime to avoid the data loss during the
    switch time.
    
    Signed-off-by: Sven Eckelmann <sven at open-mesh.com>
    [simon at open-mesh.com: added newlines for help text]
    Signed-off-by: Simon Wunderlich <simon at open-mesh.com>


>---------------------------------------------------------------

06ce1ccfd08c200f65cddac45e83b3d357c0b4ac
 alfred.h    |    2 ++
 client.c    |   38 ++++++++++++++++++++++++++++++++++++++
 main.c      |   19 ++++++++++++++++++-
 packet.h    |   24 ++++++++++++++++++++++++
 unix_sock.c |   33 +++++++++++++++++++++++++++++++++
 5 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/alfred.h b/alfred.h
index e44919c..e931b1b 100644
--- a/alfred.h
+++ b/alfred.h
@@ -84,6 +84,7 @@ enum clientmode {
 	CLIENT_NONE,
 	CLIENT_REQUEST_DATA,
 	CLIENT_SET_DATA,
+	CLIENT_MODESWITCH,
 };
 
 struct globals {
@@ -119,6 +120,7 @@ int set_best_server(struct globals *globals);
 /* client.c */
 int alfred_client_request_data(struct globals *globals);
 int alfred_client_set_data(struct globals *globals);
+int alfred_client_modeswitch(struct globals *globals);
 /* recv.c */
 int recv_alfred_packet(struct globals *globals);
 struct transaction_head *
diff --git a/client.c b/client.c
index 2187ff2..4bc7b5c 100644
--- a/client.c
+++ b/client.c
@@ -179,3 +179,41 @@ int alfred_client_set_data(struct globals *globals)
 	unix_sock_close(globals);
 	return 0;
 }
+
+int alfred_client_modeswitch(struct globals *globals)
+{
+	unsigned char buf[MAX_PAYLOAD];
+	struct alfred_modeswitch_v0 *modeswitch;
+	int ret, len;
+
+	if (unix_sock_open_client(globals, ALFRED_SOCK_PATH))
+		return -1;
+
+	modeswitch = (struct alfred_modeswitch_v0 *)buf;
+	len = sizeof(*modeswitch);
+
+	modeswitch->header.type = ALFRED_MODESWITCH;
+	modeswitch->header.version = ALFRED_VERSION;
+	modeswitch->header.length = htons(len - sizeof(modeswitch->header));
+
+	switch (globals->opmode) {
+	case OPMODE_SLAVE:
+		modeswitch->mode = ALFRED_MODESWITCH_SLAVE;
+		break;
+	case OPMODE_MASTER:
+		modeswitch->mode = ALFRED_MODESWITCH_MASTER;
+		break;
+	default:
+		fprintf(stderr, "%s: unknown opmode %u in modeswitch\n",
+			__func__, globals->opmode);
+		return -1;
+	}
+
+	ret = write(globals->unix_sock, buf, len);
+	if (ret != len)
+		fprintf(stderr, "%s: only wrote %d of %d bytes: %s\n",
+			__func__, ret, len, strerror(errno));
+
+	unix_sock_close(globals);
+	return 0;
+}
diff --git a/main.c b/main.c
index 4f39948..8664320 100644
--- a/main.c
+++ b/main.c
@@ -37,6 +37,8 @@ static void alfred_usage(void)
 	printf("  -r, --request [data type]   collect data from the network and prints\n");
 	printf("                              it on the network\n");
 	printf("  -V, --req-version           specify the data version set for -s\n");
+	printf("  -M, --modeswitch master     switch daemon to mode master\n");
+	printf("                   slave      switch daemon to mode slave\n");
 	printf("\n");
 	printf("server mode options:\n");
 	printf("  -i, --interface             specify the interface to listen on\n");
@@ -62,6 +64,7 @@ static struct globals *alfred_init(int argc, char *argv[])
 		{"master",	no_argument,		NULL,	'm'},
 		{"help",	no_argument,		NULL,	'h'},
 		{"req-version", required_argument,	NULL,	'V'},
+		{"modeswitch",  required_argument,	NULL,	'M'},
 		{"version",	no_argument,		NULL,	'v'},
 		{NULL,		0,			NULL,	0},
 	};
@@ -81,7 +84,7 @@ static struct globals *alfred_init(int argc, char *argv[])
 
 	time_random_seed();
 
-	while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:", long_options,
+	while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:", long_options,
 				  &opt_ind)) != -1) {
 		switch (opt) {
 		case 'r':
@@ -120,6 +123,17 @@ static struct globals *alfred_init(int argc, char *argv[])
 			}
 			globals->clientmode_version = atoi(optarg);
 			break;
+		case 'M':
+			if (strcmp(optarg, "master") == 0) {
+				globals->opmode = OPMODE_MASTER;
+			} else if (strcmp(optarg, "slave") == 0) {
+				globals->opmode = OPMODE_SLAVE;
+			} else {
+				fprintf(stderr, "bad modeswitch argument\n");
+				return NULL;
+			}
+			globals->clientmode = CLIENT_MODESWITCH;
+			break;
 		case 'v':
 			printf("%s %s\n", argv[0], SOURCE_VERSION);
 			printf("A.L.F.R.E.D. - Almighty Lightweight Remote Fact Exchange Daemon\n");
@@ -155,6 +169,9 @@ int main(int argc, char *argv[])
 	case CLIENT_SET_DATA:
 		return alfred_client_set_data(globals);
 		break;
+	case CLIENT_MODESWITCH:
+		return alfred_client_modeswitch(globals);
+		break;
 	}
 
 	return 0;
diff --git a/packet.h b/packet.h
index 57fa471..8250c9c 100644
--- a/packet.h
+++ b/packet.h
@@ -66,6 +66,7 @@ struct alfred_transaction_mgmt {
  * @ALFRED_REQUEST: Packet is an alfred_request_v*
  * @ALFRED_STATUS_TXEND: Transaction was finished by sender
  * @ALFRED_STATUS_ERROR: Error was detected during the transaction
+ * @ALFRED_MODESWITCH: Switch between different operation modes
  */
 enum alfred_packet_type {
 	ALFRED_PUSH_DATA = 0,
@@ -73,6 +74,7 @@ enum alfred_packet_type {
 	ALFRED_REQUEST = 2,
 	ALFRED_STATUS_TXEND = 3,
 	ALFRED_STATUS_ERROR = 4,
+	ALFRED_MODESWITCH = 5,
 };
 
 /* packets */
@@ -119,6 +121,28 @@ struct alfred_request_v0 {
 } __packed;
 
 /**
+ * enum alfred_modeswitch_type - Mode of the daemon
+ * @ALFRED_MODESWITCH_SLAVE: see OPMODE_SLAVE
+ * @ALFRED_MODESWITCH_MASTER: see OPMODE_MASTER
+ */
+enum alfred_modeswitch_type {
+	ALFRED_MODESWITCH_SLAVE = 0,
+	ALFRED_MODESWITCH_MASTER = 1,
+};
+
+/**
+ * struct alfred_modeswitch_v0 - Request for a specific type
+ * @header: TLV header describing the complete packet
+ * @mode: data type which is requested
+ *
+ * Sent to the daemon by client
+ */
+struct alfred_modeswitch_v0 {
+	struct alfred_tlv header;
+	uint8_t mode;
+} __packed;
+
+/**
  * struct alfred_status_v0 - Status info of a transaction
  * @header: TLV header describing the complete packet
  * @tx: Transaction identificator and sequence number of packet
diff --git a/unix_sock.c b/unix_sock.c
index e6b22e8..3738d6d 100644
--- a/unix_sock.c
+++ b/unix_sock.c
@@ -272,6 +272,34 @@ int unix_sock_req_data_finish(struct globals *globals,
 	return ret;
 }
 
+static int unix_sock_modesw(struct globals *globals,
+			    struct alfred_modeswitch_v0 *modeswitch,
+			    int client_sock)
+{
+	int len, ret = -1;
+
+	len = ntohs(modeswitch->header.length);
+
+	if (len < (int)(sizeof(*modeswitch) - sizeof(modeswitch->header)))
+		goto err;
+
+	switch (modeswitch->mode) {
+	case ALFRED_MODESWITCH_SLAVE:
+		globals->opmode = OPMODE_SLAVE;
+		break;
+	case ALFRED_MODESWITCH_MASTER:
+		globals->opmode = OPMODE_MASTER;
+		break;
+	default:
+		goto err;
+	}
+
+	ret = 0;
+err:
+	close(client_sock);
+	return ret;
+}
+
 int unix_sock_read(struct globals *globals)
 {
 	int client_sock;
@@ -321,6 +349,11 @@ int unix_sock_read(struct globals *globals)
 					 (struct alfred_request_v0 *)packet,
 					 client_sock);
 		break;
+	case ALFRED_MODESWITCH:
+		ret = unix_sock_modesw(globals,
+				       (struct alfred_modeswitch_v0 *)packet,
+					client_sock);
+		break;
 	default:
 		/* unknown packet type */
 		ret = -1;



More information about the commits mailing list