Devuan bug report logs - #227
nbd-client: At shutdown nbd-client disabled before file-systems could be cleanly unmounted

Package: sysvinit-utils; Reported by: David Kuehling <[email protected]>; Keywords: upstream; Done: Mark Hindley <[email protected]>; Maintainer for sysvinit-utils is Devuan Developers <[email protected]>.

Message received at [email protected]:


Received: (at 227-done) by bugs.devuan.org; 1 Jul 2023 15:10:32 +0000
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from email.devuan.org [2a01:4f8:140:32a1::58c6:6473]
	by doc.devuan.org with IMAP (fetchmail-6.4.16)
	for <debbugs@localhost> (single-drop); Sat, 01 Jul 2023 15:10:32 +0000 (UTC)
Received: from email.devuan.org
	by email.devuan.org with LMTP
	id bfraGKxBoGQKFgAAmSBk0A
	(envelope-from <[email protected]>)
	for <[email protected]>; Sat, 01 Jul 2023 15:09:32 +0000
Received: by email.devuan.org (Postfix, from userid 109)
	id 5A7F2AC2; Sat,  1 Jul 2023 15:09:32 +0000 (UTC)
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on email.devuan.org
X-Spam-Level: 
X-Spam-Status: No, score=0.4 required=5.0 tests=RDNS_DYNAMIC,SPF_PASS
	autolearn=no autolearn_force=no version=3.4.6
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=193.36.131.86; helo=mx.hindley.org.uk; [email protected]; receiver=<UNKNOWN> 
Received: from mx.hindley.org.uk (193-36-131-86.cfwn.uk [193.36.131.86])
	by email.devuan.org (Postfix) with ESMTPS id CD38A618
	for <[email protected]>; Sat,  1 Jul 2023 15:09:31 +0000 (UTC)
Received: from hindley.org.uk (apollo.hindleynet [192.168.1.3])
	by mx.hindley.org.uk (Postfix) with SMTP id 4AB507F6;
	Sat,  1 Jul 2023 16:09:30 +0100 (BST)
Received: (nullmailer pid 28355 invoked by uid 1000);
	Sat, 01 Jul 2023 15:09:29 -0000
Date: Sat, 1 Jul 2023 16:09:29 +0100
From: Mark Hindley <[email protected]>
To: David Kuehling <[email protected]>
Cc: [email protected]
Subject: Re: bug#227: nbd-client: At shutdown nbd-client disabled before
 file-systems could be cleanly unmounted
Message-ID: <[email protected]>
References: <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <[email protected]>

Version: 3.07-1

David,

The upstream fix of killall5 to properly observe /run/sendsigs.omit.d/ is
included in this version.

Closing as fixed

Mark
-- 
Mark Hindley
GPG: 506C 15A4 2B0A F5A0 A854  23EE D28A 45BF 3287 D649

Notification sent to David Kuehling <[email protected]>:
bug acknowledged by developer. Full text available.
Reply sent to Mark Hindley <[email protected]>:
You have taken responsibility. Full text available.

Message received at [email protected]:


Received: (at 227) by bugs.devuan.org; 20 Feb 2023 11:25:36 +0000
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from email.devuan.org [2001:41d0:2:d06e::5c4:2612]
	by doc.devuan.org with IMAP (fetchmail-6.4.16)
	for <debbugs@localhost> (single-drop); Mon, 20 Feb 2023 11:25:36 +0000 (UTC)
Received: from email.devuan.org
	by email.devuan.org with LMTP
	id IaJgFIRY82OFDgAAmSBk0A
	(envelope-from <[email protected]>)
	for <[email protected]>; Mon, 20 Feb 2023 11:24:52 +0000
Received: by email.devuan.org (Postfix, from userid 109)
	id 4173190; Mon, 20 Feb 2023 11:24:52 +0000 (UTC)
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on email.devuan.org
X-Spam-Level: 
X-Spam-Status: No, score=0.4 required=5.0 tests=RDNS_DYNAMIC,SPF_PASS
	autolearn=no autolearn_force=no version=3.4.6
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=193.36.131.86; helo=mx.hindley.org.uk; [email protected]; receiver=<UNKNOWN> 
Received: from mx.hindley.org.uk (193-36-131-86.cfwn.uk [193.36.131.86])
	by email.devuan.org (Postfix) with ESMTPS id 1EB0A25
	for <[email protected]>; Mon, 20 Feb 2023 11:24:46 +0000 (UTC)
Received: from apollo.hindleynet ([192.168.1.3] helo=hindley.org.uk)
	by mx.hindley.org.uk with smtp (Exim 4.84_2)
	(envelope-from <[email protected]>)
	id 1pU4Hi-0004RY-Sl; Mon, 20 Feb 2023 11:24:42 +0000
Received: (nullmailer pid 19341 invoked by uid 1000);
	Mon, 20 Feb 2023 11:24:42 -0000
Date: Mon, 20 Feb 2023 11:24:42 +0000
From: Mark Hindley <[email protected]>
To: Jesse Smith <[email protected]>
Cc: David Kuehling <[email protected]>, [email protected]
Subject: Re: bug#227: nbd-client: At shutdown nbd-client disabled before
 file-systems could be cleanly unmounted
Message-ID: <Y/[email protected]>
References: <[email protected]>
 <[email protected]>
 <[email protected]>
 <Y+5XMAODvbjKHf/[email protected]>
 <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <[email protected]>

Control: tags -1 fixed-upstream

Jesse,

Thanks for you quick work on this.

On Sun, Feb 19, 2023 at 01:03:16AM -0400, Jesse Smith wrote:
> I looked at this issue some more and it turns out option #2 doesn't
> really makes sense with the way killall5 works.


Yes, I see that

> I've tested this change and it seems to work. I'm attaching a new copy
> of killall5 for testing. It's also available on GitHub in the 3.07
> branch of sysvinit.

Since Debian is frozen at the moment, I will do a build for experimental in due
course.

Thanks

Mark

Acknowledgement sent to Mark Hindley <[email protected]>:
Extra info received and forwarded to list. Copy sent to Devuan Developers <[email protected]>. Full text available.
Information forwarded to [email protected], Devuan Developers <[email protected]>:
bug#227; Package sysvinit-utils. Full text available.

Message received at [email protected]:


Received: (at 227) by bugs.devuan.org; 19 Feb 2023 05:04:32 +0000
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from email.devuan.org [2001:41d0:2:d06e::5c4:2612]
	by doc.devuan.org with IMAP (fetchmail-6.4.16)
	for <debbugs@localhost> (single-drop); Sun, 19 Feb 2023 05:04:32 +0000 (UTC)
Received: from email.devuan.org
	by email.devuan.org with LMTP
	id SlGRGaat8WPWTwAAmSBk0A
	(envelope-from <[email protected]>)
	for <[email protected]>; Sun, 19 Feb 2023 05:03:34 +0000
Received: by email.devuan.org (Postfix, from userid 109)
	id 5654EB11; Sun, 19 Feb 2023 05:03:34 +0000 (UTC)
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on email.devuan.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,
	DKIM_VALID_AU,FREEMAIL_FROM,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,
	RCVD_IN_MSPIKE_H2,SPF_PASS autolearn=ham autolearn_force=no
	version=3.4.6
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=74.6.133.125; helo=sonic313-15.consmr.mail.bf2.yahoo.com; [email protected]; receiver=<UNKNOWN> 
Received: from sonic313-15.consmr.mail.bf2.yahoo.com (sonic313-15.consmr.mail.bf2.yahoo.com [74.6.133.125])
	by email.devuan.org (Postfix) with ESMTPS id 6AB1F34
	for <[email protected]>; Sun, 19 Feb 2023 05:03:26 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.ca; s=s2048; t=1676783004; bh=w1I/jzM5VQP+HjN9uwgLMnGWlgnpN8JSZyOHbWuYpd8=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From:Subject:Reply-To; b=jZGTmgTc7Vk8UyR2Mlwf3RXJFHpE1/1IGy6qIgoc+dWiLo11bk5RI8My3AGiOQdvbgqfAtsB1hgfCIIIRV8o+fz+tCVV4DGkuIKj34hEs9RiByshQQCxr3bL5/k603nAan8t7oiDV5RORP8gRcdDLr4DdcR4LA3It6ApzTD+NKbh1plkYxaEFG3fbrREqTrk0GQtAaZuazQzDx5RD/P/vyjyRZ9+LZ323Va/gMVKU/PoicRXC5lg//CjRgdfRC53gckXKhxnE6NWzbZbNY2Z/jyHV1sZOwPb6m0FfhBB8llIDY6S1qc64Pa3JiCwhPxfvQR5QifjtbNKHLRK90867Q==
X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1676783004; bh=mBfxGik79OJst7RW6bHLrVAaDMMMpSyvVdsAA1DD3P9=; h=X-Sonic-MF:Subject:To:From:Date:From:Subject; b=EVDbmPyYK3eOdYPmTNl6jk8CU6zDhZq53CPHXrRBDq7fRGzXds2VZ27Y+L36cVCwhyuAR+8WyybKLOamptKLfSLB32vrpstrar7LM7zXinxuAe5se9/FE7gNuyVwwJHbrJmybGYr3wwqvE4yNzwFmAuVolLbFmpo9d/9Hja2vYLSWohvXcJr+jrDYeQqB2WTgMOWbb6gjW/e8OUcKQU2pkZ7wQQ6ZDlFR+bAUM864UgY421/OIJT9CK7AAY7FniKjzgOYmlDskqQLiEP83PvXLlB3kMKvLPsSLVJzEhqxTpSG28DdYP3IQR9TOtZaFar6jhkM4OGhEfwQjSXEHHwuQ==
X-YMail-OSG: Qgc8HqcVM1krSbof00DjWMMVk0IOxacIeiPyJmUZcVn0pIx9SEqcT2KIAfIF9oT
 1XV7aDnyR5IvxWCd8CI757.Fus9VO4zOF1P8z3Npr8llXsau.VjMYQDEkYHt4MX_yVZJVfR8YzbZ
 vm0KnMEHgeeuGo2d2.VtKbj9lc0WkFfC25ZPIARH5I1lznre9eGNw8NCmUbYQHwJ7TAsc9CMW9he
 dTyjW8RcI6iX7j.MdmskJ7am38_3H7tuL_.y5RcY_gF1wQMzvQxYwsY_SwBJ_dOms8XjN7GqmeK.
 dkL_QnwuqpdaXo13TGlNyg12VurxZCdcGIvBW7HoZA9HbYop3h2F_rvZX2Ib7rTcVBWujalvuTxS
 qDS5dj2dnPspzWCTKNcycVOtEiY.WM1jQi9XbB3DZbLRtxXGD5IPBpcc441FlqgHxNkhD_n.6Vse
 u_SiW_6Pu9pbkw7OgnM1CIWcnAx1RPmJI6mIVnbEOGfq9x0hOJXBM1kg2YR4U7IVyU86DPENIcOH
 03GWcMtfL.iH4aoFJIt6EXdeBc4ca8mIprwLeK7piAXmMKshww6Bewf4572P5iLtvRXn7qrrvv9i
 VxebBFr4GRpuWMeW1Lo8MUnwzrqd6UUj6KvyauyUkjFcs4QZmfmoquuu8KO3xvx_QO3aBf.Wktim
 6syri20vVb0CamZVlX.1S95JnQC5_Z9RZsOpvYjTu7EY7zAohY48LMUukW7G_QqLO6yIFVt3VQfy
 KnK7QrbLikqgZaOZ84m3PxLbcCW3WmB2H95_mTkfMxhAdwwmHUh6QBRt21lDBNbHZIBwGsW7RP7j
 Bsn6Du0kkusq4oHyV8wK24MyiT9.Bxs71EsBOKFMNn37FcQnMI.UMXcq9xAPtVbAu6_dXy6GJPOA
 cPQDg068ffH5q3ras0UyU1wHUIA4xCZ13hNP.l_dsW71O3q.0LbGbtSuwPSX_66JkozmFxikQajz
 CUy8GoBY1UMtNa53fbJ3LW8GgCY.ZUU5TDTYuLHdgUmF60wQuOrrtXYv4htYgSFGaSzo6BC3UzLp
 p2zT6pkMDQCU1HfsxWECYSlOhnPUEdxgN8FCRsEOX.NPhFCcc1n2GDK3WzMTnw.cR6G.qS52EOK3
 Q6zIP1ntv_MUGvZIfWYxyZ0CgxNQC0aSojE.MkkvaQPJQqhvW6dZRUnBpy5OqW7ZLyiHMWs9OhwQ
 78OcUv8CDw5.iv0BOPiy5GViSZcEUqsVKQ_VF3xj46kz8xn1bhlXdtoWMESR2oVk_x26s9g3J7gD
 BaUxXbUU7ynN.TvDhBT5ac0rdWBGbsYXH_hWYCiP3fNQHMCyaY8wD3D1GlS_raSFGjshM66MBKJS
 Oehd7Zb6cQJC2ThebsyklbNvTgjD7DaPQzbpCnBdzLQuW4arOP4CZlyGXduSIAUwrAP.JBqGQyif
 7hiOVIBeUkOQfa3ms.rj1QgX.d3Pz0DdRxVX1CXysaG5t6WQcyThNd4n42HEabqo3_QnloCEimAp
 HP7Q9B6VDWK0_43NpIZ2rD.WCY_W7n3SXRjd_0IsFWTIEn7DqMMYPJVtqhfOvwTDkzuSt6bsSDAr
 MvXB2PrhxT8qWzPCs6ki0JCKH64rK2WLTnwii1NjAZZFOvT_JHEKr.kCmIbOX8GS4ECd8dvIzEfF
 OGTC3eFbgz7Jy9GZlXLsXPUyy48EltP.T9PwkOUdiNhCulwnatcYXptV.bNxLCcekjUs54HKYQvl
 POYSiLsMt2qOj7Jbi3vcWBbVk3EpQPJxejaroKNvfmDjY8HBnh1mKKAh65dQfqiiTSb5hWIvgYjT
 CQfTNXwTH4fGPkJxZFq82v_SUvXUp4TU75sNboeIu0g.BKDawrbKAmFV4bM8YCgW5Wrnv3AepGOK
 regVfposlFkGgUhr4SOYHHw9Stl8o0DsygRSPmCE5IloFEmzIJ9GTTGvyLCxHFjyasE1e1WUn0Oc
 WuKjCZ99kS.JWtaQepmcV13jCGE4_pXW.r1bC.zaGGjDxm0wUKupQ4J66B4Rw2xgy22oJc_13ccA
 o_KfVPnicxygzO.tTpbzUv4KDOr2Hgl9RIi9x7HuHEmxZNyL.FEymkxPFcUNbDBkezISG4KQagi.
 2g9VgpAEk2vBJ0y6u2CELPZbnf93Oo8FyvhtShzD1OYX5wZsU9w0xF0lT_nnka9BUT0vWuFhUE__
 3MmVL55oh_ixICbdK.k5OK9cL7YBkHOSQbR3F_j2aEq_fEx3b5tyGcsqwJ6rVa6Adc2k.hCweVAj
 wSH1aIYX1rFmTIInMzSJMrid8S4.diwDrYB2j9vyeD0dbGdy2B5GW8A--
X-Sonic-MF: <[email protected]>
Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.bf2.yahoo.com with HTTP; Sun, 19 Feb 2023 05:03:24 +0000
Received: by hermes--production-gq1-655ddccc9-zfzhj (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 9c275a2ca59a61c8d63dd7c8c2b9c24e;
          Sun, 19 Feb 2023 05:03:18 +0000 (UTC)
Subject: Re: bug#227: nbd-client: At shutdown nbd-client disabled before
 file-systems could be cleanly unmounted
To: Mark Hindley <[email protected]>
Cc: David Kuehling <[email protected]>, [email protected]
References: <[email protected]>
 <[email protected]>
 <[email protected]>
 <Y+5XMAODvbjKHf/[email protected]>
From: Jesse Smith <[email protected]>
Message-ID: <[email protected]>
Date: Sun, 19 Feb 2023 01:03:16 -0400
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
 Thunderbird/78.13.0
MIME-Version: 1.0
In-Reply-To: <Y+5XMAODvbjKHf/[email protected]>
Content-Type: multipart/mixed;
 boundary="------------F0E8AD74D4D601E640AF11BB"
Content-Language: en-CA
X-Mailer: WebService/1.1.21183 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo

This is a multi-part message in MIME format.
--------------F0E8AD74D4D601E640AF11BB
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

On 2023-02-16 12:17 p.m., Mark Hindley wrote:
> Control: reassign -1 sysvinit-utils
> Control: affects -1 nbd-client
>
> Jesse,
>
> Thanks for you quick reply.
>
> On Thu, Feb 16, 2023 at 11:54:32AM -0400, Jesse Smith wrote:
>> I see two possible ways we could fix this:
>>
>> 1. Create a command line flag which disables the SIGSTOP and SIGCONT
>> signals being sent. This is an easy fix, quick and dirty. The potential
>> downside is if someone disables the STOP signal then maybe processes
>> terminate, move groups, or are replaced before we get around to sending
>> them the KILL signal. This probably won't happen, but it means killall5
>> is working with a "moving target".
>>
>> 2. We can run SIGSTOP on all processes _except_ those in the omit list.
>> This will be a lot slower than the existing "kill(-1, SIGSTOP)" call we
>> currently make. But I think it's more correct.
>>
>> Basically the new work flow would look like this:
>>
>> 1. Send all processes except those omitted the SIGSTOP command.
>> 2. Send all processes except those omitted the SIGKILL command.
>> 3. Send all processes except those omitted the SIGCONT command.
>>
>> Option #2 is slow and ugly, but seems "correct" from a behaviour point
>> of view.
> I don't really like #1: it will mean patching callers to get the (more?) correct
> behaviour. So #2 seems better. Will it be significantly slower?. You could only
> use it when omitpid is specified? If there are no omitpids, the current
> behaviour seems fine.
>

I looked at this issue some more and it turns out option #2 doesn't
really makes sense with the way killall5 works. The SIGSTOP signal is
sent out to basically pause everything on the system so we can sort
through what is available to be terminated and what should be spared. If
we want to go through the whole process tree to see what should or
should not be stopped first, then it removes the point of sending
SIGSTOP to give us a fixed collection of processes.

In other words, sending SIGSTOP only makes sense if we later want to
freeze everything and then sort processes into what we will terminate
and what will be omitted. If we are going to go through all the
processes and send some the SIGSTOP signal and not others, then we might
as well just skip the STOP and move straight on to terminating
appropriate processes.

I've tried to work in a reasonable middle ground. Now, if no processes
are in the "omit" list, we stick to the original behaviour. We stop
everything, sort through which processes we will terminate, then send
everything the SIGCONT signal. Just like before.

However, if there are any processes in the "omit" list, then we err on
the side of caution. Nothing is sent STOP or CONT, we just sort through
the processes we know about quickly and try to terminate everything
we're supposed to kill. And ignore anything in the process list.

It's not perfect, we could conceivably miss a process that was created
while we were sorting through the list after the point we'd normally
send SIGSTOP. However, this approach makes certain we do not damage any
process that can't handle receiving SIGSTOP.

The downside is that a process could get created after killall5 is run
and before it is terminated. However, this is always going to be the
case when we allow some programs to be in the "omit" list. Any of the
omitted programs could spawn a new process, so that risk already
existed. This doesn't really make the situation (much) worse.

I've tested this change and it seems to work. I'm attaching a new copy
of killall5 for testing. It's also available on GitHub in the 3.07
branch of sysvinit.

Also, as a bonus, a bunch of the killall5 code didn't initialize
variables, seeming to assume a specific code path or that the compiler
would initialize variables to zero/NULL. Since this isn't always true,
I've initialized variables we might now use in unexpected order or which
should be NULL/false at the start of the program.

- Jesse


--------------F0E8AD74D4D601E640AF11BB
Content-Type: text/x-csrc; charset=UTF-8;
 name="killall5.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="killall5.c"

/*
 * killall5.c	Kill all processes except processes that have the
 *		same session id, so that the shell that called us
 *		won't be killed. Typically used in shutdown scripts.
 *
 * pidof.c	Tries to get the pid of the process[es] named.
 *
 * Version:	2.86 30-Jul-2004 MvS
 *
 * Usage:	killall5 [-][signal]
 *		pidof [-s] [-o omitpid [-o omitpid]] program [program..]
 *
 * Authors:	Miquel van Smoorenburg, [email protected]
 *
 *		Riku Meskanen, <[email protected]>
 *		- return all running pids of given program name
 *		- single shot '-s' option for backwards compatibility
 *		- omit pid '-o' option and %PPID (parent pid metavariable)
 *		- syslog() only if not a connected to controlling terminal
 *		- swapped out programs pids are caught now
 *
 *		Werner Fink
 *		- make omit dynamic
 *		- provide '-n' to skip stat(2) syscall on network based FS
 *
 *		This file is part of the sysvinit suite,
 *		Copyright (C) 1991-2004 Miquel van Smoorenburg.
 *
 *		This program is free software; you can redistribute it and/or modify
 *		it under the terms of the GNU General Public License as published by
 *		the Free Software Foundation; either version 2 of the License, or
 *		(at your option) any later version.
 *
 *		This program is distributed in the hope that it will be useful,
 *		but WITHOUT ANY WARRANTY; without even the implied warranty of
 *		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *		GNU General Public License for more details.
 *
 *		You should have received a copy of the GNU General Public License
 *		along with this program; if not, write to the Free Software
 *		Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <mntent.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#ifndef PATH_MAX
#  ifdef MAXPATHLEN
#    define PATH_MAX MAXPATHLEN
#  else
#    define PATH_MAX 2048
#  endif
#endif

#define STATNAMELEN	15

/* Info about a process. */
typedef struct proc {
	char *pathname;		/* full path to executable        */
	char *argv0;		/* Name as found out from argv[0] */
	char *argv0base;	/* `basename argv[1]`		  */
	char *argv1;		/* Name as found out from argv[1] */
	char *argv1base;	/* `basename argv[1]`		  */
	char *statname;		/* the statname without braces    */
	pid_t pid;		/* Process ID.			  */
	pid_t sid;		/* Session ID.			  */
	char kernel;		/* Kernel thread or zombie.	  */
	char nfs;		/* Name found on network FS.	  */
	struct proc *next;	/* Pointer to next struct. 	  */
} PROC;

/* pid queue */

typedef struct pidq {
	PROC		*proc;
	struct pidq	*next;
} PIDQ;

typedef struct {
	PIDQ		*head;
	PIDQ		*tail;
	PIDQ		*next;
} PIDQ_HEAD;

typedef struct _s_omit {
	struct _s_omit *next;
	struct _s_omit *prev;
	pid_t pid;
} OMIT;

typedef struct _s_shadow
{
	struct _s_shadow *next;
	struct _s_shadow *prev;
	size_t nlen;
	char * name;
} SHADOW;

typedef struct _s_nfs
{
	struct _s_nfs *next;	/* Pointer to next struct. */
	struct _s_nfs *prev;	/* Pointer to previous st. */
	SHADOW *shadow;		/* Pointer to shadows      */
	size_t nlen;
	char * name;
} NFS;

/* List of processes. */
PROC *plist = NULL;

/* List of processes to omit. */
OMIT *omit = NULL;

/* List of NFS mountes partitions. */
NFS *nlist = NULL;

/* Did we stop all processes ? */
int sent_sigstop = 0;
int scripts_too = 0;

/* Should pidof try to list processes in I/O wait (D) and zombie (Z) states? */
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
int list_dz_processes = FALSE;

char *progname;	/* the name of the running program */
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
void nsyslog(int pri, char *fmt, ...);

#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
# ifndef  inline
#  define inline	__inline__
# endif
# ifndef  restrict
#  define restrict	__restrict__
# endif
#endif
#define alignof(type)	((sizeof(type)+(sizeof(void*)-1)) & ~(sizeof(void*)-1))

/*
 *	Malloc space, barf if out of memory.
 */
#ifdef __GNUC__
static void *xmalloc(size_t) __attribute__ ((__malloc__));
#endif
static void *xmalloc(size_t bytes)
{
	void *p;

	if ((p = malloc(bytes)) == NULL) {
		if (sent_sigstop) kill(-1, SIGCONT);
		nsyslog(LOG_ERR, "out of memory");
		exit(1);
	}
	return p;
}

#ifdef __GNUC__
static inline void xmemalign(void **, size_t, size_t) __attribute__ ((__nonnull__ (1)));
#endif
static inline void xmemalign(void **memptr, size_t alignment, size_t size)
{
	if ((posix_memalign(memptr, alignment, size)) < 0) {
		if (sent_sigstop) kill(-1, SIGCONT);
		nsyslog(LOG_ERR, "out of memory");
		exit(1);
	}
}

/*
 *	See if the proc filesystem is there. Mount if needed.
 */
int mount_proc(void)
{
	struct stat	st;
	char		*args[] = { "mount", "-t", "proc", "proc", "/proc", 0 };
	pid_t		pid, rc;
	int		wst;
	int		did_mount = 0;

	/* Stat /proc/version to see if /proc is mounted. */
	if (stat("/proc/version", &st) < 0 && errno == ENOENT) {

		/* It's not there, so mount it. */
		if ((pid = fork()) < 0) {
			nsyslog(LOG_ERR, "cannot fork");
			exit(1);
		}
		if (pid == 0) {
			/* Try a few mount binaries. */
			execv("/bin/mount", args);
			execv("/sbin/mount", args);

			/* Okay, I give up. */
			nsyslog(LOG_ERR, "cannot execute mount");
			exit(1);
		}
		/* Wait for child. */
		while ((rc = wait(&wst)) != pid)
			if (rc < 0 && errno == ECHILD)
				break;
		if (rc != pid || WEXITSTATUS(wst) != 0)
			nsyslog(LOG_ERR, "mount returned non-zero exit status");

		did_mount = 1;
	}

	/* See if mount succeeded. */
	if (stat("/proc/version", &st) < 0) {
		if (errno == ENOENT)
			nsyslog(LOG_ERR, "/proc not mounted, failed to mount.");
		else
			nsyslog(LOG_ERR, "/proc unavailable.");
		exit(1);
	}

	return did_mount;
}

static inline int isnetfs(const char * type)
{
	static const char* netfs[] = {"nfs", "nfs4", "smbfs", "cifs", "afs", "ncpfs", (char*)0};
	int n;
	for (n = 0; netfs[n]; n++) {
		if (!strcasecmp(netfs[n], type))
			return 1;
	}
	return 0;
}

/*
 *     Remember all NFS typed partitions.
 */
void init_nfs(void)
{
        struct stat st;
        struct mntent * ent;
	FILE * mnt;

	nlist = (NFS*)0;

	if (stat("/proc/version", &st) < 0)
		return;
	if ((mnt = setmntent("/proc/mounts", "r")) == (FILE*)0)
		return;

	while ((ent = getmntent(mnt))) {
		if (isnetfs(ent->mnt_type)) {
			size_t nlen = strlen(ent->mnt_dir);
			NFS *restrict p;
			xmemalign((void*)&p, sizeof(void*), alignof(NFS)+(nlen+1));
			p->name = ((char*)p)+alignof(NFS);
			p->nlen = nlen;
			p->shadow = (SHADOW*)0;

			strcpy(p->name, ent->mnt_dir);
			if (nlist)
				nlist->prev = p;
			p->next = nlist;
			p->prev = (NFS*)0;
			nlist = p;
		}
	}
	endmntent(mnt);

	if ((mnt = setmntent("/proc/mounts", "r")) == (FILE*)0)
		return;

	while ((ent = getmntent(mnt))) {
		NFS *p;

		for (p = nlist; p; p = p->next) {
			SHADOW * restrict s;
			size_t nlen;

			if (strcmp(ent->mnt_dir, p->name) == 0)
				continue;
			if (strncmp(ent->mnt_dir, p->name, p->nlen) != 0)
				continue;

			nlen = strlen(ent->mnt_dir);
			xmemalign((void*)&s, sizeof(void*), alignof(SHADOW)+(nlen+1));
			s->name = ((char*)s)+alignof(SHADOW);
			s->nlen = nlen;

			strcpy(s->name, ent->mnt_dir);
			if (p->shadow)
			    p->shadow->prev = s;
			s->next = p->shadow;
			s->prev = (SHADOW*)0;
			p->shadow = s;
		}
	}
	endmntent(mnt);
}

static void clear_shadow(SHADOW *restrict shadow)
{
	SHADOW *s, *n, *l;

	n = shadow;
	l = (SHADOW*)0;
	for (s = shadow; n; s = n) {
		l = s->prev;
		n = s->next;
		if (s == shadow) {
			if (n) n->prev = (SHADOW*)0;
			shadow = n;
		} else if (l) {
			if (n) n->prev = l;
			l->next = n;
		}
		free(s);
	}
}

static void clear_mnt(void)
{
	NFS *p, *n, *l;

	n = nlist;
	l = (NFS*)0;
	for (p = nlist; n; p = n) {
		l = p->prev;
		n = p->next;
		if (p == nlist) {
			if (n) n->prev = (NFS*)0;
			nlist = n;
		} else if (l) {
			if (n) n->prev = l;
			l->next = n;
		}
		if (p->shadow)
			clear_shadow(p->shadow);
		free(p);
	}
}

/*
 *     Check if path is a shadow off a NFS partition.
 */
static int shadow(SHADOW *restrict this, const char *restrict name, const size_t nlen)
{
	SHADOW *s;

	if (!this)
		goto out;
	for (s = this; s; s = s->next) {
		if (nlen < s->nlen)
			continue;
		if (name[s->nlen] != '\0' && name[s->nlen] != '/')
			continue;
		if (strncmp(name, s->name, s->nlen) == 0)
			return 1;
	}
out:
	return 0;
}

/*
 * Get the maximal number of symlinks to follow.  Use sysconf() on
 * Hurd where the hardcoded value MAXSYMLINKS is not available.
 */
static int maxsymlinks(void)
{
	int v = sysconf(_SC_SYMLOOP_MAX);
#ifdef MAXSYMLINKS
	if (v == -1)
		return MAXSYMLINKS;
#endif
	return v;
}

/*
 *     Check path is located on a network based partition.
 */
int check4nfs(const char * path, char * real)
{
	char buf[PATH_MAX+1];
	const char *curr;
	int deep = maxsymlinks();

	if (!nlist) return 0;

	curr = path;
	do {
		const char *prev;
		int len;

		if ((prev = strdupa(curr)) == NULL) {
			nsyslog(LOG_ERR, "strdupa(): %s\n", strerror(errno));
			return 0;
		}

		errno = 0;
		if ((len = readlink(curr, buf, PATH_MAX)) < 0)
			break;
		buf[len] = '\0';

		if (buf[0] != '/') {
			const char *slash;

			if ((slash = strrchr(prev, '/'))) {
				size_t off = slash - prev + 1;

				if (off + len > PATH_MAX)
					len = PATH_MAX - off;

				memmove(&buf[off], &buf[0], len + 1);
				memcpy(&buf[0], prev, off);
			}
		}
		curr = &buf[0];

		if (deep-- <= 0) return 0;

	} while (1);

	if (real)     /* real is defined elsewhere as being PATH_MAX + 1 */
        {
           memset(real, '\0', PATH_MAX + 1);
           strncpy(real, curr, PATH_MAX);
        }

	if (errno == EINVAL) {
		const size_t nlen = strlen(curr);
		NFS *p;
		for (p = nlist; p; p = p->next) {
			if (nlen < p->nlen)
				continue;
			if (curr[p->nlen] != '\0' && curr[p->nlen] != '/')
				continue;
			if (!strncmp(curr, p->name, p->nlen)) {
				if (shadow(p->shadow, curr, nlen))
					continue;
				return 1;
			}
		}
	}

	return 0;
}

int readarg(FILE *fp, char *buf, int sz)
{
	int		c = 0, f = 0;

	while (f < (sz-1) && (c = fgetc(fp)) != EOF && c)
		buf[f++] = c;
	buf[f] = 0;

	return (c == EOF && f == 0) ? c : f;
}

/*
 *	Read the proc filesystem.
 *	CWD must be /proc to avoid problems if / is affected by the killing (ie depend on fuse).
 */
int readproc()
{
	DIR		*dir;
	FILE		*fp;
	PROC		*p, *n;
	struct dirent	*d;
	char		path[PATH_MAX+1];
	char		buf[PATH_MAX+1];
	char		*s, *q;
	unsigned long	startcode, endcode;
	int		pid, f;
        char            process_status[11];

	/* Open the /proc directory. */
	if (chdir("/proc") == -1) {
		nsyslog(LOG_ERR, "chdir /proc failed");
		return -1;
	}
	if ((dir = opendir(".")) == NULL) {
		nsyslog(LOG_ERR, "cannot opendir(/proc)");
		return -1;
	}

	/* Free the already existing process list. */
	n = plist;
	for (p = plist; n; p = n) {
		n = p->next;
		if (p->argv0) free(p->argv0);
		if (p->argv1) free(p->argv1);
		if (p->statname) free(p->statname);
		if (p->pathname) free(p->pathname);
		free(p);
	}
	plist = NULL;

	/* Walk through the directory. */
	while ((d = readdir(dir)) != NULL) {

		/* See if this is a process */
		if ((pid = atoi(d->d_name)) == 0) continue;

		/* Get a PROC struct . */
		p = (PROC *)xmalloc(sizeof(PROC));
		memset(p, 0, sizeof(PROC));

		/* Open the status file. */
		snprintf(path, sizeof(path), "%s/stat", d->d_name);

		/* Read SID & statname from it. */
		if ((fp = fopen(path, "r")) != NULL) {
			size_t len;

			len = fread(buf, sizeof(char), sizeof(buf)-1, fp);
			buf[len] = '\0';

			if (buf[0] == '\0') {
				nsyslog(LOG_ERR,
					"can't read from %s\n", path);
				fclose(fp);
				free(p);
				continue;
			}

			/* See if name starts with '(' */
			s = buf;
			while (*s && *s != ' ') s++;
			if (*s) s++;
			if (*s == '(') {
				/* Read program name. */
				q = strrchr(buf, ')');
				if (q == NULL) {
					p->sid = 0;
					nsyslog(LOG_ERR,
					"can't get program name from /proc/%s\n",
						path);
					fclose(fp);
					if (p->argv0) free(p->argv0);
					if (p->argv1) free(p->argv1);
					if (p->statname) free(p->statname);
					if (p->pathname) free(p->pathname);
					free(p);
					continue;
				}
				s++;
			} else {
				q = s;
				while (*q && *q != ' ') q++;
			}
			if (*q) *q++ = 0;
			while (*q == ' ') q++;
			p->statname = (char *)xmalloc(strlen(s)+1);
			strcpy(p->statname, s);

			/* Get session, startcode, endcode. */
			startcode = endcode = 0;
			if (sscanf(q,   "%10s %*d %*d %d %*d %*d %*u %*u "
					"%*u %*u %*u %*u %*u %*d %*d "
					"%*d %*d %*d %*d %*u %*u %*d "
					"%*u %lu %lu",
					process_status, 
					&p->sid, &startcode, &endcode) != 4) {

				p->sid = 0;
				nsyslog(LOG_ERR, "can't read sid from %s\n",
					path);
				fclose(fp);
				if (p->argv0) free(p->argv0);
				if (p->argv1) free(p->argv1);
				if (p->statname) free(p->statname);
				free(p->pathname);
				free(p);
				continue;
			}
			if (startcode == 0 && endcode == 0)
				p->kernel = 1;
			fclose(fp);
                        if ( (! list_dz_processes) &&
                               (strchr(process_status, 'Z') != NULL) ) {
                           /* Ignore zombie processes */
                              if (p->argv0) free(p->argv0);
                              if (p->argv1) free(p->argv1);
                              if (p->statname) free(p->statname);
                             free(p);
                             continue;
                        }
		} else {
			/* Process disappeared.. */
			if (p->argv0) free(p->argv0);
			if (p->argv1) free(p->argv1);
			if (p->statname) free(p->statname);
			if (p->pathname) free(p->pathname);
			free(p);
			continue;
		}

		snprintf(path, sizeof(path), "%s/cmdline", d->d_name);
		if ((fp = fopen(path, "r")) != NULL) {

			/* Now read argv[0] */
			f = readarg(fp, buf, sizeof(buf));

			if (buf[0]) {
				/* Store the name into malloced memory. */
				p->argv0 = (char *)xmalloc(f + 1);
				strcpy(p->argv0, buf);

				/* Get a pointer to the basename. */
				p->argv0base = strrchr(p->argv0, '/');
				if (p->argv0base != NULL)
					p->argv0base++;
				else
					p->argv0base = p->argv0;
			}

			/* And read argv[1] */
			while ((f = readarg(fp, buf, sizeof(buf))) != EOF)
				if (buf[0] != '-') break;

			if (buf[0]) {
				/* Store the name into malloced memory. */
				p->argv1 = (char *)xmalloc(f + 1);
				strcpy(p->argv1, buf);

				/* Get a pointer to the basename. */
				p->argv1base = strrchr(p->argv1, '/');
				if (p->argv1base != NULL)
					p->argv1base++;
				else
					p->argv1base = p->argv1;
			}

			fclose(fp);

		} else {
			/* Process disappeared.. */
			if (p->argv0) free(p->argv0);
			if (p->argv1) free(p->argv1);
			if (p->statname) free(p->statname);
			if (p->pathname) free(p->pathname);
			free(p);
			continue;
		}

		/* Try to stat the executable. */
		snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name);
                p->pathname = (char *)xmalloc(PATH_MAX);
 		if (readlink(path, p->pathname, PATH_MAX) == -1) {
 			p->pathname = NULL;
 		}

		/* Link it into the list. */
		p->next = plist;
		plist = p;
		p->pid = pid;
	}
	closedir(dir);

	/* Done. */
	return 0;
}

PIDQ_HEAD *init_pid_q(PIDQ_HEAD *q)
{
	q->head =  q->next = q->tail = NULL;
	return q;
}

int empty_q(PIDQ_HEAD *q)
{
	return (q->head == NULL);
}

int add_pid_to_q(PIDQ_HEAD *q, PROC *p)
{
	PIDQ *tmp;

	tmp = (PIDQ *)xmalloc(sizeof(PIDQ));

	tmp->proc = p;
	tmp->next = NULL;

	if (empty_q(q)) {
		q->head = tmp;
		q->tail  = tmp;
	} else {
		q->tail->next = tmp;
		q->tail = tmp;
	}
	return 0;
}

PROC *get_next_from_pid_q(PIDQ_HEAD *q)
{
	PROC		*p;
	PIDQ		*tmp = q->head;

	if (!empty_q(q)) {
		p = q->head->proc;
		q->head = tmp->next;
		free(tmp);
		return p;
	}

	return NULL;
}

/* Try to get the process ID of a given process. */
PIDQ_HEAD *pidof(char *prog)
{
	PROC		*p;
	PIDQ_HEAD	*q;
	char		*s;
	int		nfs = 0;
	int		dostat = 0;
	int		foundone = 0;
	int		ok = 0;
	const int	root = (getuid() == 0);
	char		real_path[PATH_MAX+1];

	if (! prog)
		return NULL;

	/* Try to stat the executable. */
	if ( (prog[0] == '/') && ( realpath(prog, real_path) ) ) {
		memset(&real_path[0], 0, sizeof(real_path));
		dostat++;
	}

	/* Get basename of program. */
	if ((s = strrchr(prog, '/')) == NULL)
		s = prog;
	else
		s++;

	if (! *s)
		return NULL;

	q = (PIDQ_HEAD *)xmalloc(sizeof(PIDQ_HEAD));
	q = init_pid_q(q);

	/* First try to find a match based on dev/ino pair. */
	if (dostat) {
		for (p = plist; p; p = p->next) {
			if (p->pathname && strcmp(real_path, p->pathname) == 0) {
				add_pid_to_q(q, p);
				foundone++;
			}
		}
	}

	/* Second try to find a match based on full path name on
	 * network FS located binaries */
	if (!foundone && nfs) {
		for (p = plist; p; p = p->next) {
			if (!p->pathname)
				continue;
			if (!p->nfs)
				continue;
			if (strcmp(prog, p->pathname) != 0)
				continue;
			add_pid_to_q(q, p);
			foundone++;
		}
	}

	/* If we didn't find a match based on dev/ino, try the name. */
	if (!foundone) for (p = plist; p; p = p->next) {
		if (prog[0] == '/') {
			if (!p->pathname) {
				if (root)
					continue;
				goto fallback; 
			}
			if (strcmp(prog, p->pathname)) {
				int len = strlen(prog);
				if (strncmp(prog, p->pathname, len))
				{
					if (scripts_too)
						goto fallback;
					continue;
				}
				if (strcmp(" (deleted)", p->pathname + len))
				{
					if (scripts_too)
						goto fallback;
					continue;
				}
			}
			add_pid_to_q(q, p);
			continue;
		}

	fallback:
		ok = 0;

		/*             matching        nonmatching
		 * proc name   prog name       prog name
		 * ---         -----------     ------------
		 *   b         b, p/b, q/b
		 * p/b         b, p/b          q/b
		 *
		 * Algorithm: Match if:
		 *    cmd = arg
		 * or cmd = base(arg)
		 * or base(cmd) = arg
		 *
		 * Specifically, do not match just because base(cmd) = base(arg)
		 * as was done in earlier versions of this program, since this
		 * allows /aaa/foo to match /bbb/foo .
		 */
		ok |=
			(p->argv0 && strcmp(p->argv0, prog) == 0)
			|| (p->argv0 && s != prog && strcmp(p->argv0, s) == 0)
			|| (p->argv0base && strcmp(p->argv0base, prog) == 0);

		/* For scripts, compare argv[1] as well. */
		if (
			scripts_too && p->statname && p->argv1base
			&& !strncmp(p->statname, p->argv1base, STATNAMELEN)
		) {
			ok |=
				(p->argv1 && strcmp(p->argv1, prog) == 0)
				|| (p->argv1 && s != prog && strcmp(p->argv1, s) == 0)
				|| (p->argv1base && strcmp(p->argv1base, prog) == 0);
		}

		/*
		 *	if we have a space in argv0, process probably
		 *	used setproctitle so try statname.
		 */
		if (strlen(s) <= STATNAMELEN &&
		    (p->argv0 == NULL ||
		     p->argv0[0] == 0 ||
		     strchr(p->argv0, ' '))) {
			ok |= (strcmp(p->statname, s) == 0);
		}

		/*
		 *	if we have a `-' as the first character, process
		 *	probably used as a login shell
		 */
		if (strlen(s) <= STATNAMELEN &&
		    p->argv1 == NULL &&
		    (p->argv0 != NULL &&
		     p->argv0[0] == '-')) {
			ok |= (strcmp(p->statname, s) == 0);
		}

		if (ok) add_pid_to_q(q, p);
	}

	return q;
}

/* Give usage message and exit. */
void usage(void)
{
	nsyslog(LOG_ERR, "usage: killall5 -signum [-o omitpid] [-o omitpid] ...");
	closelog();
	exit(1);
}


void pidof_usage(void)
{
   printf("pidof usage: [options] <program-name>\n\n");
   printf(" -c           Return PIDs with the same root directory\n");
   printf(" -d <sep>     Use the provided character as output separator\n");
   printf(" -h           Display this help text\n");
   printf(" -n           Avoid using stat system function on network shares\n");
   printf(" -o <pid>     Omit results with a given PID\n");
   printf(" -q           Quiet mode. Do not display output\n");
   printf(" -s           Only return one PID\n");
   printf(" -x           Return PIDs of shells running scripts with a matching name\n");
   printf(" -z           List zombie and I/O waiting processes. May cause pidof to hang.\n");
   printf("\n");
}


/* write to syslog file if not open terminal */
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
void nsyslog(int pri, char *fmt, ...)
{
	va_list  args;

	va_start(args, fmt);

	if (ttyname(0) == NULL) {
		vsyslog(pri, fmt, args);
	} else {
		fprintf(stderr, "%s: ",progname);
		vfprintf(stderr, fmt, args);
		fprintf(stderr, "\n");
	}

	va_end(args);
}

#define PIDOF_SINGLE	0x01
#define PIDOF_OMIT	0x02
#define PIDOF_NETFS	0x04
#define PIDOF_QUIET     0x08

/*
 *	Pidof functionality.
 */
int main_pidof(int argc, char **argv)
{
	PIDQ_HEAD	*q;
	PROC		*p;
	char		*token, *here;
	int		f;
	int		first = 1;
	int		opt, flags = 0;
	int		chroot_check = 0;
	struct stat	st;
	char		tmp[512];
        char            sep = ' ';

	omit = (OMIT*)0;
	nlist = (NFS*)0;
	opterr = 0;

	if ((token = getenv("PIDOF_NETFS")) && (strcmp(token,"no") != 0))
		flags |= PIDOF_NETFS;

	while ((opt = getopt(argc,argv,"qhco:d:sxzn")) != EOF) switch (opt) {
		case '?':
			nsyslog(LOG_ERR,"invalid options on command line!\n");
			closelog();
			exit(1);
		case 'c':
			if (geteuid() == 0) chroot_check = 1;
			break;
                case 'h':
                        pidof_usage();
                        exit(0);
                case 'd':
                        sep = optarg[0];
                        break;
		case 'o':
			here = optarg;
			while ((token = strsep(&here, ",;:"))) {
				OMIT *restrict optr;
				pid_t opid;

				if (strcmp("%PPID", token) == 0)
					opid = getppid();
				else
					opid = (pid_t)atoi(token);

				if (opid < 1) {
					nsyslog(LOG_ERR,
						"illegal omit pid value "
						"(%s)!\n", token);
					continue;
				}
				xmemalign((void*)&optr, sizeof(void*), alignof(OMIT));
				optr->next = omit;
				optr->prev = (OMIT*)0;
				optr->pid  = opid;
				omit = optr;
			}
			flags |= PIDOF_OMIT;
			break;
                case 'q':
                        flags |= PIDOF_QUIET;
                        break; 
		case 's':
			flags |= PIDOF_SINGLE;
			break;
		case 'x':
			scripts_too++;
			break;
                case 'z':
                        list_dz_processes = TRUE;
                        break;
		case 'n':
			flags |= PIDOF_NETFS;
			break;
		default:
			/* Nothing */
			break;
	}
	argc -= optind;
	argv += optind;

	/* Check if we are in a chroot */
	if (chroot_check) {
		snprintf(tmp, 512, "/proc/%d/root", getpid());
		if (stat(tmp, &st) < 0) {
			nsyslog(LOG_ERR, "stat failed for %s!\n", tmp);
			closelog();
			exit(1);
		}
	}

	if (flags & PIDOF_NETFS)
		init_nfs();		/* Which network based FS are online? */

	/* Print out process-ID's one by one. */
	readproc();

	for(f = 0; f < argc; f++) {
		if ((q = pidof(argv[f])) != NULL) {
			pid_t spid = 0;
			while ((p = get_next_from_pid_q(q))) {
				if ((flags & PIDOF_OMIT) && omit) {
					OMIT * optr;
					for (optr = omit; optr; optr = optr->next) {
						if (optr->pid == p->pid)
							break;
					}

					/*
					 *	On a match, continue with
					 *	the for loop above.
					 */
					if (optr)
						continue;
				}
				if (flags & PIDOF_SINGLE) {
					if (spid)
						continue;
					else
						spid = 1;
				}
				if (chroot_check) {
					struct stat st2;
					snprintf(tmp, 512, "/proc/%d/root",
						 p->pid);
					if (stat(tmp, &st2) < 0 ||
					    st.st_dev != st2.st_dev ||
					    st.st_ino != st2.st_ino) {
						continue;
					}
				}

				if ( ~flags & PIDOF_QUIET ) {
					if (! first)
						printf("%c", sep);
					printf("%d", p->pid);
				}
				first = 0;
			}
		}
	}
	if (!first)
        {
            if ( ~flags & PIDOF_QUIET ) 
		printf("\n");
        }

	clear_mnt();

	closelog();
	return(first ? 1 : 0);
}

/* Main for either killall or pidof. */
int main(int argc, char **argv)
{
	PROC		*p;
	int		pid, sid = -1;
	int		sig = SIGKILL;
	int		c;

	/* return non-zero if no process was killed */
	int		retval = 2;

	/* Get program name. */
	if ((progname = strrchr(argv[0], '/')) == NULL)
		progname = argv[0];
	else
		progname++;

	/* Now connect to syslog. */
	openlog(progname, LOG_CONS|LOG_PID, LOG_DAEMON);

	/* Were we called as 'pidof' ? */
	if (strcmp(progname, "pidof") == 0)
		return main_pidof(argc, argv);

	/* Right, so we are "killall". */
	omit = (OMIT*)0;

	if (argc > 1) {
		for (c = 1; c < argc; c++) {
			if (argv[c][0] == '-') (argv[c])++;
			if (argv[c][0] == 'o') {
				char * token, * here;

				if (++c >= argc)
					usage();

				here = argv[c];
				while ((token = strsep(&here, ",;:"))) {
					OMIT *restrict optr;
					pid_t opid = (pid_t)atoi(token);

					if (opid < 1) {
						nsyslog(LOG_ERR,
							"illegal omit pid value "
							"(%s)!\n", token);
						continue;
					}
					xmemalign((void*)&optr, sizeof(void*), alignof(OMIT));
					optr->next = omit;
					optr->prev = (OMIT*)0;
					optr->pid  = opid;
					omit = optr;
				}
			}
			else if ((sig = atoi(argv[1])) <= 0 || sig > 31)
				usage();
		}
	}

	/* First get the /proc filesystem online. */
	mount_proc();

	/*
	 *	Ignoring SIGKILL and SIGSTOP do not make sense, but
	 *	someday kill(-1, sig) might kill ourself if we don't
	 *	do this. This certainly is a valid concern for SIGTERM-
	 *	Linux 2.1 might send the calling process the signal too.
	 */
	signal(SIGTERM, SIG_IGN);
	signal(SIGSTOP, SIG_IGN);
	signal(SIGKILL, SIG_IGN);

	/* lock us into memory */
	mlockall(MCL_CURRENT | MCL_FUTURE);

        /* Get our session ID and PID to make sure we do not kill ourselves or our session. */
	sid = (int)getsid(0);
	pid = (int)getpid();

	/* Now stop all processes, unless there are some we should omit. */
        if (! omit)
        {
	    kill(-1, SIGSTOP);
	    sent_sigstop = 1;
        }

	/* Read /proc filesystem */
	if (readproc() < 0) {
             if (sent_sigstop)
		kill(-1, SIGCONT);
  	     return(1);
	}

	/* Now kill all processes except init (pid 1) and our session. */
	for (p = plist; p; p = p->next) {
		if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel)
			continue;

		if (omit) {
			OMIT * optr;
			for (optr = omit; optr; optr = optr->next) {
				if (optr->pid == p->pid)
					break;
			}

			/* On a match, continue with the for loop above. */
			if (optr)
				continue;
		}      /* end of skipping PIDs to omit */

		kill(p->pid, sig);
		retval = 0;
	}

	/* And let them continue. */
        if (sent_sigstop)
	    kill(-1, SIGCONT);

	/* Done. */
	closelog();

	/* Force the kernel to run the scheduler */
	usleep(1);

	return retval;
}

--------------F0E8AD74D4D601E640AF11BB--

Acknowledgement sent to Jesse Smith <[email protected]>:
Extra info received and forwarded to list. Copy sent to Devuan Developers <[email protected]>. Full text available.
Information forwarded to [email protected], Devuan Developers <[email protected]>:
bug#227; Package sysvinit-utils. Full text available.

Message received at [email protected]:


Received: (at 227) by bugs.devuan.org; 16 Feb 2023 16:28:37 +0000
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from email.devuan.org [2001:41d0:2:d06e::5c4:2612]
	by doc.devuan.org with IMAP (fetchmail-6.4.16)
	for <debbugs@localhost> (single-drop); Thu, 16 Feb 2023 16:28:37 +0000 (UTC)
Received: from email.devuan.org
	by email.devuan.org with LMTP
	id C4e2OWJZ7mN0UQAAmSBk0A
	(envelope-from <[email protected]>)
	for <[email protected]>; Thu, 16 Feb 2023 16:27:14 +0000
Received: by email.devuan.org (Postfix, from userid 109)
	id C679DA0; Thu, 16 Feb 2023 16:27:14 +0000 (UTC)
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on email.devuan.org
X-Spam-Level: 
X-Spam-Status: No, score=-1.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,
	DKIM_VALID_AU,FREEMAIL_FROM,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,SPF_PASS
	autolearn=ham autolearn_force=no version=3.4.6
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=74.6.131.124; helo=sonic311-14.consmr.mail.bf2.yahoo.com; [email protected]; receiver=<UNKNOWN> 
Received: from sonic311-14.consmr.mail.bf2.yahoo.com (sonic311-14.consmr.mail.bf2.yahoo.com [74.6.131.124])
	by email.devuan.org (Postfix) with ESMTPS id D552223
	for <[email protected]>; Thu, 16 Feb 2023 16:27:08 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.ca; s=s2048; t=1676564826; bh=Gw+hKeqXuum0lnAKVZd5Us+sz2EQwg8xbx24cVAhfsI=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From:Subject:Reply-To; b=UiM56mhDf+VqIfWOCHpewc3CkPBA+zb3XhhZYh2Ir2OzpWJM0pmo+mkW/zCC//Wwsy5SvcaABuRs5PNYfTksmMO/Rei4ZURWTZmdRL9MQzVspXKXSLZCiNfWGi7WcZn2vjV7/4WmRYjycK3MyqSkYelzJFMZGiDtlsIT1GVz08ix6nLpRMtMsLizNWP2tiy07oHvtsCVpc583SIwHIEIc0ebNFqbwy4WI67e9SV8knjHlgdCe37VaJRUFqeyku8ZdtZ6ImgEr4LPNLYiFdk3lfRbbReU6FYrFuliegISyBP0U3wGOvsKducAoXHPVdWH6f0BvnZzlW65walHgn5xbA==
X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1676564826; bh=gSCcX1caN6P0agSpQBxWpIyRBivQssSO8o2FWdEutgc=; h=X-Sonic-MF:Subject:To:From:Date:From:Subject; b=nqBiX8Xhnspo6eUVrmQ28oxrsmBH6djng0dRlqBjqMDkq3XOY37J6vnUgNmPrx4OvTUBhw5r4/y5GbPpJ8dhSy2tXWNvsR9g3fsqBIfhLtxRQNmW3a63xLQEEhsV7KPeCQH2aAVuJFRJjXscLh9tgZfMiCXUXgAA9nDdGrLCdJvagjZAn/lfvxPyAuaDxFjSfHsvhAryuiPaUTaHu+MLNQRCdLKUVSM7wFucIWM9VYEc6n9KJ05C65MFmbY8szagBBN3IL51lmJ3J2CTAEAK2CxIahJQkmwdGW9zVz8x4BSi9qwzi6gzlMHaucL9vPQ39IE41Qqcszc8td4Wy5LVNw==
X-YMail-OSG: LCNL0XsVM1kKTWtQ4jHjVKrk8tU_F3isot6Pp11lsaWFVdqRFJjlB9COeAN50l4
 kdHJ.ETkSynyvCydU.7YtjFXX2BEBcgF.A3Xmg9U47Fzyd7w8dPJt0iDwFpgoJYc1UonE7TSop4z
 0MbhFcYM_wo5bDpYGXBCgfBuTbuRP3FyNDO81gBJMHs5Cjrh51SEbxtw6WAEYAeDX0gDd.uTAO0k
 DwdvyNKyg8pfyjM8I0Kyngpb2MscPsYGvXQ.GCTyqm54I4QsdYPQ2lgF8VhjtukYxCfMKsTkLR.E
 BoKGGnpUoAd..gvM62AnmN6dVRM5TaSfvuKcNcjaTI.D8Lb45bLJ9t.b7qBThhPaFGkfrbbfiXt6
 lu4K7rT2CN.Fyg6hi7YJ14JRCHCf7ICql6Os01ZYoca7XXB.XKtNFvRHl5hkR3gX1eR3bxtMddje
 y1VfbcFBYD8GI1Zp4VFE89_06K1rthWR_NPyIICrmYd2mDR2mBaYr9vSFQwupyQPYc9HIjlvFVm9
 l2k5RCiYQB3Swi4ke6BHPk615U243VFLepFT1c_HXamWy2hNI6u2D2gu_02h3LbRrp1W5N1Keq3G
 U7sTdxmMvXVq0qDbyKMu6zo1XJhwG8ko_scNlz7g3MamobBKAvs15qGNOx7GRZWV7QLNeTa_5qPZ
 WXuplqP5Ec7vEwOlEm9mjONiPBJlDbL.F2Km7pcFHZaFzJx4zmxGHqWkZWc.wrqrXuVPUovceySW
 M4_vl4j.NRV9ftErR4eGKGObKp6mNcv1ah0Fbk14FMCFtfMuK6Ka.LVzTCIhgQIPncI3bSiye6rN
 4.PSIleh66xLmfU87bE46psPpOzZgdOKTBDjZCysSFpgXNXp5fpgxSzkCc0FL8ZWzf.4t_d1sp7p
 QtxEAmG6LMBoZVQeCraeded9NA2RNbDn4Z3mjs1YBk7cj4DztH1TLD_j5wAUEfIlzIgb39G7XltS
 8gFIRAeOJespGTlYC.mHd9x1QWn5BnTTwZMI23Vgg0FMSDpagNlM10UaZJNZAE.TSftxM2qmIs7o
 .6U5TbY6IUhk0ZTyzUNyoSZHWmdKKfow76r8FM.Y09IBBMc8omQSXiF_dTvHInDtAYeScutQ712s
 Zmz5ViW8MrJx7pzfNHiYvye5czqNjb2CWH7C3nf2mWzLR5blQzAW6yTb4_mDakMPFjiBRrczKunp
 Agt5RIjLqMdrpCkX7hSZinkgQ6CJ_3ep_VcC8MP9H1zZG_TjQGNbynN0fDnvX0lQm7oh6WNqKq7R
 9GuMxnwRe6L96lflHZQaN9i7eB3ad5qIjs7yOMlg0AMvnrbReivfxaqtCNWAiMDIIDChWYa5H2Fd
 wvgF3W4l9Kr_K6W8XbrUNAKFt51cuYqS7ih01XCAaU7Q3rX0Y.w9qItIEzlZEget41jAqf1Q8_ZY
 WioGsu5aDvMAlsNmdtgOLWneaT6JLZ4cbfu4WV80lOLgXsSJr3qwBWciQHMQFYMzG_1afMzory19
 Ih8R2MpVpHU6kYaTLoV8pvUTIlsl_HT7apiv4_MsWzveLCWsAHSQvUG6kXQ0nECTcdN_XYSpgohO
 Kt8P5hOb5ViSyPgdh7EGqqXg5.8GlrcWrxWtzXq.HF8BM_ShaChkyUgDg4sBJqg1en1cyFP.9Fhi
 tzJwJwxGG7UJsIzwsF8g0pdlbsg428oIzJmr6VvLSKIgCYkAKOC8u09dm9d92U0.gqnDP.7ff7G9
 FEFhDuV75Asa8St31n4A9Ael_ZFXS_xA9M.v_k_VmJpzKsSBBPeNflp5F1ywW5FBVchcP7i5tpyH
 U2Qw_UcvJ3GHxJrGft0pWb2rVg5Xxv36zghRZxok1QlXfUkl4vileWLNw2PfFW4WKciXfKkB6u0_
 E1.JlRWznbwG.xOAlM5RDu.8J5RiGM1KLBgPzFKlV9Nx.76b24ikwTyRKoQ9BOGYkULX6KnyccVE
 Q_oKDRlXjvaBgxvhxS0xVnBEPAsxAd4CPsTskW7auowifHYngtpmthKVY6ZiPISwSUIgzbqjblr9
 yq6ey9D2QtIMO2JnDRW9dFjBqVD3F5Bf2y1zNREfSf4kcFi3Q58Ed5SFjqL51M09HUWelWHiWgl3
 Eye6WNlY7PGuKHyIUXm3onIVrqtCX5uqYmH3jHFUgY4rSDXtQMcV83.xeLAjnJJ2lATUelAcVjig
 1kGIO6jviQu3BNisad7Y0Pcvequ029rQwYrXleIV_rpy8cJRXVqAPzH.6Jmbn_sNiSGY26TrG8E6
 UdUocM6BxLP_JzDuGP9Y6wURW2aiZty2Yz0.HEZN2wj2Nl2rF_bs1kf1Qcg--
X-Sonic-MF: <[email protected]>
Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.bf2.yahoo.com with HTTP; Thu, 16 Feb 2023 16:27:06 +0000
Received: by hermes--production-gq1-655ddccc9-hdxk5 (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 7d7ad19d4afba9ac7c2286525f4a4431;
          Thu, 16 Feb 2023 16:27:01 +0000 (UTC)
Subject: Re: bug#227: nbd-client: At shutdown nbd-client disabled before
 file-systems could be cleanly unmounted
To: Mark Hindley <[email protected]>
Cc: David Kuehling <[email protected]>, [email protected]
References: <[email protected]>
 <[email protected]>
 <[email protected]>
 <Y+5XMAODvbjKHf/[email protected]>
From: Jesse Smith <[email protected]>
Message-ID: <[email protected]>
Date: Thu, 16 Feb 2023 12:26:59 -0400
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
 Thunderbird/78.13.0
MIME-Version: 1.0
In-Reply-To: <Y+5XMAODvbjKHf/[email protected]>
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Content-Language: en-CA
X-Mailer: WebService/1.1.21183 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo

On 2023-02-16 12:17 p.m., Mark Hindley wrote:
> Control: reassign -1 sysvinit-utils
> Control: affects -1 nbd-client
>
> Jesse,
>
> Thanks for you quick reply.
>
> On Thu, Feb 16, 2023 at 11:54:32AM -0400, Jesse Smith wrote:
>> I see two possible ways we could fix this:
>>
>> 1. Create a command line flag which disables the SIGSTOP and SIGCONT
>> signals being sent. This is an easy fix, quick and dirty. The potential
>> downside is if someone disables the STOP signal then maybe processes
>> terminate, move groups, or are replaced before we get around to sending
>> them the KILL signal. This probably won't happen, but it means killall5
>> is working with a "moving target".
>>
>> 2. We can run SIGSTOP on all processes _except_ those in the omit list.
>> This will be a lot slower than the existing "kill(-1, SIGSTOP)" call we
>> currently make. But I think it's more correct.
>>
>> Basically the new work flow would look like this:
>>
>> 1. Send all processes except those omitted the SIGSTOP command.
>> 2. Send all processes except those omitted the SIGKILL command.
>> 3. Send all processes except those omitted the SIGCONT command.
>>
>> Option #2 is slow and ugly, but seems "correct" from a behaviour point
>> of view.
> I don't really like #1: it will mean patching callers to get the (more?) correct
> behaviour. So #2 seems better. Will it be significantly slower?. You could only
> use it when omitpid is specified? If there are no omitpids, the current
> behaviour seems fine.
>
>
if I had to guess, I'd assume the new approach would be about 3x slower.
But we're probably talking about loops that will finish in a thousandths
of a second. From a practical point of view, I don't think anyone will
see the difference. And, as you pointed out, if there is no list of
omitted PIDs then we can revert to the old way of doing things.

I'll look at fixing this and testing it this weekend. See if I can fix
this without breaking anything else.

- Jesse


Acknowledgement sent to Jesse Smith <[email protected]>:
Extra info received and forwarded to list. Copy sent to Devuan Developers <[email protected]>. Full text available.
Information forwarded to [email protected], Devuan Developers <[email protected]>:
bug#227; Package sysvinit-utils. Full text available.
Added indication that 227 affects nbd-client Request was from Mark Hindley <[email protected]> to [email protected]. Full text available.
bug reassigned from package 'nbd-client' to 'sysvinit-utils'. Request was from Mark Hindley <[email protected]> to [email protected]. Full text available.

Message received at [email protected]:


Received: (at 227) by bugs.devuan.org; 16 Feb 2023 16:18:06 +0000
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from email.devuan.org [2001:41d0:2:d06e::5c4:2612]
	by doc.devuan.org with IMAP (fetchmail-6.4.16)
	for <debbugs@localhost> (single-drop); Thu, 16 Feb 2023 16:18:06 +0000 (UTC)
Received: from email.devuan.org
	by email.devuan.org with LMTP
	id 6vYOKzNX7mMdUQAAmSBk0A
	(envelope-from <[email protected]>)
	for <[email protected]>; Thu, 16 Feb 2023 16:17:55 +0000
Received: by email.devuan.org (Postfix, from userid 109)
	id A7204A0; Thu, 16 Feb 2023 16:17:55 +0000 (UTC)
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on email.devuan.org
X-Spam-Level: 
X-Spam-Status: No, score=0.4 required=5.0 tests=RDNS_DYNAMIC,SPF_PASS
	autolearn=no autolearn_force=no version=3.4.6
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=193.36.131.86; helo=mx.hindley.org.uk; [email protected]; receiver=<UNKNOWN> 
Received: from mx.hindley.org.uk (193-36-131-86.cfwn.uk [193.36.131.86])
	by email.devuan.org (Postfix) with ESMTPS id 45C3723
	for <[email protected]>; Thu, 16 Feb 2023 16:17:55 +0000 (UTC)
Received: from apollo.hindleynet ([192.168.1.3] helo=hindley.org.uk)
	by mx.hindley.org.uk with smtp (Exim 4.84_2)
	(envelope-from <[email protected]>)
	id 1pSgxE-0006iS-KQ; Thu, 16 Feb 2023 16:17:52 +0000
Received: (nullmailer pid 27154 invoked by uid 1000);
	Thu, 16 Feb 2023 16:17:52 -0000
Date: Thu, 16 Feb 2023 16:17:52 +0000
From: Mark Hindley <[email protected]>
To: Jesse Smith <[email protected]>
Cc: David Kuehling <[email protected]>, [email protected]
Subject: Re: bug#227: nbd-client: At shutdown nbd-client disabled before
 file-systems could be cleanly unmounted
Message-ID: <Y+5XMAODvbjKHf/[email protected]>
References: <[email protected]>
 <[email protected]>
 <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <[email protected]>

Control: reassign -1 sysvinit-utils
Control: affects -1 nbd-client

Jesse,

Thanks for you quick reply.

On Thu, Feb 16, 2023 at 11:54:32AM -0400, Jesse Smith wrote:
> I see two possible ways we could fix this:
> 
> 1. Create a command line flag which disables the SIGSTOP and SIGCONT
> signals being sent. This is an easy fix, quick and dirty. The potential
> downside is if someone disables the STOP signal then maybe processes
> terminate, move groups, or are replaced before we get around to sending
> them the KILL signal. This probably won't happen, but it means killall5
> is working with a "moving target".
> 
> 2. We can run SIGSTOP on all processes _except_ those in the omit list.
> This will be a lot slower than the existing "kill(-1, SIGSTOP)" call we
> currently make. But I think it's more correct.
> 
> Basically the new work flow would look like this:
> 
> 1. Send all processes except those omitted the SIGSTOP command.
> 2. Send all processes except those omitted the SIGKILL command.
> 3. Send all processes except those omitted the SIGCONT command.
> 
> Option #2 is slow and ugly, but seems "correct" from a behaviour point
> of view.

I don't really like #1: it will mean patching callers to get the (more?) correct
behaviour. So #2 seems better. Will it be significantly slower?. You could only
use it when omitpid is specified? If there are no omitpids, the current
behaviour seems fine.

Thanks

Mark

Acknowledgement sent to Mark Hindley <[email protected]>:
Extra info received and forwarded to list. Copy sent to [email protected]. Full text available.
Information forwarded to [email protected], [email protected]:
bug#227; Package nbd-client. Full text available.

Message received at [email protected]:


Received: (at 227) by bugs.devuan.org; 16 Feb 2023 16:09:02 +0000
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from email.devuan.org [2001:41d0:2:d06e::5c4:2612]
	by doc.devuan.org with IMAP (fetchmail-6.4.16)
	for <debbugs@localhost> (single-drop); Thu, 16 Feb 2023 16:09:02 +0000 (UTC)
Received: from email.devuan.org
	by email.devuan.org with LMTP
	id +kMcHQ1V7mPAUAAAmSBk0A
	(envelope-from <[email protected]>)
	for <[email protected]>; Thu, 16 Feb 2023 16:08:45 +0000
Received: by email.devuan.org (Postfix, from userid 109)
	id 6B369A0; Thu, 16 Feb 2023 16:08:45 +0000 (UTC)
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on email.devuan.org
X-Spam-Level: 
X-Spam-Status: No, score=-1.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,
	DKIM_VALID_AU,FREEMAIL_FROM,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,SPF_PASS
	autolearn=ham autolearn_force=no version=3.4.6
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=74.6.131.41; helo=sonic303-2.consmr.mail.bf2.yahoo.com; [email protected]; receiver=<UNKNOWN> 
Received: from sonic303-2.consmr.mail.bf2.yahoo.com (sonic303-2.consmr.mail.bf2.yahoo.com [74.6.131.41])
	by email.devuan.org (Postfix) with ESMTPS id E175023
	for <[email protected]>; Thu, 16 Feb 2023 16:08:42 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.ca; s=s2048; t=1676563720; bh=lYAaoVVkvoFp8eGzQNijfdzhWuzZ67CRqdQLpeggQNQ=; h=Subject:To:References:From:Date:In-Reply-To:From:Subject:Reply-To; b=jcHT5vbkBzB5plCOxxF8YfclaojSrr+KCdtRbqxOTs/h/eBYiGM92sV/7RKdUtRK/EgZRiVaTe8MF6Bckyc8H85WECDtLiihU1a4VZ2+A/HpG2q9BCIIgtJyFPDtYmuGN0Ans998EeveRqE64AED8CfMbbBxwB2VdIA2mD4ojTPwgIbD1QeZ++x3tmTM/nDU1rgod9pbE3hlrGM3Emc1xufECzpzW+4msmPn8AEw0GOgOTXrpdh7araK8E8x2MBI5o8px3c25BKQ+tEAlL+n0IKv3VYHqHVxXc+lRrDIYqDUwLCjGPxRwwKFK8S79Pm0WPVQuCCWG6n5yArrB7EAYA==
X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1676563720; bh=HVJNN12j1GZB5hCuNuVMErfMwIzFF1UmDC8Grzzmc4p=; h=X-Sonic-MF:Subject:To:From:Date:From:Subject; b=C0JxSNl/soCgHtBkcGm51xbei3i9bNSJkrQLA6ANQD5cyCs5yXW8OU+AwgLrXu5Nh9933nVqcxWEWr6huBe8Lx/Ax+OCoZ+wK4L34JsmNX/nCgZHBUlSAulOcrtL+ALP9QUfQifk4zPrhS5mie4UkJj8o0DTBAG7KSzcF1i/ZZatU9ocJ+SGceqL66jZE4LmGykkfvizG+A0xs3VoIDyK+7BvCM76bK+kjeuA3HkO87Wru7FYoR3+q8pALy1u3aGs9ooxC45TPB7brG8aeqly8oiZbA0JK6pKxiDM78/Qy6Rx9ookwbUe0V9qRNZqR1ZDUZqyFiT/nIbIeDu5JVL3g==
X-YMail-OSG: AvtNiJkVM1mJl40OHLvQOIa15DbYE3YRVylM1ET57HoniFaQ_L8SxljkXqWv1Mn
 cWe859niOFD5SHB_97BZZxSodueEgcg8niBMPgX9Q9d2SnXc1yBh5PJHR6sDc0Oa4apWnX_aC2AU
 biSntfFU.JGHLZepCiktrUpoJFnjciit5cZ7aW4.oX41634dg7eO8Z4V.RcTDMDZI_Ym0JMBkn6z
 8YWoLhjKjo7Y2bSgT27AYZTAi6yIFSgeXNjW2meqLvcuVif_x6iAjfbTAiBy44Vo52u2U8iGbHYW
 Xx8GuPEOxZh51pQIj0HpTS7QBI8R6blP3yAU.tZyYV.JbBD.gxtv4gNe9sNpA99kfKl2jU95IiKp
 TMLn0KhL6mHvSkmOiWOqUVhrTviXj67aLZrOw7CNvEDS5DyZHfcAHvwdcFukNzoti1Bdne7iKgpt
 JLgxYPEgyO_cxaTIMHIY8Hqw3bg3IzdGnxXiiIccIMlrT5YmOryMEWQlLCtEpfaFOk59Dvq1GQgw
 6B1QoFhP_wMx3XWft9z8UDB6FTZnqwroqLdMLuk3fYDtelyTs5FbFtjvaN.sm2xH3H3Y403ujK4D
 sooFL63s0y0tV.vjzH8e5EDftrCU7vG8bCKhV0zpdu9CQs2e9dYWmbllYHquwyOkrgh273gDpGe6
 FI_GtrVxm4DaJrldGNkfCJ6Ft2TLbg_yKbplpFomCnsm8MNoS7eZN554.yEcdfqjJoYxbkhXk1UG
 Mjt6rwDPphdmXt_.RarIXx2zckQ8fURRGyoRHmfX7Iv0hsNXe9REBUt5A2Yd8XS6VZiFT3rZke36
 8r55NUL79bSYx0pJdI1ML_.vMPcr7uFnPAZK7PaBCcOTp17B0JuMMmwZjkjWCnFu1eDbLJGdr.oR
 fWLs20gtR.bTUp7mCW4qS5xbgaFTfDr_Klnp6cK29UGxZ8OczhpzMWkgOjsBjnV0OGFnZ6WP8SgX
 j3CTDIAXRWs7FiMv3BYx9y0BN9JGfXW49Aitb4oUlx7r0pB6xlVLa7.q6.iPD1lxld.kvAYfnsBT
 gvgg.Ql7jEnYF8cUU75P7xxm2qPMv9NWRZp6RCpJXNRolxLQucOXXQyd3Uo2aPLnsGpPXVm3lhEv
 VeIhJFYy2N7wBg.9_yb1ohsMCqQwVv0kD9jttBvPDc9JbKP0VpG8IV6pz.kHrGyhVUd0aTMJ_DDw
 xp01aQpt_ccW24xFm1ATMlSidJibP1aGCsXJTbowh4QU55GzjnK9ZYV4BL3B.lWBjx5zjtCBJF.y
 uANBen6MHBUyKJhv53c2Xr1bPsbZ5F0ueMPgGM2h3nOfQ.UCLAfeL4YgplRwz9Uz4_vmlr31osg_
 x50CVdQ9fytdQbJnBFjdSJ29mJhRNF6Rt9hqJJOtmd22q7fjvHcXSkgIYMTt9BWLM2OnJb1ZScia
 QsJZyIis3WDFm_VuBjJCeJyj_YzPcK8AhlunrsGSrAxcIBxNDs8ChdCeYN5dknbXxJS51qLgoVn9
 ttLpqRYuCTIXpsHdjT2wFbnymars0rOFT3HIgPruB9n7zTNmOX4VpfGByCInTJ9rpTfg.VDq3RSX
 Vx.fRLTJyit5SF3AQ8TBNx4yfe22ZKSR_Us8O__R3fO7PmLrQC1PebWfK6Lx6fgjMNfbQ4fGmDRC
 nQ0.WgVEd6aQzyoW0uWMsargy1D01awbYj3f0dTkCgq6HHJdiVxO0zmmDjCTa8ot5pdSe7I00qBf
 6UjQM2Tl2uQiuAPc9dExvBmCromi.b2a9IiupESAyhIU8IPJZ9YBNK0wqZ9Z9i1GT8muCnjqWWcM
 teuNA0k92AsJxJNIFsvwvpZm30OSRC5zr_RzMK4pwXyQXmTKW2LSupNUYUJPlf1KG_3PCSJpNma7
 8E92SKrk9YleAbDrS1JWnZugnutBrRufNsEmac9IEl2ssBYbWa4gCqJ_0nLVYnOCrY8BaGGGEfE.
 BH.SB0fxx5RmywwvqAQCMSB6oGnQj5edRzvKmugU4d.wkv8XQG8TJhuxV1su4qc100dDqOcZRhaP
 TUCa9ipBqN4wdW4WLUz3x6ANnehAVN_5eBot_F0DXjSe1e4zkkhAZZUdciKeccLjg670sji6HrGb
 XIkR..qMyu9hB_aOOEL2lIBd4WQELKQi9UOTYXyrzVBmIyTxaKnjn3LjvlwKVWXQYLt7wSNY48is
 Vjqmg7JuVxojoRIbwL9jSNHhNDv1FwbTRSai5O4sTERCwp31rOUsi8GXfk8lPfd0BlqDt7P9N3pL
 yJsu4r_UBwkymt0nKHckuff4E1l1BzPvOhLFHq1Jax6Tf.74z6FH1DbEZ8IAP
X-Sonic-MF: <[email protected]>
Received: from sonic.gate.mail.ne1.yahoo.com by sonic303.consmr.mail.bf2.yahoo.com with HTTP; Thu, 16 Feb 2023 16:08:40 +0000
Received: by hermes--production-gq1-655ddccc9-nql2v (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 812ef8049f229529834550bd7cb8832e;
          Thu, 16 Feb 2023 16:08:37 +0000 (UTC)
Subject: Re: bug#227: nbd-client: At shutdown nbd-client disabled before
 file-systems could be cleanly unmounted
To: Mark Hindley <[email protected]>, David Kuehling <[email protected]>,
 [email protected]
References: <[email protected]>
 <[email protected]>
From: Jesse Smith <[email protected]>
Message-ID: <[email protected]>
Date: Thu, 16 Feb 2023 12:08:34 -0400
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
 Thunderbird/78.13.0
MIME-Version: 1.0
In-Reply-To: <[email protected]>
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Content-Language: en-CA
X-Mailer: WebService/1.1.21183 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo

On 2023-02-16 11:22 a.m., Mark Hindley wrote:
> Control: tags -1 upstream
>
> David,
>
> I know it has been a long time, but thanks for this.
>
> On Mon, Jul 16, 2018 at 01:52:51AM +0200, David Kuehling wrote:
>> Short summary of the problem: during shutdown /etc/init.d/sendsigs calls
>> killall5 binary from sysvinit-utils, killing almost all running
>> processes.
>>
>> Of course it never should kill nbd-client, so the /etc/init.d/nbd-client
>> script is smart enough to register its PID to be exempt from sendsig's
>> action: by recording it in the /run/sendsigs.omit.d/nbd-cient file.
>>
>> These PIDs are then collected by /etc/init.d/sendsig and passed as "-o
>> NNN" options to killall5 which spares those processes from premature
>> termination.
>>
>> However, before killall5 goes on to kill all the other processes, it
>> does a:
>>
>> 	/* Now stop all processes. */
>> 	kill(-1, SIGSTOP);
>>
>> And when it's done, it does:
>>
>> 	/* And let them continue. */
>> 	kill(-1, SIGCONT);
>>
>> These SIGSTOP, SIGCONT signals are passed to all processes, including
>> nbd-client.  Unfortunately nbd-client is written in a way that makes it
>> unable to handle any signals delivered while it is inside an ioctl call,
>> and it looses its server connection on SIGSTOP, totally breaking the
>> block devices it provides.
>>
>> What would be the right way to prevent this problem?  Fix sysvinit?
> My inclination here is that killall5 shouldn't send any signals (including a
> STOP CONT pair) to processes that have registered to be omitted.
>
> Copying Jesse Smith the sysvinit maintainer.
>
> Jesse what do you think? Is it possible to avoid that?
>
>


Thanks for the detailed bug report and explanation.

The way I see it this probably is a bug in the way killall5 operates. If
we've been explicitly told not to send signals to a process, then we
shouldn't send any signals to that process. It shouldn't matter if the
signal is STOP, CONT, or TERM.

I see two possible ways we could fix this:

1. Create a command line flag which disables the SIGSTOP and SIGCONT
signals being sent. This is an easy fix, quick and dirty. The potential
downside is if someone disables the STOP signal then maybe processes
terminate, move groups, or are replaced before we get around to sending
them the KILL signal. This probably won't happen, but it means killall5
is working with a "moving target".

2. We can run SIGSTOP on all processes _except_ those in the omit list.
This will be a lot slower than the existing "kill(-1, SIGSTOP)" call we
currently make. But I think it's more correct.

Basically the new work flow would look like this:

1. Send all processes except those omitted the SIGSTOP command.
2. Send all processes except those omitted the SIGKILL command.
3. Send all processes except those omitted the SIGCONT command.

Option #2 is slow and ugly, but seems "correct" from a behaviour point
of view.

I'm open to comments before I patch this.

- Jesse


Acknowledgement sent to Jesse Smith <[email protected]>:
Extra info received and forwarded to list. Copy sent to [email protected]. Full text available.
Information forwarded to [email protected], [email protected]:
bug#227; Package nbd-client. Full text available.
Added tag(s) upstream. Request was from Mark Hindley <[email protected]> to [email protected]. Full text available.

Message received at [email protected]:


Received: (at 227) by bugs.devuan.org; 16 Feb 2023 15:24:04 +0000
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from email.devuan.org [2001:41d0:2:d06e::5c4:2612]
	by doc.devuan.org with IMAP (fetchmail-6.4.16)
	for <debbugs@localhost> (single-drop); Thu, 16 Feb 2023 15:24:04 +0000 (UTC)
Received: from email.devuan.org
	by email.devuan.org with LMTP
	id 2C6BFkZK7mPaTgAAmSBk0A
	(envelope-from <[email protected]>)
	for <[email protected]>; Thu, 16 Feb 2023 15:22:46 +0000
Received: by email.devuan.org (Postfix, from userid 109)
	id 53449A1; Thu, 16 Feb 2023 15:22:46 +0000 (UTC)
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on email.devuan.org
X-Spam-Level: 
X-Spam-Status: No, score=0.4 required=5.0 tests=RDNS_DYNAMIC,SPF_PASS
	autolearn=no autolearn_force=no version=3.4.6
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=193.36.131.86; helo=mx.hindley.org.uk; [email protected]; receiver=<UNKNOWN> 
Received: from mx.hindley.org.uk (193-36-131-86.cfwn.uk [193.36.131.86])
	by email.devuan.org (Postfix) with ESMTPS id 01EE884
	for <[email protected]>; Thu, 16 Feb 2023 15:22:45 +0000 (UTC)
Received: from apollo.hindleynet ([192.168.1.3] helo=hindley.org.uk)
	by mx.hindley.org.uk with smtp (Exim 4.84_2)
	(envelope-from <[email protected]>)
	id 1pSg5s-0006MC-AX; Thu, 16 Feb 2023 15:22:44 +0000
Received: (nullmailer pid 12521 invoked by uid 1000);
	Thu, 16 Feb 2023 15:22:44 -0000
Date: Thu, 16 Feb 2023 15:22:44 +0000
From: Mark Hindley <[email protected]>
To: David Kuehling <[email protected]>, [email protected]
Cc: [email protected]
Subject: Re: bug#227: nbd-client: At shutdown nbd-client disabled before
 file-systems could be cleanly unmounted
Message-ID: <[email protected]>
References: <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <[email protected]>
X-Debbugs-No-Ack: No Thanks

Control: tags -1 upstream

David,

I know it has been a long time, but thanks for this.

On Mon, Jul 16, 2018 at 01:52:51AM +0200, David Kuehling wrote:
> Short summary of the problem: during shutdown /etc/init.d/sendsigs calls
> killall5 binary from sysvinit-utils, killing almost all running
> processes.
> 
> Of course it never should kill nbd-client, so the /etc/init.d/nbd-client
> script is smart enough to register its PID to be exempt from sendsig's
> action: by recording it in the /run/sendsigs.omit.d/nbd-cient file.
> 
> These PIDs are then collected by /etc/init.d/sendsig and passed as "-o
> NNN" options to killall5 which spares those processes from premature
> termination.
> 
> However, before killall5 goes on to kill all the other processes, it
> does a:
> 
> 	/* Now stop all processes. */
> 	kill(-1, SIGSTOP);
> 
> And when it's done, it does:
> 
> 	/* And let them continue. */
> 	kill(-1, SIGCONT);
> 
> These SIGSTOP, SIGCONT signals are passed to all processes, including
> nbd-client.  Unfortunately nbd-client is written in a way that makes it
> unable to handle any signals delivered while it is inside an ioctl call,
> and it looses its server connection on SIGSTOP, totally breaking the
> block devices it provides.
> 
> What would be the right way to prevent this problem?  Fix sysvinit?

My inclination here is that killall5 shouldn't send any signals (including a
STOP CONT pair) to processes that have registered to be omitted.

Copying Jesse Smith the sysvinit maintainer.

Jesse what do you think? Is it possible to avoid that?

Thanks

Mark

Information forwarded to [email protected], [email protected]:
bug#227; Package nbd-client. Full text available.

Message received at [email protected]:


Received: (at submit) by bugs.devuan.org; 16 Jul 2018 00:00:03 +0000
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from tupac3.dyne.org [195.169.149.119]
	by fulcanelli with IMAP (fetchmail-6.3.26)
	for <debbugs@localhost> (single-drop); Mon, 16 Jul 2018 02:00:03 +0200 (CEST)
Received: from mout01.posteo.de (mout01.posteo.de [185.67.36.65])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(No client certificate requested)
	by vm6.ganeti.dyne.org (Postfix) with ESMTPS id 01470F60ABC
	for <[email protected]>; Mon, 16 Jul 2018 01:55:30 +0200 (CEST)
Authentication-Results: vm6.ganeti.dyne.org;
	dkim=pass (2048-bit key; secure) header.d=posteo.de [email protected] header.b="k5aWO0Lp";
	dkim-atps=neutral
Received: from submission (posteo.de [89.146.220.130]) 
	by mout01.posteo.de (Postfix) with ESMTPS id CA8202111A
	for <[email protected]>; Mon, 16 Jul 2018 01:52:52 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.de; s=2017;
	t=1531698772; bh=MbqyJhXJhX1pwz1o3aOJUCmWrKAIs+Es4rodC5gw7Tw=;
	h=From:To:Subject:Date:From;
	b=k5aWO0Lp2+UdrCgX+OLGxeS3O/Ydigjp1nisZ2GGXObJJquM/kjTNXh3iDY8GaQI3
	 IjwkXe7XRHyIy9sz2tx+KcI6Wsz/Xui/YSqXq9whQkeBOAQtrZZjhgy01iUUgTeSrX
	 NbRFPg+7PrgOrx6OeXHMr0zlYwZsP4YAMbTuBzToPkgkL047Nh7uk8/hYQwmwiRGw0
	 82uXEuh0ZFDF/OSfpe2Ybg/YDPpjTI/YLG99g0EOGqHMUrnl8h+aPd6Sky9ZBVa6Ct
	 wQjVDZ7JeirPjdiiHu+Qne++mRiAU9546MZVg/6m3psU3NgGfiLHisd17uCyiLyxyN
	 W+A4F6qXb2Q0w==
Received: from customer (localhost [127.0.0.1])
	by submission (posteo.de) with ESMTPSA id 41TNdb5yPyz9rxD
	for <[email protected]>; Mon, 16 Jul 2018 01:52:51 +0200 (CEST)
From: David Kuehling <[email protected]>
To: Devuan Bug Tracking System <[email protected]>
Subject: nbd-client: At shutdown nbd-client disabled before file-systems could be cleanly unmounted
X-Debbugs-CC: David Kuehling <[email protected]>
Date: Mon, 16 Jul 2018 01:52:51 +0200
Message-ID: <[email protected]>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Status: No, score=-2.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,
	DKIM_VALID_AU,RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,SPF_PASS autolearn=disabled
	version=3.4.1
X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on tupac3.dyne.org

Package: nbd-client
Version: 1:3.15.2-3
Severity: normal

Dear Maintainer,

I'm currently running a Devuan desktop without local storage using
pxelinux and root located on a network block device provided via
nbd-client (kernel command line "root=/dev/mapper/vg-root
nbdroot=192.168.0.123,devicename,nbd0").

Unfortunately the sysvinit tools and init scripts and the nbd-client
binary do not properly work together causing nbd-client to disconnect at
shutdown before the filesystems can be properly unmounted.

This seems to be a very old problem documented e.g. here [1] and here
[2] and it seems that systemd already got specific patches to prevent
that problem.  With only sysvinit left to exhibit the problem, this sort
of makes the bug devuan-specific (or should I still bother to report it
to debian?).

Short summary of the problem: during shutdown /etc/init.d/sendsigs calls
killall5 binary from sysvinit-utils, killing almost all running
processes.

Of course it never should kill nbd-client, so the /etc/init.d/nbd-client
script is smart enough to register its PID to be exempt from sendsig's
action: by recording it in the /run/sendsigs.omit.d/nbd-cient file.

These PIDs are then collected by /etc/init.d/sendsig and passed as "-o
NNN" options to killall5 which spares those processes from premature
termination.

However, before killall5 goes on to kill all the other processes, it
does a:

	/* Now stop all processes. */
	kill(-1, SIGSTOP);

And when it's done, it does:

	/* And let them continue. */
	kill(-1, SIGCONT);

These SIGSTOP, SIGCONT signals are passed to all processes, including
nbd-client.  Unfortunately nbd-client is written in a way that makes it
unable to handle any signals delivered while it is inside an ioctl call,
and it looses its server connection on SIGSTOP, totally breaking the
block devices it provides.

What would be the right way to prevent this problem?  Fix sysvinit?  Fix
nbd-client?  Note that for nbd-root installations nbd-client is run via
(a copy of) /usr/share/initramfs-tools/scripts/local-top/nbd and not via
/etc/init.d/nbd-client.

Other than that I'm very happy with the stability and maturity of
Devuan.  Running the installer on a diskless system, installing into a
network block device (with cryptsetup and LVM on top), then still being
able to boot the system without problems was sort of surprising :)

cheers,

David

[1] https://github.com/NetworkBlockDevice/nbd/issues/51
[2] https://sourceforge.net/p/nbd/mailman/message/27368126/

-- System Information:
Distributor ID:	Devuan
Description:	Devuan GNU/Linux 2.0 (ascii)
Release:	2.0
Codename:	ascii

Architecture: x86_64

Kernel: Linux 4.9.0-6-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)

Versions of packages nbd-client depends on:
ii  debconf [debconf-2.0]  1.5.61
ii  libc6                  2.24-11+deb9u3
ii  libgnutls30            3.5.8-5+deb9u3

nbd-client recommends no packages.

nbd-client suggests no packages.

-- debconf information:
  nbd-client/no-auto-config:
  nbd-client/killall_set:


Acknowledgement sent to David Kuehling <[email protected]>:
New bug report received and forwarded. Copy sent to David Kuehling <[email protected]>, [email protected]. Full text available.
Report forwarded to [email protected], David Kuehling <[email protected]>, [email protected]:
bug#227; Package nbd-client. Full text available.

Devuan BTS -- Powered by Debian bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.

Devuan Bugs Owner <[email protected]>.
Last modified: Sat, 18 Jan 2025 04:39:02 UTC