mctp-demux-daemon: Cleanup binding on exit

This is necessary for e.g. the astlpc binding which should notify the
host that the interface is no longer active if the daemon is going away.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I3f92232017d8faa1f3cd9be7ec27043b900fd4be
diff --git a/utils/mctp-demux-daemon.c b/utils/mctp-demux-daemon.c
index 9dddd8c..0fa5041 100644
--- a/utils/mctp-demux-daemon.c
+++ b/utils/mctp-demux-daemon.c
@@ -48,6 +48,7 @@
 	int		(*init)(struct mctp *mctp, struct binding *binding,
 				mctp_eid_t eid, int n_params,
 				char * const * params);
+	void		(*destroy)(struct mctp *mctp, struct binding *binding);
 	int		(*get_fd)(struct binding *binding);
 	int		(*process)(struct binding *binding);
 	void		*data;
@@ -226,6 +227,15 @@
 	return 0;
 }
 
+static void binding_astlpc_destroy(struct mctp *mctp, struct binding *binding)
+{
+	struct mctp_binding_astlpc *astlpc = binding->data;
+
+	mctp_unregister_bus(mctp, mctp_binding_astlpc_core(astlpc));
+
+	mctp_astlpc_destroy(astlpc);
+}
+
 static int binding_astlpc_get_fd(struct binding *binding)
 {
 	return mctp_astlpc_get_fd(binding->data);
@@ -244,12 +254,14 @@
 	{
 		.name = "serial",
 		.init = binding_serial_init,
+		.destroy = NULL,
 		.get_fd = binding_serial_get_fd,
 		.process = binding_serial_process,
 	},
 	{
 		.name = "astlpc",
 		.init = binding_astlpc_init,
+		.destroy = binding_astlpc_destroy,
 		.get_fd = binding_astlpc_get_fd,
 		.process = binding_astlpc_process,
 	}
@@ -425,6 +437,12 @@
 	return rc;
 }
 
+static void binding_destroy(struct ctx *ctx)
+{
+	if (ctx->binding->destroy)
+		ctx->binding->destroy(ctx->mctp, ctx->binding);
+}
+
 enum {
 	FD_BINDING = 0,
 	FD_SOCKET,
@@ -662,7 +680,7 @@
 		rc = socket_init(ctx);
 		if (rc) {
 			fprintf(stderr, "Failed to initialse socket: %d\n", rc);
-			goto cleanup_pcap_socket;
+			goto cleanup_binding;
 		}
 	} else {
 		ctx->sock = SD_LISTEN_FDS_START;
@@ -670,6 +688,9 @@
 
 	rc = run_daemon(ctx);
 
+cleanup_binding:
+	binding_destroy(ctx);
+
 cleanup_pcap_socket:
 	if (ctx->pcap.socket.path)
 		capture_close(&ctx->pcap.socket);