From patchwork Mon Apr 11 11:18:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zefir Kurtisi X-Patchwork-Id: 608750 X-Patchwork-Delegate: blogic@openwrt.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (caladan.dune.hu [78.24.191.180]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qk6yR1RkDz9sBG for ; Mon, 11 Apr 2016 21:18:55 +1000 (AEST) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id E4D66B91896; Mon, 11 Apr 2016 13:18:47 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00,RDNS_NONE autolearn=no autolearn_force=no version=3.4.1 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP; Mon, 11 Apr 2016 13:18:47 +0200 (CEST) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 3BB1BB9188F for ; Mon, 11 Apr 2016 13:18:46 +0200 (CEST) X-policyd-weight: using cached result; rate:hard: -6.1 Received: from mail.neratec.com (unknown [46.140.151.2]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Mon, 11 Apr 2016 13:18:44 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail.neratec.com (Postfix) with ESMTP id 525BEAA1DCA; Mon, 11 Apr 2016 13:18:44 +0200 (CEST) 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 8MzQV5Lggw19; Mon, 11 Apr 2016 13:18:44 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail.neratec.com (Postfix) with ESMTP id 33C47AA1DCD; Mon, 11 Apr 2016 13:18:44 +0200 (CEST) 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 THqp_Q8uaZ8K; Mon, 11 Apr 2016 13:18:44 +0200 (CEST) Received: from zefir.neratec.local (zefir.neratec.local [192.168.11.130]) by mail.neratec.com (Postfix) with ESMTPSA id 09EDDAA1DCA; Mon, 11 Apr 2016 13:18:44 +0200 (CEST) From: Zefir Kurtisi To: openwrt-devel@lists.openwrt.org Date: Mon, 11 Apr 2016 13:18:37 +0200 Message-Id: <1460373517-23537-1-git-send-email-zefir.kurtisi@neratec.com> X-Mailer: git-send-email 2.7.4 Subject: [OpenWrt-Devel] [PATCH] ubus: cli.wait_for: add polling for services X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" In ubus_cli_wait_for() there is a potential critical section between initially checking for the requested services and the following handling of 'ubus.object.add' events. In our system we let procd (re)start services and synchronize inter-service dependencies by using 'ubus wait_for' in the initscripts' service_started() functions. There we observe randomly that 'wait_for' is waiting for the full timeout and returning UBUS_STATUS_TIMEOUT, even if the service it is waiting for is already up and running. This happens when the service is started in the critical section mentioned above. The proposed patch adds periodic lookup for the requested services while waiting for the 'add' event and with that fixes the observed failure. Signed-off-by: Zefir Kurtisi --- cli.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/cli.c b/cli.c index c5cbfc3..8d98b12 100644 --- a/cli.c +++ b/cli.c @@ -16,6 +16,7 @@ #include #include "libubus.h" +static struct ubus_context *ctx; static struct blob_buf b; static int timeout = 30; static bool simple_output = false; @@ -277,15 +278,27 @@ static void wait_timeout(struct uloop_timeout *timeout) uloop_end(); } -static int ubus_cli_wait_for(struct ubus_context *ctx, int argc, char **argv) -{ - struct cli_wait_data data = { +#define WAIT_LOOP_TIME 200 +static struct cli_wait_data data = { .timeout.cb = wait_timeout, .ev.cb = wait_event_cb, - .pending = argv, - .n_pending = argc, - }; +}; + +static void poll_timeout_cb(struct uloop_timeout *timeout) +{ + int ret = ubus_lookup(ctx, NULL, wait_list_cb, &data); + if (ret || !data.n_pending) { + uloop_end(); + return; + } + uloop_timeout_set(timeout, WAIT_LOOP_TIME); +} +static int ubus_cli_wait_for(struct ubus_context *ctx, int argc, char **argv) +{ + data.pending = argv; + data.n_pending = argc; int ret; + static struct uloop_timeout poll_timeout = { .cb = poll_timeout_cb, }; if (argc < 1) return -2; @@ -305,6 +318,7 @@ static int ubus_cli_wait_for(struct ubus_context *ctx, int argc, char **argv) return ret; uloop_timeout_set(&data.timeout, timeout * 1000); + uloop_timeout_set(&poll_timeout, WAIT_LOOP_TIME); uloop_run(); uloop_done(); @@ -509,7 +523,6 @@ static struct { int main(int argc, char **argv) { const char *progname, *ubus_socket = NULL; - struct ubus_context *ctx; char *cmd; int ret = 0; int i, ch;