From patchwork Sat Feb 3 14:06:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicolas Graves X-Patchwork-Id: 59707 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id E488D27BBE9; Sat, 3 Feb 2024 14:07:03 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id CFF6527BBEA for ; Sat, 3 Feb 2024 14:06:59 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rWGfV-0005mR-IM; Sat, 03 Feb 2024 09:06:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rWGfT-0005j0-0w for guix-patches@gnu.org; Sat, 03 Feb 2024 09:06:51 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rWGfS-0002QF-Nh for guix-patches@gnu.org; Sat, 03 Feb 2024 09:06:50 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1rWGfd-0006RP-Lj for guix-patches@gnu.org; Sat, 03 Feb 2024 09:07:01 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#57387] [PATCH v3] gnu: Add restartd. References: <87czcp8wet.fsf@ngraves.fr> In-Reply-To: <87czcp8wet.fsf@ngraves.fr> Resent-From: Nicolas Graves Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 03 Feb 2024 14:07:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 57387 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 57387@debbugs.gnu.org Cc: maximedevos@telenet.be, ngraves@ngraves.fr, othacehe@gnu.org Received: via spool by 57387-submit@debbugs.gnu.org id=B57387.170696920924738 (code B ref 57387); Sat, 03 Feb 2024 14:07:01 +0000 Received: (at 57387) by debbugs.gnu.org; 3 Feb 2024 14:06:49 +0000 Received: from localhost ([127.0.0.1]:46001 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rWGfP-0006Qv-Ot for submit@debbugs.gnu.org; Sat, 03 Feb 2024 09:06:48 -0500 Received: from 8.mo575.mail-out.ovh.net ([46.105.74.219]:33077) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rWGfK-0006Qg-43 for 57387@debbugs.gnu.org; Sat, 03 Feb 2024 09:06:45 -0500 Received: from director8.ghost.mail-out.ovh.net (unknown [10.108.2.23]) by mo575.mail-out.ovh.net (Postfix) with ESMTP id ADECF29410 for <57387@debbugs.gnu.org>; Sat, 3 Feb 2024 14:06:28 +0000 (UTC) Received: from ghost-submission-6684bf9d7b-9bx58 (unknown [10.108.54.212]) by director8.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 17F131FD15; Sat, 3 Feb 2024 14:06:27 +0000 (UTC) Received: from ngraves.fr ([37.59.142.107]) by ghost-submission-6684bf9d7b-9bx58 with ESMTPSA id V05BO2NIvmXmAgAAPnR5nw (envelope-from ); Sat, 03 Feb 2024 14:06:27 +0000 Authentication-Results: garm.ovh; auth=pass (GARM-107S001a95e5700-ce43-4de3-b5b4-aa0903573b7d, F5ADB67915646DBFD32EB3060FF73679FEA22C13) smtp.auth=ngraves@ngraves.fr X-OVh-ClientIp: 81.67.146.208 Date: Sat, 3 Feb 2024 15:06:17 +0100 Message-ID: <20240203140625.25139-1-ngraves@ngraves.fr> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 X-Ovh-Tracer-Id: 5216294269097075214 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedvkedrfeduiedgheekucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucenucfjughrpefhvfevufffkffogggtgfesthekredtredtjeenucfhrhhomheppfhitgholhgrshcuifhrrghvvghsuceonhhgrhgrvhgvshesnhhgrhgrvhgvshdrfhhrqeenucggtffrrghtthgvrhhnpeeigeevkeejhefhieefffdvfeektdeitdfgkefhtddvgfetvdekleeuveffgeeuueenucffohhmrghinhepghhithhhuhgsrdgtohhmpdhlrghunhgthhhprggurdhnvghtpdguvggsihgrnhdrohhrghenucfkphepuddvjedrtddrtddruddpkedurdeijedrudegiedrvddtkedpfeejrdehledrudegvddruddtjeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepoehnghhrrghvvghssehnghhrrghvvghsrdhfrheqpdhnsggprhgtphhtthhopedupdhrtghpthhtohepheejfeekjeesuggvsggsuhhgshdrghhnuhdrohhrghdpoffvtefjohhsthepmhhoheejhedpmhhouggvpehsmhhtphhouhht X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Nicolas Graves X-ACL-Warn: , Nicolas Graves via Guix-patches X-Patchwork-Original-From: Nicolas Graves via Guix-patches via From: Nicolas Graves Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/packages/admin.scm (restartd): New variable. * gnu/packages/patches/restartd-update-robust.patch: Add file. * gnu/local.mk: Register gnu/packages/patches/restartd-update-robust.patch. Change-Id: I38b9b70e97b64f006a86d7618a75f1ec3ed8b034 --- gnu/local.mk | 1 + gnu/packages/admin.scm | 51 +++ .../patches/restartd-update-robust.patch | 295 ++++++++++++++++++ 3 files changed, 347 insertions(+) create mode 100644 gnu/packages/patches/restartd-update-robust.patch diff --git a/gnu/local.mk b/gnu/local.mk index fbdb285695..6e4c3b277b 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1981,6 +1981,7 @@ dist_patch_DATA = \ %D%/packages/patches/racket-rktio-bin-sh.patch \ %D%/packages/patches/racket-zuo-bin-sh.patch \ %D%/packages/patches/remake-impure-dirs.patch \ + %D%/packages/patches/restartd-update-robust.patch \ %D%/packages/patches/restic-0.9.6-fix-tests-for-go1.15.patch \ %D%/packages/patches/rng-tools-revert-build-randstat.patch \ %D%/packages/patches/rocclr-5.6.0-enable-gfx800.patch \ diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm index fcf05992d8..6940638c75 100644 --- a/gnu/packages/admin.scm +++ b/gnu/packages/admin.scm @@ -62,6 +62,7 @@ ;;; Copyright © 2023 Bruno Victal ;;; Copyright © 2023 Tobias Kortkamp ;;; Copyright © 2023 Jaeme Sifat +;;; Copyright © 2023 Nicolas Graves ;;; ;;; This file is part of GNU Guix. ;;; @@ -5814,6 +5815,56 @@ (define-public fail2ban mechanisms if you really want to protect services.") (license license:gpl2+))) +(define-public restartd + (let* ((commit "7044125ac55056f2663536f7137170edf92ebd75") + ;; Version is 0.2.4 in the version file in the repo + ;; but not in github tags. + ;; It is released as 0.2.3-1.1 for other distributions. + ;; Probably because of the lack of activity upstream. + (revision "1")) + (package + (name "restartd") + (version (git-version "0.2.3" revision commit)) + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/ajraymond/restartd") + (commit commit))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "1m1np00b4zvvwx63gzysbi38i5vj1jsjvh2s0p9czl6dzyz582z0")) + (patches (search-patches "restartd-update-robust.patch")))) + (build-system gnu-build-system) + (arguments + (list + #:tests? #f ; no tests + #:make-flags + #~(list (string-append "CC=" #$(cc-for-target))) + #:phases + #~(modify-phases %standard-phases + (delete 'configure) + (replace 'install + (lambda _ + (install-file "restartd.conf" (string-append #$output "/etc")) + (install-file "restartd" (string-append #$output "/sbin")) + (install-file "restartd.8" + (string-append #$output "/share/man/man8")) + (mkdir-p (string-append #$output "/share/man/fr/man8")) + (copy-file + "restartd.fr.8" + (string-append #$output "/share/man/fr/man8/restartd.8"))))))) + (home-page "https://launchpad.net/debian/+source/restartd") + (synopsis "Daemon for restarting processes") + (description "This package provides a daemon for checking running and not +running processes. It reads the /proc directory every n seconds and does a +POSIX regexp on the process names. The daemon runs an user-provided script +when it detects a program in the running processes, or an alternate script if +it doesn't detect the program. The daemon can only be called by the root +user, but can use @code{sudo -u user} in the process called if needed.") + (license license:gpl2+)))) + (define-public rex (package (name "rex") diff --git a/gnu/packages/patches/restartd-update-robust.patch b/gnu/packages/patches/restartd-update-robust.patch new file mode 100644 index 0000000000..d279ebd8ff --- /dev/null +++ b/gnu/packages/patches/restartd-update-robust.patch @@ -0,0 +1,295 @@ +From 01cd2d15a9bf1109e0e71b3e31b835d63dcf9cd8 Mon Sep 17 00:00:00 2001 +From: Maxime Devos , Yin Kangkai , Sudip Mukherjee +Subject: [PATCH] + +Fix segfault when run as normal user + +Also exit immediately when "restartd -h" +Signed-off-by: Yin Kangkai + +Fix build with gcc-10 + +Bug: https://bugs.debian.org/957761 +Signed-off-by: Sudip Mukherjee + +Handle memory allocation failures. + +This makes the code a little more robust. +Signed-off-by: Maxime Devos + +Handle fopen failures. + +This makes the code a little more robust. What if /var/run does not +exist, or we do not have permission to open +/var/run/restartd.pid (EPERM?) due to SELinux misconfiguration? +Signed-off-by: Maxime Devos + +Handle printf and fprintf failures. + +This makes the code a little more robust. What if the write was +refused to the underlying device being removed? + +The --help, debug and stderr printfs were ignored because there error +handling does not appear important to me. +Signed-off-by: Maxime Devos + +Handle fclose failures when writing. + +This makes the code a little more robust. What if a quotum is exceeded? +Signed-off-by: Maxime Devos +--- + config.c | 19 +++++++++---- + config.h | 14 ++++++---- + restartd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++------- + 3 files changed, 92 insertions(+), 21 deletions(-) + +diff --git a/config.c b/config.c +index f307b8a..5cc0271 100644 +--- a/config.c ++++ b/config.c +@@ -57,7 +57,11 @@ int read_config(void) + config_process_number = 0; + + line1 = (char *) malloc(MAX_LINE_LENGTH); ++ if (!line1) ++ oom_failure(); + line2 = (char *) malloc(MAX_LINE_LENGTH); ++ if (!line2) ++ oom_failure(); + + if ((config_fd = fopen(config_file, "rt")) == NULL) { + fprintf(stderr, "Error at opening config file: %s\n", config_file); +@@ -155,11 +159,16 @@ void dump_config(void) { + int i; + + for(i=0; i + * Copyright (C) 2006 Aurélien GÉRÔME ++ * Copyright (C) 2022 Maxime Devos + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -25,12 +26,12 @@ + + #define DEFAULT_CONFIG "/etc/restartd.conf" + +-int debug; +-int config_process_number; +-int check_interval; +-int foreground; +-struct config_process_type *config_process; +-char *config_file; ++extern int debug; ++extern int config_process_number; ++extern int check_interval; ++extern int foreground; ++extern struct config_process_type *config_process; ++extern char *config_file; + + typedef struct config_process_type { + char name[64]; +@@ -43,5 +44,6 @@ typedef struct config_process_type { + + int read_config(/* char *config_file */); + void dump_config(void); ++void oom_failure(void); + + #endif /* RESTARTD_CONFIG_H */ +diff --git a/restartd.c b/restartd.c +index 2aa720c..aa74334 100644 +--- a/restartd.c ++++ b/restartd.c +@@ -1,6 +1,7 @@ + /* restartd - Process checker and/or restarter daemon + * Copyright (C) 2000-2002 Tibor Koleszar + * Copyright (C) 2006 Aurélien GÉRÔME ++ * Copyright (C) 2022 Maxime Devos + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -35,6 +36,13 @@ + + #include "config.h" + ++int debug; ++int config_process_number; ++int check_interval; ++int foreground; ++struct config_process_type *config_process; ++char *config_file; ++ + /* SIGTERM & SIGHUP handler */ + void got_signal(int sig) + { +@@ -52,6 +60,17 @@ void got_signal(int sig) + } + } + ++/* Ignoring out-of-memory failures is risky on systems without virtual memory ++ where additionally at address 0 there is actually something important ++ mapped. Additionally, while often on Linux the OOM killer will kill processes ++ where an OOM happens, this is not always the case and there exist other systems ++ without an OOM killer (e.g. the Hurd). */ ++void oom_failure() ++{ ++ syslog(LOG_ERR, "Failed to allocate memory. Exiting."); ++ exit(1); ++} ++ + int main(int argc, char *argv[]) + { + DIR *procdir_id; +@@ -75,15 +94,21 @@ int main(int argc, char *argv[]) + + /* Options */ + config_file = strdup(DEFAULT_CONFIG); ++ if (!config_file) ++ oom_failure(); ++ + list_only = 0; + + for(i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) { + config_file = strdup(argv[i + 1]); ++ if (!config_file) ++ oom_failure(); + } + if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { + printf("restard %s - Copyright 2000-2002 Tibor Koleszar \n" +- " Copyright 2006 Aurélien GÉRÔME \n", ++ " Copyright 2006 Aurélien GÉRÔME \n" ++ " Copyright 2022 Maxime Devos \n", + VERSION); + exit(0); + } +@@ -118,10 +143,13 @@ int main(int argc, char *argv[]) + " -i : the check interval in second\n" + " -l : list configuration options\n" + " -h : help\n\n", VERSION); ++ exit(0); + } + } + + config_process = malloc(sizeof(struct config_process_type) * 128); ++ if (!config_process) ++ oom_failure(); + + read_config(); + if (list_only) { +@@ -133,9 +161,17 @@ int main(int argc, char *argv[]) + config_process_number); + + procdir_dirent = malloc(sizeof(struct dirent)); ++ if (!procdir_dirent) ++ oom_failure(); + proc_cmdline_str = (char *) malloc(1024); ++ if (!proc_cmdline_str) ++ oom_failure(); + proc_cmdline_name = (char *) malloc(1024); ++ if (!proc_cmdline_name) ++ oom_failure(); + regc = malloc(1024); ++ if (!regc) ++ oom_failure(); + + /* Catch signals */ + signal(SIGTERM, got_signal); +@@ -187,8 +223,19 @@ int main(int argc, char *argv[]) + } + + out_proc = fopen("/var/run/restartd.pid", "wt"); +- fprintf(out_proc, "%d", getpid()); +- fclose(out_proc); ++ if (!out_proc) { ++ syslog(LOG_ERR, "Failed to open /var/run/restartd.pid"); ++ return -1; ++ } ++ if (fprintf(out_proc, "%d", getpid()) < 0) { ++ syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting."); ++ return -1; ++ } ++ if (fclose(out_proc) < 0) { /* errors can happen when flushing the buffer */ ++ syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting."); ++ return -1; ++ } ++ + + while(1) { + if ((procdir_id = opendir("/proc")) == NULL) { +@@ -237,16 +284,23 @@ int main(int argc, char *argv[]) + now = time(NULL); + + out_proc = fopen("/var/run/restartd", "wt"); ++ if (!out_proc) { ++ syslog(LOG_ERR, "Failed to open /var/run/restartd.pid"); ++ return -1; ++ } + +- fprintf(out_proc, "%s\n", ctime(&now)); ++ if (fprintf(out_proc, "%s\n", ctime(&now)) < 0) { ++ syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting."); ++ return -1; ++ } + + for(i=0; i 0) { + if (strlen(config_process[i].running) > 0) { + strcpy(config_process[i].status, "running"); +- syslog(LOG_INFO, "%s is running, executing '%s'", ++ /* syslog(LOG_INFO, "%s is running, executing '%s'", + config_process[i].name, +- config_process[i].running); ++ config_process[i].running); */ + system(config_process[i].running); + } else { + strcpy(config_process[i].status, "running"); +@@ -267,12 +321,18 @@ int main(int argc, char *argv[]) + strcpy(config_process[i].status, "not running"); + } + +- fprintf(out_proc, "%-12s %-12s %s\n", +- config_process[i].name, config_process[i].status, +- config_process[i].processes); ++ if (fprintf(out_proc, "%-12s %-12s %s\n", ++ config_process[i].name, config_process[i].status, ++ config_process[i].processes) < 0) { ++ syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting."); ++ return -1; ++ } + } + +- fclose(out_proc); ++ if (fclose(out_proc) < 0) { ++ syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting."); ++ return -1; ++ } + + sleep(check_interval); + } +-- +2.37.3 +