From patchwork Sun Dec 13 02:21:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sava Jakovljev X-Patchwork-Id: 1415503 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:4864:20::439; helo=mail-wr1-x439.google.com; envelope-from=swupdate+bncbaabbp7v2x7akgqetbaeiti@googlegroups.com; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=teufel.de Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.a=rsa-sha256 header.s=20161025 header.b=ZOCDlW7J; dkim-atps=neutral Received: from mail-wr1-x439.google.com (mail-wr1-x439.google.com [IPv6:2a00:1450:4864:20::439]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CtpF30c3gz9sSf for ; Sun, 13 Dec 2020 13:21:55 +1100 (AEDT) Received: by mail-wr1-x439.google.com with SMTP id w5sf2626986wrl.9 for ; Sat, 12 Dec 2020 18:21:55 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1607826111; cv=pass; d=google.com; s=arc-20160816; b=ECuuafWA3IMswH2tU8xD6t5lq64reDabI5XUhc0WIVSTgpBbm3gjjXEkxnMFsswAjU FSmHduL/x8f8AFBO8ENvSNIq+U8+P6mMh0eG7gPhcthtFLZp6jACFpY13lv2Gy/O1seI 5WoRl3pqWMXP7QFTgO4TLiv7MvdS+rvEIUHp3fwVr23QLH3TsdihDP1k+CASzOZLWNqr ShUqDSgsXdJNhZEU9AcpXYgaaUrWcYo1blEuobSdIqmDCIk6FToaYOP4WAyo9fEH6rsy S/CAf/v2X3pMeU39qOWxGAbDNkXAI+lkkvVcW2IoONbzkpZPigqMvL+L1HrH38dZzw4V aCVA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:mime-version:message-id:date :subject:cc:to:from:sender:dkim-signature; bh=3vcD8xgleO5rIZ3UDZqutDjsI4k0LaLSoBsDWnDT4QU=; b=Ipv2smsYODeIDj/vGBo8P8TrxXO5SBE0aHqdPOBXpzmlt3ZRaT0lddXlLpvB/ZFrUB ntQXoEmrKdTqWcM8TQLTEmECnslLnDx3RF5euAiWLtOukbgclEDJuiFELQNvUqti1EoD /ByBYKqfL6pzIkw12QAUeNG0h8ZFHGeVMbXDOuhh3h4OTWz3GFuKHkne1Ua7odXgTwbl B4PMbB4hqBUerVxBtnJRFM8KxJW0qJdfSJycrtNLFn+oFAMMn4I/04Zn1G4ejgtcn3FM gY9kiCP4W+9eElzJIazDlQmLa/YlX1xN1bgse23p89ws/krOMkc6zrNBObDb0E05COHw 3OJw== ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@teufel.de header.s=hse1 header.b=D99JRl21; spf=pass (google.com: domain of sava.jakovljev@teufel.de designates 94.100.133.204 as permitted sender) smtp.mailfrom=sava.jakovljev@teufel.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:mime-version :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=3vcD8xgleO5rIZ3UDZqutDjsI4k0LaLSoBsDWnDT4QU=; b=ZOCDlW7Jj33iACdkukm3XHy9q6AZ3B3qvS+tPSBfuXUeAWd5n+7Ijx2iEFtA5E7SAj dSUa4wkVTnR7JKSfGy8myfNuk5u4kEcx+Ar6cF+uqpEyBA0U7JvTmaKfZZkEp+lHnc+a E2+IPjP/b86PWtRGo4FzL4jbgcrsZE1F17iA5Cef3sRMTUFdPVXyuYlXgcUAiNVyK+ge LsQegYsfQN8BKcowf71BXICypDsE+fxL/BF/7FRUeBqB+iL2fiYqmIxfiH+kdL+M5y1N TxatYBpO229K/J8PEHORVln9aG/T/cekwvIEYGejDcv4qKOF7ZoVt3sp3Dz17nzgZQtt Go9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=sender:x-gm-message-state:from:to:cc:subject:date:message-id :mime-version:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post :list-help:list-archive:list-subscribe:list-unsubscribe; bh=3vcD8xgleO5rIZ3UDZqutDjsI4k0LaLSoBsDWnDT4QU=; b=VG1YisXCpXovX4TRYCH5nEkSArTyuf7sS6wqh7g1BehVfg56DIVqVgoMaNUIb+SW7U iI56zbXY4002X/usrkyXWuuXRuuQOjvXHqOuUgHSbgHIvC3kdNOdX6VhzGKWneco5rqm BJKGJwmOWMQ3YMqYzHDaeg82Y+bIXjcI7ocrk3IjycCtsRgH5u1xPzZNaAhWGsD9KKjK aGjlb6A9b4AtUHgDf8gsZaFrE1KiPeSFDQOzxFnUEERst+1K9D8DPbekCqW6J6HumGtE 0Oe5N338j2bMhF0RSHLg7KbqXsXstq3qgejFKdxR+gfrNrLwUPc8Z8E9GhB6fzB9Cd4c QC8Q== Sender: swupdate@googlegroups.com X-Gm-Message-State: AOAM533YU+mfhUR/Sj4MBlFnQ+qNxRy62aAXEcoJpRkiO1b2gANvbNOI RdesZoTPtoLuUJE/sXcpWgk= X-Google-Smtp-Source: ABdhPJxG7sFgK3tVO6lRIOANZUo2w3lpteBKTjLc/+l9pfkjQ/QJHhj33/6P0oyw9OrsgapgwBeGxg== X-Received: by 2002:a1c:e142:: with SMTP id y63mr21468648wmg.28.1607826111639; Sat, 12 Dec 2020 18:21:51 -0800 (PST) X-BeenThere: swupdate@googlegroups.com Received: by 2002:a5d:6812:: with SMTP id w18ls8162292wru.1.gmail; Sat, 12 Dec 2020 18:21:50 -0800 (PST) X-Received: by 2002:adf:812a:: with SMTP id 39mr20819586wrm.362.1607826110759; Sat, 12 Dec 2020 18:21:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1607826110; cv=none; d=google.com; s=arc-20160816; b=ObFxtgf07MM6f6AqQGC4e1HACVQr/2JIBC2mUQgxYLXxlv8ONxuOFGZwgdY84LwXto t2xXPf622frMj7qmP2t4UXqs9SJRUC+kRyLDAEXbG2Q5eiUQjpCED0vC0fVJLS+hyUNf sYP7zaQVGQeAD6l3p8oktL6xmM8hGp8Vd/b+gJkzXovStR9EO0MzKyfXZ4L+WYU+TFQ9 YvsN4nJFvGHxLpaLT/Yx4bOlZlXJGDnDwdQPBQxW/pkLzbOafjdJ8d2NkjqAXr+CBlQn 8nPziFvFO5lHGVAtimnPcyEsZfRLfJXfNhI06bMR9lJpGPa5jSDhAkyfO1ppRSi15qXn 6RgQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=dkim-signature:content-transfer-encoding:mime-version:message-id :date:subject:cc:to:from; bh=wDokPYTjIJxb3gwCj28vH6ejhrwwHobueFdSPtj1zP4=; b=deNJpAHxFMQedrKFxqsEZFHwsBOa99SHL9sW4+I5hs8ngc4izVyzdcw37ebypA+PSK JAmxesrLAGs/Hwbjao+d5bCsjx8qf/VQ/6NHOoh+psiy8qt9XJOJp63t/T0qQI2SokOc E6ZGPWlzub5O9bw+N2KftOwb+tvj7MKYFTpn0FRn7qq3OFba6p/W5Jz+U1alIxQYJld7 YzYIhUGR5FpYBYU0Vk2dz8THCg00yf+eQfr4nDCELd0swh9pBPNeGEaoCicRIBhxXHWU wHAfsacup4bCN3mOoN2TGXUiWjE1aPX1+vdEonYxt85icy51hza86XviZ5nkuypud/1Z 0FVg== ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@teufel.de header.s=hse1 header.b=D99JRl21; spf=pass (google.com: domain of sava.jakovljev@teufel.de designates 94.100.133.204 as permitted sender) smtp.mailfrom=sava.jakovljev@teufel.de Received: from mx-relay28-hz1.antispameurope.com (mx-relay28-hz1.antispameurope.com. [94.100.133.204]) by gmr-mx.google.com with ESMTPS id h18si592946wmb.1.2020.12.12.18.21.50 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 Dec 2020 18:21:50 -0800 (PST) Received-SPF: pass (google.com: domain of sava.jakovljev@teufel.de designates 94.100.133.204 as permitted sender) client-ip=94.100.133.204; Received: from unknown ([212.91.255.190]) by mx-relay28-hz1.antispameurope.com; Sun, 13 Dec 2020 03:21:50 +0100 From: Sava Jakovljev To: CC: Sava Jakovljev Subject: [swupdate] [PATCH v2] Execute subprocess IPC in separate thread Date: Sun, 13 Dec 2020 03:21:30 +0100 Message-ID: <20201213022130.42375-1-sava.jakovljev@teufel.de> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 X-Originating-IP: [10.10.6.11] X-ClientProxiedBy: DNS-EX-02.teufel.local (10.10.0.81) To DNS-EX-02.teufel.local (10.10.0.81) X-C2ProcessedOrg: b93e13a0-e8da-4ba4-97b8-f14375b21c41 X-cloud-security-sender: sava.jakovljev@teufel.de X-cloud-security-recipient: swupdate@googlegroups.com X-cloud-security-Virusscan: CLEAN X-cloud-security-disclaimer: This E-Mail was scanned by E-Mailservice on mx-relay28-hz1.antispameurope.com with 36CFA1C02C3 X-cloud-security-connect: unknown[212.91.255.190], TLS=1, IP=212.91.255.190 X-cloud-security: scantime:.3415 X-Original-Sender: sava.jakovljev@teufel.de X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@teufel.de header.s=hse1 header.b=D99JRl21; spf=pass (google.com: domain of sava.jakovljev@teufel.de designates 94.100.133.204 as permitted sender) smtp.mailfrom=sava.jakovljev@teufel.de Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , Signed-off-by: Sava Jakovljev --- Subprocesses may want to alter global SWUpdate state. In order to do this, subprocess RPC must be handled with network thread being kept free, in order to avoid deadlocks. One currently exists in Suricatta activation IPC. Changes from v1 version of this patch are to correctly handle OOM situation by sending a NACK message back, and to declare subprocess thread functions static. core/network_thread.c | 217 ++++++++++++++++++++++++++++-------------- 1 file changed, 145 insertions(+), 72 deletions(-) -- 2.26.2 diff --git a/core/network_thread.c b/core/network_thread.c index 0e6080d..64be58f 100644 --- a/core/network_thread.c +++ b/core/network_thread.c @@ -56,6 +56,20 @@ static unsigned long nrmsgs = 0; static pthread_mutex_t msglock = PTHREAD_MUTEX_INITIALIZER; +struct subprocess_msg_elem { + ipc_message message; + int client; + SIMPLEQ_ENTRY(subprocess_msg_elem) next; +}; + +SIMPLEQ_HEAD(subprocess_msglist, subprocess_msg_elem); +static struct subprocess_msglist subprocess_messages; + +static pthread_t subprocess_ipc_handler_thread_id; +static pthread_mutex_t subprocess_msg_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t subprocess_wkup = PTHREAD_COND_INITIALIZER; +static unsigned long subprocess_messages_count = 0; + static bool is_selection_allowed(const char *software_set, char *running_mode, struct dict const *acceptedlist) { @@ -239,6 +253,110 @@ static void unlink_socket(void) unlink(get_ctrl_socket()); } +static void send_subprocess_reply(struct subprocess_msg_elem *subprocess_msg) +{ + if (write(subprocess_msg->client, &subprocess_msg->message, + sizeof(subprocess_msg->message)) < 0) + printf("Error write on socket ctrl"); +} + +static void handle_subprocess_ipc(struct subprocess_msg_elem *subprocess_msg) +{ + ipc_message *msg = &subprocess_msg->message; + int pipe = pctl_getfd_from_type(msg->data.procmsg.source); + if (pipe < 0) { + ERROR("Cannot find channel for requested process"); + msg->type = NACK; + + return; + } + + TRACE("Received Message for %s", + pctl_getname_from_type(msg->data.procmsg.source)); + if (fcntl(pipe, F_GETFL) < 0 && errno == EBADF) { + ERROR("Pipe not available or closed: %d", pipe); + msg->type = NACK; + + return; + } + + /* + * Cleanup the queue to be sure there are not + * outstanding messages + */ + empty_pipe(pipe); + + int ret = write(pipe, msg, sizeof(*msg)); + if (ret != sizeof(*msg)) { + ERROR("Writing to pipe failed !"); + msg->type = NACK; + + return; + } + + /* + * Do not block forever for an answer + * This would block the whole thread + * If a message requires more time, + * the destination process should sent an + * answer back explaining this in the payload + */ + fd_set pipefds; + FD_ZERO(&pipefds); + FD_SET(pipe, &pipefds); + + struct timeval tv; + tv.tv_usec = 0; + if (!msg->data.procmsg.timeout) + tv.tv_sec = DEFAULT_INTERNAL_TIMEOUT; + else + tv.tv_sec = msg->data.procmsg.timeout; + ret = select(pipe + 1, &pipefds, NULL, NULL, &tv); + + /* + * If there is an error or timeout, + * send a NACK back + */ + if (ret <= 0 || !FD_ISSET(pipe, &pipefds)) { + msg->type = NACK; + + return; + } + + ret = read(pipe, msg, sizeof(*msg)); + if (ret != sizeof(*msg)) { + ERROR("Reading from pipe failed !"); + msg->type = NACK; + } +} + +static void *subprocess_thread (void *data) +{ + (void)data; + pthread_mutex_lock(&subprocess_msg_lock); + + while(1) { + pthread_cond_wait(&subprocess_wkup, &subprocess_msg_lock); + + while(subprocess_messages_count) { + struct subprocess_msg_elem *subprocess_msg; + subprocess_msg = SIMPLEQ_FIRST(&subprocess_messages); + SIMPLEQ_REMOVE_HEAD(&subprocess_messages, next); + --subprocess_messages_count; + pthread_mutex_unlock(&subprocess_msg_lock); + + handle_subprocess_ipc(subprocess_msg); + send_subprocess_reply(subprocess_msg); + close(subprocess_msg->client); + + free(subprocess_msg); + pthread_mutex_lock(&subprocess_msg_lock); + } + } + + return NULL; +} + void *network_thread (void *data) { struct installer *instp = (struct installer *)data; @@ -249,17 +367,18 @@ void *network_thread (void *data) int nread; struct msg_elem *notification; int ret; - int pipe; - fd_set pipefds; - struct timeval tv; update_state_t value; + struct subprocess_msg_elem *subprocess_msg; if (!instp) { TRACE("Fatal error: Network thread aborting..."); return (void *)0; } + subprocess_ipc_handler_thread_id = start_thread(subprocess_thread, NULL); + SIMPLEQ_INIT(¬ifymsgs); + SIMPLEQ_INIT(&subprocess_messages); register_notifier(network_notifier); /* Initialize and bind to UDS */ @@ -287,7 +406,8 @@ void *network_thread (void *data) nread = read(ctrlconnfd, (void *)&msg, sizeof(msg)); if (nread != sizeof(msg)) { - TRACE("IPC message too short: fragmentation not supported"); + TRACE("IPC message too short: fragmentation not supported (read %d bytes)", + nread); close(ctrlconnfd); continue; } @@ -309,72 +429,22 @@ void *network_thread (void *data) } break; case SWUPDATE_SUBPROCESS: - /* - * this request is not for the installer, - * but for one of the subprocesses - * forward the request without checking - * the payload - */ - - pipe = pctl_getfd_from_type(msg.data.procmsg.source); - if (pipe < 0) { - ERROR("Cannot find channel for requested process"); - msg.type = NACK; - break; - } - TRACE("Received Message for %s", - pctl_getname_from_type(msg.data.procmsg.source)); - if (fcntl(pipe, F_GETFL) < 0 && errno == EBADF) { - ERROR("Pipe not available or closed: %d", pipe); + subprocess_msg = (struct subprocess_msg_elem*)malloc( + sizeof(struct subprocess_msg_elem)); + if (subprocess_msg == NULL) { + ERROR("Cannot handle subprocess IPC because of OOM."); msg.type = NACK; break; } - /* - * Cleanup the queue to be sure there are not - * outstanding messages - */ - empty_pipe(pipe); - - ret = write(pipe, &msg, sizeof(msg)); - if (ret != sizeof(msg)) { - ERROR("Writing to pipe failed !"); - msg.type = NACK; - break; - } - - /* - * Do not block forever for an answer - * This would block the whole thread - * If a message requires more time, - * the destination process should sent an - * answer back explaining this in the payload - */ - FD_ZERO(&pipefds); - FD_SET(pipe, &pipefds); - tv.tv_usec = 0; - if (!msg.data.procmsg.timeout) - tv.tv_sec = DEFAULT_INTERNAL_TIMEOUT; - else - tv.tv_sec = msg.data.procmsg.timeout; - ret = select(pipe + 1, &pipefds, NULL, NULL, &tv); - - /* - * If there is an error or timeout, - * send a NACK back - */ - if (ret <= 0 || !FD_ISSET(pipe, &pipefds)) { - msg.type = NACK; - break; - } - - ret = read(pipe, &msg, sizeof(msg)); - if (ret != sizeof(msg)) { - ERROR("Reading from pipe failed !"); - msg.type = NACK; - break; - } + subprocess_msg->client = ctrlconnfd; + subprocess_msg->message = msg; + pthread_mutex_lock(&subprocess_msg_lock); + ++subprocess_messages_count; + SIMPLEQ_INSERT_TAIL(&subprocess_messages, subprocess_msg, next); + pthread_cond_signal(&subprocess_wkup); + pthread_mutex_unlock(&subprocess_msg_lock); /* * ACK/NACK was inserted by the called SUBPROCESS * It should not be touched here @@ -453,12 +523,15 @@ void *network_thread (void *data) msg.type = NACK; sprintf(msg.data.msg, "Wrong request: aborting"); } - ret = write(ctrlconnfd, &msg, sizeof(msg)); - if (ret < 0) - printf("Error write on socket ctrl"); - if (msg.type != ACK) - close(ctrlconnfd); + if (msg.type == ACK || msg.type == NACK || msg.type == GET_STATUS) { + ret = write(ctrlconnfd, &msg, sizeof(msg)); + if (ret < 0) + printf("Error write on socket ctrl"); + + if (msg.type != ACK) + close(ctrlconnfd); + } pthread_mutex_unlock(&stream_mutex); } while (1); return (void *)0;