[LEDE-DEV] [PATCH v2] ubox/logread: add re-connect capability
John Crispin
john at phrozen.org
Wed Feb 14 00:31:05 PST 2018
On 24/11/17 14:06, Zefir Kurtisi wrote:
> When logd is restarted while 'logread -f' is running, the
> logread process terminates, which cumbers debugging in
> different use-cases.
>
> This patch adds re-connect functionality to logread. In
> follow mode, when the ustream to logd is disconnected,
> instead of terminating, it tries to re-connect to logd
> and re-issue the original request.
>
> Signed-off-by: Zefir Kurtisi <zefir.kurtisi at neratec.com>
Hi Zefir,
I have just pushed a different version of the patch, thanks for
reporting the problem
John
> ---
> v2: in follow mode, don't exit if the initial
> ubus lookup for logd fails
>
> log/logread.c | 143 +++++++++++++++++++++++++++++++++++++---------------------
> 1 file changed, 91 insertions(+), 52 deletions(-)
>
> diff --git a/log/logread.c b/log/logread.c
> index ad06f2a..8229c98 100644
> --- a/log/logread.c
> +++ b/log/logread.c
> @@ -65,6 +65,10 @@ static int log_type = LOG_STDOUT;
> static int log_size, log_udp, log_follow, log_trailer_null = 0;
> static int log_timestamp;
> static int last_errno = 0;
> +static struct ubus_context *ctx;
> +static int lines;
> +
> +static void logread_reconnect_cb(struct uloop_timeout *timeout);
>
> static const char* getcodetext(int value, CODE *codetable) {
> CODE *i;
> @@ -268,29 +272,82 @@ static void logread_fd_data_cb(struct ustream *s, int bytes)
> }
> }
>
> +/*
> + * Reconnect Handling
> + * while following log
> + * - after logd removal
> + * - destroy ustream
> + * - cyclically try to re-connect to new logd object
> + * - re-issue original request
> + *
> + * Note: if a re-connection appears while a 'logread -l' request is active, the
> + * number of returned lines will not match (i.e. you get some lines from
> + * the old instance plus the number of lines requested from the new one)
> + */
> +
> +/* flag to prevent printing error messages during reconnect cycles */
> +static int object_reconnect_active;
> +
> +static void logread_restart_reconnect_timer(struct uloop_timeout *timeout)
> +{
> + const int LOG_RECONNECT_TIMEOUT_MS = 250;
> + uloop_timeout_set(timeout, LOG_RECONNECT_TIMEOUT_MS);
> +}
> +
> static void logread_fd_state_cb(struct ustream *s)
> {
> - uloop_end();
> + static struct uloop_timeout ubus_timer;
> + /* force re-opening of stream */
> + s->free(s);
> +
> + object_reconnect_active = 1;
> + ubus_timer.cb = logread_reconnect_cb;
> + logread_restart_reconnect_timer(&ubus_timer);
> }
>
> static void logread_fd_cb(struct ubus_request *req, int fd)
> {
> static struct ustream_fd test_fd;
> -
> test_fd.stream.notify_read = logread_fd_data_cb;
> test_fd.stream.notify_state = logread_fd_state_cb;
> ustream_fd_init(&test_fd, fd);
> }
>
> -int main(int argc, char **argv)
> +static int logread_process(void)
> {
> + static struct blob_buf b;
> static struct ubus_request req;
> - struct ubus_context *ctx;
> uint32_t id;
> + int ret = ubus_lookup_id(ctx, "log", &id);
> + if (ret) {
> + if (!object_reconnect_active)
> + fprintf(stderr, "Failed to find log object\n");
> + return ret;
> + }
> + blob_buf_init(&b, 0);
> + blobmsg_add_u8(&b, "stream", 1);
> + if (lines)
> + blobmsg_add_u32(&b, "lines", lines);
> + else if (log_follow)
> + blobmsg_add_u32(&b, "lines", 0);
> +
> + ubus_invoke_async(ctx, id, "read", b.head, &req);
> + req.fd_cb = logread_fd_cb;
> + ubus_complete_request_async(ctx, &req);
> +
> + return 0;
> +}
> +
> +static void logread_reconnect_cb(struct uloop_timeout *timeout)
> +{
> + if (logread_process())
> + logread_restart_reconnect_timer(timeout);
> +}
> +
> +int main(int argc, char **argv)
> +{
> const char *ubus_socket = NULL;
> - int ch, ret, lines = 0;
> - static struct blob_buf b;
> - int tries = 5;
> + int ch, ret;
>
> signal(SIGPIPE, SIG_IGN);
>
> @@ -354,58 +411,40 @@ int main(int argc, char **argv)
> }
> ubus_add_uloop(ctx);
>
> - /* ugly ugly ugly ... we need a real reconnect logic */
> - do {
> - ret = ubus_lookup_id(ctx, "log", &id);
> - if (ret) {
> - fprintf(stderr, "Failed to find log object: %s\n", ubus_strerror(ret));
> - sleep(1);
> - continue;
> - }
> -
> - blob_buf_init(&b, 0);
> - blobmsg_add_u8(&b, "stream", 1);
> - blobmsg_add_u8(&b, "oneshot", !log_follow);
> - if (lines)
> - blobmsg_add_u32(&b, "lines", lines);
> - else if (log_follow)
> - blobmsg_add_u32(&b, "lines", 0);
> - if (log_follow) {
> - if (pid_file) {
> - FILE *fp = fopen(pid_file, "w+");
> - if (fp) {
> - fprintf(fp, "%d", getpid());
> - fclose(fp);
> - }
> + if (log_follow) {
> + if (pid_file) {
> + FILE *fp = fopen(pid_file, "w+");
> + if (fp) {
> + fprintf(fp, "%d", getpid());
> + fclose(fp);
> }
> }
> + }
>
> - if (log_ip && log_port) {
> - openlog("logread", LOG_PID, LOG_DAEMON);
> - log_type = LOG_NET;
> - sender.cb = log_handle_fd;
> - retry.cb = log_handle_reconnect;
> - uloop_timeout_set(&retry, 1000);
> - } else if (log_file) {
> - log_type = LOG_FILE;
> - sender.fd = open(log_file, O_CREAT | O_WRONLY| O_APPEND, 0600);
> - if (sender.fd < 0) {
> - fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno));
> - exit(-1);
> - }
> - } else {
> - sender.fd = STDOUT_FILENO;
> + if (log_ip && log_port) {
> + openlog("logread", LOG_PID, LOG_DAEMON);
> + log_type = LOG_NET;
> + sender.cb = log_handle_fd;
> + retry.cb = log_handle_reconnect;
> + uloop_timeout_set(&retry, 1000);
> + } else if (log_file) {
> + log_type = LOG_FILE;
> + sender.fd = open(log_file, O_CREAT | O_WRONLY| O_APPEND, 0600);
> + if (sender.fd < 0) {
> + fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno));
> + exit(-1);
> }
> + } else {
> + sender.fd = STDOUT_FILENO;
> + }
>
> - ubus_invoke_async(ctx, id, "read", b.head, &req);
> - req.fd_cb = logread_fd_cb;
> - ubus_complete_request_async(ctx, &req);
> -
> + ret = logread_process();
> + /* unless we are following, immediately exit when logd is not up */
> + if (!ret || log_follow)
> uloop_run();
> - ubus_free(ctx);
> - uloop_done();
>
> - } while (ret && tries--);
> + ubus_free(ctx);
> + uloop_done();
>
> return ret;
> }
More information about the Lede-dev
mailing list