From a0ac5c276e5bb3dfdd9d2c772544a317f4583bbf Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 10 Jan 2017 15:24:20 +1030 Subject: [PATCH] status: API for status reporting. The API formalizes how daemons should report their statuses back to the main lightningd. It's a simple write API, which includes tracing support (currently it always sends traces, later it could send iff there's a failure, for example). Signed-off-by: Rusty Russell --- Makefile | 2 ++ daemon/test/Makefile | 4 +-- status.c | 85 ++++++++++++++++++++++++++++++++++++++++++++ status.h | 29 +++++++++++++++ 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 status.c create mode 100644 status.h diff --git a/Makefile b/Makefile index a8f5efc8c..662da7859 100644 --- a/Makefile +++ b/Makefile @@ -51,6 +51,7 @@ CORE_SRC := \ opt_bits.c \ permute_tx.c \ protobuf_convert.c \ + status.c \ type_to_string.c \ utils.c \ version.c @@ -175,6 +176,7 @@ CORE_HEADERS := close_tx.h \ permute_tx.h \ protobuf_convert.h \ remove_dust.h \ + status.h \ type_to_string.h \ utils.h \ version.h diff --git a/daemon/test/Makefile b/daemon/test/Makefile index de8d3964a..bf1c88afe 100644 --- a/daemon/test/Makefile +++ b/daemon/test/Makefile @@ -63,9 +63,9 @@ DAEMON_TEST_PROGRAMS := $(DAEMON_TEST_OBJS:.o=) update-mocks: $(DAEMON_TEST_SRC:%=update-mocks/%) -$(DAEMON_TEST_PROGRAMS): $(CCAN_OBJS) $(BITCOIN_OBJS) $(CORE_OBJS) $(LIBBASE58_OBJS) libsecp256k1.a utils.o +$(DAEMON_TEST_PROGRAMS): $(CCAN_OBJS) $(BITCOIN_OBJS) $(CORE_OBJS) $(LIBBASE58_OBJS) $(WIRE_OBJS) libsecp256k1.a utils.o -$(DAEMON_TEST_OBJS): $(DAEMON_HEADERS) $(DAEMON_JSMN_HEADERS) $(BITCOIN_HEADERS) $(CORE_HEADERS) $(GEN_HEADERS) $(DAEMON_GEN_HEADERS) $(CCAN_HEADERS) +$(DAEMON_TEST_OBJS): $(DAEMON_HEADERS) $(DAEMON_JSMN_HEADERS) $(BITCOIN_HEADERS) $(CORE_HEADERS) $(GEN_HEADERS) $(DAEMON_GEN_HEADERS) $(CCAN_HEADERS) $(WIRE_HEADERS) daemon-unit-tests: $(DAEMON_TEST_PROGRAMS:%=unittest/%) diff --git a/status.c b/status.c new file mode 100644 index 000000000..f00adeb30 --- /dev/null +++ b/status.c @@ -0,0 +1,85 @@ +#include "status.h" +#include "utils.h" +#include "wire/wire_sync.h" +#include +#include +#include +#include +#include +#include +#include +#include + +static int status_fd = -1; +const void *trc; + +void status_setup(int fd) +{ + status_fd = fd; + trc = tal_tmpctx(NULL); +} + +void status_send(const u8 *p) +{ + assert(status_fd >= 0); + + if (!wire_sync_write(status_fd, p)) + err(1, "Writing out status len %zu", tal_count(p)); + tal_free(p); +} + +void status_send_fd(int fd) +{ + assert(status_fd >= 0); + assert(fd >= 0); + + if (!fdpass_send(status_fd, fd)) + err(1, "Writing out status fd %i", fd); + close(fd); +} + +static void status_send_with_hdr(u16 type, const void *p, size_t len) +{ + be16 be_type, be_len; + + be_type = cpu_to_be16(type); + be_len = cpu_to_be16(len + sizeof(be_type)); + assert(status_fd >= 0); + assert(be16_to_cpu(be_len) == len + sizeof(be_type)); + + if (!write_all(status_fd, &be_len, sizeof(be_len)) + || !write_all(status_fd, &be_type, sizeof(be_type)) + || !write_all(status_fd, p, len)) + err(1, "Writing out status %u len %zu", type, len); +} + +void status_trace(const char *fmt, ...) +{ + va_list ap; + char *str; + + va_start(ap, fmt); + str = tal_vfmt(NULL, fmt, ap); + status_send_with_hdr(STATUS_TRACE, str, strlen(str)); + tal_free(str); + va_end(ap); + + /* Free up any temporary children. */ + tal_free(trc); + trc = tal_tmpctx(NULL); +} + +void status_failed(u16 code, const char *fmt, ...) +{ + va_list ap; + char *str; + + breakpoint(); + assert(code & STATUS_FAIL); + va_start(ap, fmt); + str = tal_vfmt(NULL, fmt, ap); + status_send_with_hdr(code, str, strlen(str)); + va_end(ap); + + exit(0x80 | (code & 0xFF)); +} diff --git a/status.h b/status.h new file mode 100644 index 000000000..0f2d223f7 --- /dev/null +++ b/status.h @@ -0,0 +1,29 @@ +#ifndef LIGHTNING_STATUS_H +#define LIGHTNING_STATUS_H +#include "config.h" +#include +#include +#include + +/* Simple status reporting API. */ +void status_setup(int fd); + +/* Convenient context, frees up after every status_update/failed */ +extern const void *trc; + +/* Special status code for tracing messages. */ +#define STATUS_TRACE 0x7FFF + +/* Failure codes always have high bit set. */ +#define STATUS_FAIL 0x8000 + +/* Send a message (frees the message). */ +void status_send(const u8 *msg); +/* Send a file descriptor (closes fd). */ +void status_send_fd(int fd); +/* Send a printf-style debugging trace. */ +void status_trace(const char *fmt, ...) PRINTF_FMT(1,2); +/* Send a failure status code with printf-style msg, and exit. */ +void status_failed(u16 code, const char *fmt, ...) PRINTF_FMT(2,3) NORETURN; + +#endif /* LIGHTNING_STATUS_H */