[28/29] discover: Maintain a backlog of status updates
diff mbox

Message ID 20161219041915.30497-29-sam@mendozajonas.com
State Accepted
Headers show

Commit Message

Samuel Mendoza-Jonas Dec. 19, 2016, 4:19 a.m. UTC
Add status updates to a persistent list in the discover_server struct,
and send each client the backlog on connect. This avoids clients missing
useful messages from early init. Clients will only show this in the
backlog screen to avoid flooding the client's status line.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
---
 discover/boot.c               |  1 +
 discover/device-handler.c     |  2 ++
 discover/discover-server.c    | 25 +++++++++++++++++++++++++
 lib/pb-protocol/pb-protocol.c | 10 +++++++++-
 lib/types/types.h             |  6 ++++++
 ui/ncurses/nc-cui.c           |  4 +++-
 ui/ncurses/nc-statuslog.c     |  5 -----
 7 files changed, 46 insertions(+), 7 deletions(-)

Patch
diff mbox

diff --git a/discover/boot.c b/discover/boot.c
index da7b946..fab4b61 100644
--- a/discover/boot.c
+++ b/discover/boot.c
@@ -45,6 +45,7 @@  static void __attribute__((format(__printf__, 4, 5))) update_status(
 	va_end(ap);
 
 	status.type = type;
+	status.backlog = false;
 
 	pb_debug("boot status: [%d] %s\n", type, status.message);
 
diff --git a/discover/device-handler.c b/discover/device-handler.c
index f3405f2..eff9a25 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -442,6 +442,7 @@  static void _device_handler_vstatus(struct device_handler *handler,
 
 	status.type = type;
 	status.message = talloc_vasprintf(handler, fmt, ap);
+	status.backlog = false;
 
 	device_handler_status(handler, &status);
 
@@ -616,6 +617,7 @@  static void countdown_status(struct device_handler *handler,
 	status.type = STATUS_INFO;
 	status.message = talloc_asprintf(handler,
 			_("Booting in %d sec: %s"), sec, opt->option->name);
+	status.backlog = false;
 
 	device_handler_status(handler, &status);
 
diff --git a/discover/discover-server.c b/discover/discover-server.c
index ad184f6..a3087b3 100644
--- a/discover/discover-server.c
+++ b/discover/discover-server.c
@@ -28,6 +28,7 @@  struct discover_server {
 	struct waitset *waitset;
 	struct waiter *waiter;
 	struct list clients;
+	struct list status;
 	struct device_handler *device_handler;
 };
 
@@ -282,6 +283,7 @@  static int discover_server_process_message(void *arg)
 static int discover_server_process_connection(void *arg)
 {
 	struct discover_server *server = arg;
+	struct statuslog_entry *entry;
 	int fd, rc, i, n_devices;
 	struct client *client;
 
@@ -333,6 +335,10 @@  static int discover_server_process_connection(void *arg)
 		}
 	}
 
+	/* send status backlog to client */
+	list_for_each_entry(&server->status, entry, list)
+		write_boot_status_message(server, client, entry->status);
+
 	return 0;
 }
 
@@ -368,8 +374,26 @@  void discover_server_notify_device_remove(struct discover_server *server,
 void discover_server_notify_boot_status(struct discover_server *server,
 		struct status *status)
 {
+	struct statuslog_entry *entry;
 	struct client *client;
 
+	/* Duplicate the status struct to add to the backlog */
+	entry = talloc(server, struct statuslog_entry);
+	if (!entry) {
+		pb_log("Failed to allocated saved status!\n");
+	} else {
+		entry->status = talloc(entry, struct status);
+		if (entry->status) {
+			entry->status->type = status->type;
+			entry->status->message = talloc_strdup(entry->status,
+							       status->message);
+			entry->status->backlog = true;
+			list_add_tail(&server->status, &entry->list);
+		} else {
+			talloc_free(entry);
+		}
+	}
+
 	list_for_each_entry(&server->clients, client, list)
 		write_boot_status_message(server, client, status);
 }
@@ -410,6 +434,7 @@  struct discover_server *discover_server_init(struct waitset *waitset)
 	server->waiter = NULL;
 	server->waitset = waitset;
 	list_init(&server->clients);
+	list_init(&server->status);
 
 	unlink(PB_SOCKET_PATH);
 
diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c
index 8bc8820..65a1e93 100644
--- a/lib/pb-protocol/pb-protocol.c
+++ b/lib/pb-protocol/pb-protocol.c
@@ -217,8 +217,9 @@  int pb_protocol_boot_len(const struct boot_command *boot)
 
 int pb_protocol_boot_status_len(const struct status *status)
 {
-	return  4 +
+	return  4 +	/* type */
 		4 + optional_strlen(status->message) +
+		4 +	/* backlog */
 		4;
 }
 
@@ -410,6 +411,9 @@  int pb_protocol_serialise_boot_status(const struct status *status,
 
 	pos += pb_protocol_serialise_string(pos, status->message);
 
+	*(bool *)pos = __cpu_to_be32(status->backlog);
+	pos += sizeof(bool);
+
 	assert(pos <= buf + buf_len);
 	(void)buf_len;
 
@@ -847,6 +851,10 @@  int pb_protocol_deserialise_boot_status(struct status *status,
 	if (read_string(status, &pos, &len, &status->message))
 		goto out;
 
+	/* backlog */
+	status->backlog = *(bool *)pos;
+	pos += sizeof(status->backlog);
+
 	rc = 0;
 
 out:
diff --git a/lib/types/types.h b/lib/types/types.h
index 506510b..63f1b21 100644
--- a/lib/types/types.h
+++ b/lib/types/types.h
@@ -76,6 +76,12 @@  struct status {
 		STATUS_ERROR,
 	} type;
 	char	*message;
+	bool	backlog;
+};
+
+struct statuslog_entry {
+	struct status		*status;
+	struct list_item	list;
 };
 
 struct interface_info {
diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c
index 93b2e43..b4f74a7 100644
--- a/ui/ncurses/nc-cui.c
+++ b/ui/ncurses/nc-cui.c
@@ -714,7 +714,9 @@  static void cui_update_status(struct status *status, void *arg)
 
 	statuslog_append_steal(cui, cui->statuslog, status);
 
-	nc_scr_status_printf(cui->current, "%s", status->message);
+	/* Ignore status messages from the backlog */
+	if (!status->backlog)
+		nc_scr_status_printf(cui->current, "%s", status->message);
 }
 
 static void cui_update_mm_title(struct cui *cui)
diff --git a/ui/ncurses/nc-statuslog.c b/ui/ncurses/nc-statuslog.c
index 1943f39..623aa55 100644
--- a/ui/ncurses/nc-statuslog.c
+++ b/ui/ncurses/nc-statuslog.c
@@ -33,11 +33,6 @@ 
 
 static const int max_status_entry = 10000;
 
-struct statuslog_entry {
-	struct status		*status;
-	struct list_item	list;
-};
-
 struct statuslog {
 	struct list		status;
 	int			n_status;