From patchwork Fri Nov 24 13:06:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zefir Kurtisi X-Patchwork-Id: 841027 X-Patchwork-Delegate: blogic@openwrt.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=65.50.211.133; helo=bombadil.infradead.org; envelope-from=lede-dev-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="HiZj02W3"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yjxKn3stQz9sMN for ; Sat, 25 Nov 2017 00:06:52 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:Subject:References: In-Reply-To:Message-Id:Date:To:From:Reply-To:Cc:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=obWqf+FrfbgtNsl5ULWW7VDiLfX4em2k7wxCRGi83eE=; b=HiZj02W3YwS0d2lKDgWkU+Ny1w 9qrp9AklfCYV2fRTDVWs/sDrdDbA2En2CgKfUzj6DBfG+0AaRSNc3VwhQrbyu05wKeNdT90dEwxAI /zhmT64t8l69+XUtrO9h854t82EpzPp2hSwvzZMWpaLChap2p7wEOtb+eIXCcMOX5XC9AAxCxJGng rINUh3YtvVnHQgNGTxstSJrZM+hSdU8a4kvRbvJUDI+XQWBmccvsrel55LAoZXfSxRqqOv29SoYrB 9JqnuGDlTAsnEB/H2p1y31uiaBa5vwGrNY2JsBBvBipwca+ARaOTh843x+SgdjZr3xP/EKegpeqxQ qs4VtOMg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eIDgs-0001qz-EV; Fri, 24 Nov 2017 13:06:46 +0000 Received: from mail.neratec.com ([46.140.151.2]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eIDgn-0001qM-Ih for lede-dev@lists.infradead.org; Fri, 24 Nov 2017 13:06:44 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.neratec.com (Postfix) with ESMTP id 5830ECE038B for ; Fri, 24 Nov 2017 14:06:17 +0100 (CET) Received: from mail.neratec.com ([127.0.0.1]) by localhost (mail.neratec.com [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 6-ST6nVxshbt for ; Fri, 24 Nov 2017 14:06:17 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by mail.neratec.com (Postfix) with ESMTP id 3CF25CE0390 for ; Fri, 24 Nov 2017 14:06:17 +0100 (CET) X-Virus-Scanned: amavisd-new at neratec.com Received: from mail.neratec.com ([127.0.0.1]) by localhost (mail.neratec.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id dLrLIsQ4quvL for ; Fri, 24 Nov 2017 14:06:17 +0100 (CET) Received: from zefir.lan.neratec.com (zefir.lan.neratec.com [192.168.11.83]) by mail.neratec.com (Postfix) with ESMTPSA id 1DBABCE038B for ; Fri, 24 Nov 2017 14:06:17 +0100 (CET) From: Zefir Kurtisi To: lede-dev@lists.infradead.org Date: Fri, 24 Nov 2017 14:06:14 +0100 Message-Id: <20171124130614.2875-1-zefir.kurtisi@neratec.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171121162753.31468-1-zefir.kurtisi@neratec.com> References: <20171121162753.31468-1-zefir.kurtisi@neratec.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171124_050642_029316_D05E7F35 X-CRM114-Status: GOOD ( 16.11 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Subject: [LEDE-DEV] [PATCH v2] ubox/logread: add re-connect capability X-BeenThere: lede-dev@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "Lede-dev" Errors-To: lede-dev-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org 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 --- 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; }