NetBSD Problem Report #58408

From www@netbsd.org  Tue Jul  9 07:33:11 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
	 client-signature RSA-PSS (2048 bits) client-digest SHA256)
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id EFEBE1A9238
	for <gnats-bugs@gnats.NetBSD.org>; Tue,  9 Jul 2024 07:33:10 +0000 (UTC)
Message-Id: <20240709073309.8A9971A923A@mollari.NetBSD.org>
Date: Tue,  9 Jul 2024 07:33:09 +0000 (UTC)
From: nmingotti@gmail.com
Reply-To: nmingotti@gmail.com
To: gnats-bugs@NetBSD.org
Subject: cron ignores parameter "-n" in crontab
X-Send-Pr-Version: www-1.0

>Number:         58408
>Category:       bin
>Synopsis:       cron ignores parameter "-n" in crontab
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jul 09 07:35:00 +0000 2024
>Last-Modified:  Wed Jul 24 13:35:01 +0000 2024
>Originator:     Dr. Nicola Mingotti
>Release:        10.0
>Organization:
Borghi SRL
>Environment:
NetBSD pulce4 10.0 NetBSD 10.0 (GENERIC) #0: Thu Mar 28 08:33:33 UTC 2024  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/evbarm/compile/GENERIC evbarm

>Description:
According to man page crontab (5), if the modifier '-n' is used before a command no mail should be sent on successful run. This is not the case, parameter '-n' is ignored. Example below. 




>How-To-Repeat:

---- /home/p/bin/test3.sh ----------
#!/bin/sh
echo "test3.sh -- `date` " >> /home/p/bin/test.log
echo "write something and quit. "
exit 0
------------------------------------

---- /home/p/bin/test4.sh ----------
#!/bin/sh
echo "test4.sh -- `date` " >> /home/p/bin/test.log
echo "write something and fail"
exit 1
------------------------------------

p@pulce4 $> crontab -l 
-----------
#
#minute hour    mday    month   wday    command
*/1     *       *       *       *        -n /home/p/bin/test3.sh
*/1     *       *       *       *        -n /home/p/bin/test4.sh
-----------

. wait a bit
p@pulce4> mail 
----
 N 14 root@pulce4.localdom  Tue Jul  9 08:55   3/695   "Cron <p@pulce4> /home/p/bin/test3.sh"
 N 15 root@pulce4.localdom  Tue Jul  9 08:56   3/693   "Cron <p@pulce4> /home/p/bin/test4.sh"
 N 16 root@pulce4.localdom  Tue Jul  9 08:56   3/695   "Cron <p@pulce4> /home/p/bin/test3.sh"
 N 17 root@pulce4.localdom  Tue Jul  9 08:57   3/693   "Cron <p@pulce4> /home/p/bin/test4.sh"
 N 18 root@pulce4.localdom  Tue Jul  9 08:57   3/695   "Cron <p@pulce4> /home/p/bin/test3.sh"
 N 19 root@pulce4.localdom  Tue Jul  9 08:58   3/693   "Cron <p@pulce4> /home/p/bin/test4.sh"
 N 20 root@pulce4.localdom  Tue Jul  9 08:58   3/695   "Cron <p@pulce4> /home/p/bin/test3.sh"
 N 21 root@pulce4.localdom  Tue Jul  9 08:59   3/693   "Cron <p@pulce4> /home/p/bin/test4.sh"
 N 22 root@pulce4.localdom  Tue Jul  9 08:59   3/695   "Cron <p@pulce4> /home/p/bin/test3.sh"
----






>Fix:


>Audit-Trail:
From: Christos Zoulas <christos@zoulas.com>
To: gnats-bugs@netbsd.org
Cc: gnats-admin@netbsd.org,
 netbsd-bugs@netbsd.org
Subject: Re: bin/58408: cron ignores parameter "-n" in crontab
Date: Sun, 21 Jul 2024 15:45:07 -0400

 I just tried your example and it worked as expected

 log_it: (christos 5384) CMD START (/u/christos/cron1)
 log_it: (christos 15992) CMD START (/u/christos/cron2)
 [4179] child continues, closing pipes
 [4179] child reading output from grandchild
 [13945] child continues, closing pipes
 [13945] child reading output from grandchild
 [7886] child continues, closing pipes
 [7886] child reading output from grandchild
 [4179] got EOF from grandchild [0]
 log_it: (christos 4179) CMD FINISH (/usr/bin/true)
 [4179] child process done (rc=3D0), exiting
 [20135] sigchld...pid #4179 died, stat=3D0
 [20135] sigchld...no dead kids
 [7886] got data (77:w) from grandchild
 [7886] aborting pipe to mail
 [13945] got data (77:w) from grandchild
 [13945] closing pipe to mail
 [13945] got EOF from grandchild [0]
 log_it: (christos 13945) CMD FINISH (/u/christos/cron2)
 [13945] child process done (rc=3D0), exiting
 [20135] sigchld...pid #13945 died, stat=3D0
 [20135] sigchld...no dead kids

 you can try running cron -x proc


 christos

 > On Jul 9, 2024, at 3:35=E2=80=AFAM, nmingotti@gmail.com wrote:
 >=20
 >> Number:         58408
 >> Category:       bin
 >> Synopsis:       cron ignores parameter "-n" in crontab
 >> Confidential:   no
 >> Severity:       non-critical
 >> Priority:       medium
 >> Responsible:    bin-bug-people
 >> State:          open
 >> Class:          sw-bug
 >> Submitter-Id:   net
 >> Arrival-Date:   Tue Jul 09 07:35:00 +0000 2024
 >> Originator:     Dr. Nicola Mingotti
 >> Release:        10.0
 >> Organization:
 > Borghi SRL
 >> Environment:
 > NetBSD pulce4 10.0 NetBSD 10.0 (GENERIC) #0: Thu Mar 28 08:33:33 UTC =
 2024  =
 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/evbarm/compile/GENERIC =
 evbarm
 >=20
 >> Description:
 > According to man page crontab (5), if the modifier '-n' is used before =
 a command no mail should be sent on successful run. This is not the =
 case, parameter '-n' is ignored. Example below.=20
 >=20
 >=20
 >=20
 >=20
 >> How-To-Repeat:
 >=20
 > ---- /home/p/bin/test3.sh ----------
 > #!/bin/sh
 > echo "test3.sh -- `date` " >> /home/p/bin/test.log
 > echo "write something and quit. "
 > exit 0
 > ------------------------------------
 >=20
 > ---- /home/p/bin/test4.sh ----------
 > #!/bin/sh
 > echo "test4.sh -- `date` " >> /home/p/bin/test.log
 > echo "write something and fail"
 > exit 1
 > ------------------------------------
 >=20
 > p@pulce4 $> crontab -l=20
 > -----------
 > #
 > #minute hour    mday    month   wday    command
 > */1     *       *       *       *        -n /home/p/bin/test3.sh
 > */1     *       *       *       *        -n /home/p/bin/test4.sh
 > -----------
 >=20
 > . wait a bit
 > p@pulce4> mail=20
 > ----
 > N 14 root@pulce4.localdom  Tue Jul  9 08:55   3/695   "Cron <p@pulce4> =
 /home/p/bin/test3.sh"
 > N 15 root@pulce4.localdom  Tue Jul  9 08:56   3/693   "Cron <p@pulce4> =
 /home/p/bin/test4.sh"
 > N 16 root@pulce4.localdom  Tue Jul  9 08:56   3/695   "Cron <p@pulce4> =
 /home/p/bin/test3.sh"
 > N 17 root@pulce4.localdom  Tue Jul  9 08:57   3/693   "Cron <p@pulce4> =
 /home/p/bin/test4.sh"
 > N 18 root@pulce4.localdom  Tue Jul  9 08:57   3/695   "Cron <p@pulce4> =
 /home/p/bin/test3.sh"
 > N 19 root@pulce4.localdom  Tue Jul  9 08:58   3/693   "Cron <p@pulce4> =
 /home/p/bin/test4.sh"
 > N 20 root@pulce4.localdom  Tue Jul  9 08:58   3/695   "Cron <p@pulce4> =
 /home/p/bin/test3.sh"
 > N 21 root@pulce4.localdom  Tue Jul  9 08:59   3/693   "Cron <p@pulce4> =
 /home/p/bin/test4.sh"
 > N 22 root@pulce4.localdom  Tue Jul  9 08:59   3/695   "Cron <p@pulce4> =
 /home/p/bin/test3.sh"
 > ----
 >=20
 >=20
 >=20
 >=20
 >=20
 >=20
 >> Fix:
 >=20

From: "Dr. Nicola Mingotti" <nmingotti@gmail.com>
To: gnats-bugs@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc: 
Subject: Re: bin/58408: cron ignores parameter "-n" in crontab
Date: Mon, 22 Jul 2024 17:36:45 +0200

 Hi Christos, thanks for looking into it,

 I hope i am doing well replying to the email.

 To ease the reproduction of the problem I re-do it all in a VM.

 . I get an image from https://nycdn.netbsd.org/pub/arm/,
    download the image NetBSD 10.0, GENERIC 64 bit, decompress,
    change its size do 2G (required by qemu), rename to arm64.img
    for shorter command lines.

 . I run it in qemu in Linux/Debian with
 $> qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 4 -m 4g -drive 
 if=none,file=/home/p/download/arm64.img,id=hd0 -device virtio-blk-devic
 e,drive=hd0 -netdev type=user,id=net0 -device 
 virtio-net-device,netdev=net0,mac=00:11:22:33:44:55 -bios 
 /usr/share/qemu-efi-aarch64/QEMU_EFI.fd -
 nographic

 . login as root

 . Create the user "p" and its directory

 . #> su p    ( i don't set password, this is a test machine)

 . Create the file /home/p/test3.sh and /home/p/test4.sh
    code given previously, make them executable

 . Create the empty file /home/p/test.log

 . Create crontab
 -----
 # SHELL=/bin/sh
 # MAILTO=p
 #
 # minute hour    mday    month   wday    command
 */1     *       *       *       *       -n /home/p/test3.sh
 */1     *       *       *       *       -n /home/p/test4.sh
 -----

 . I can't say if the first 2 lines are relevant, they shouldn't, i guess

 . Reboot

 . Wait a bit (say 10/20 mins), the errors does not appear immediately, 
 still some
    clues are visible things are not going well

 . Some sendmail "zombie"? processes will start to accumulate, probably 
 this is
    related to issue. I guess any of these entries are related to the launch
    of a /home/p/test3.sh command
 $> ps aux | grep mail
 ps aux | grep mail
 p        385  0.0  0.1 22704  5376 ?      Is    4:54PM 0:00.54 sendmail 
 -FCronD
 p        414  0.0  0.1 22708  5380 ?      Is    4:56PM 0:00.36 sendmail 
 -FCronD
 p        808  0.0  0.1 22708  5384 ?      Is    4:57PM 0:00.44 sendmail 
 -FCronD
 p       1621  0.0  0.1 22708  5388 ?      Is    4:42PM 0:00.41 sendmail 
 -FCronD
 p       1720  0.0  0.1 22708  5392 ?      Is    4:43PM 0:00.37 sendmail 
 -FCronD
 ....

 . Afte a while some wrong mail will start to appear
    when 2 mail arrive in the same minute it is a good signal
    one of the two is about "test3.sh", so it should not be there.
 $> mail
 ----
   U  5 root@arm64.localdoma  Mon Jul 22 16:49   4/700   "Cron <p@arm64> 
 /home/p/t
 U  6 root@arm64.localdoma  Mon Jul 22 17:04   4/700   "Cron <p@arm64> 
 /home/p/t
 U  7 root@arm64.localdoma  Mon Jul 22 17:05   4/700   "Cron <p@arm64> 
 /home/p/t
 U  8 root@arm64.localdoma  Mon Jul 22 17:06   4/700   "Cron <p@arm64> 
 /home/p/t
 *** >N  9 root@arm64.localdoma  Mon Jul 22 17:07   3/690 "Cron <p@arm64> 
 /home/p/t
 *** N 10 root@arm64.localdoma  Mon Jul 22 17:07   3/689   "Cron 
 <p@arm64> /home/p/t
 N 11 root@arm64.localdoma  Mon Jul 22 17:08   3/690   "Cron <p@arm64> 
 /home/p/t
 ----

 . Indeed, opening mail (10) i get
 ---- mail-10 ----------------
 Message 10:
  From p@arm64.localdomain  Mon Jul 22 17:07:03 2024
 X-Original-To: p
 Delivered-To: p@arm64.localdomain
 From: root@arm64.localdomain (Cron Daemon)
 To: p@arm64.localdomain
 Subject: Cron <p@arm64> /home/p/test3.sh
 Auto-Submitted: auto-generated
 X-Cron-Env: <SHELL=/bin/sh>
 X-Cron-Env: <HOME=/home/p>
 X-Cron-Env: <PATH=/usr/bin:/bin:/usr/pkg/bin:/usr/local/bin>
 X-Cron-Env: <LOGNAME=p>
 X-Cron-Env: <USER=p>
 Date: Mon, 22 Jul 2024 17:07:03 +0200 (CEST)

 test3: write something and quit.
 --------------------------------------

 . This mail should have never arrived, test3.sh does not generate errors

 ==================================
 === Requested test =====
 ==================================

 . I stop cron
 #> /etc/rc.d/cron stop

 . I re-run cron as requested
 #> /usr/sbin/cron -x proc
 debug flags enabled: proc
 [2490] cron started
 [2490] do_command(/home/p/test4.sh , (p,1000,100))
 [2490] main process returning to work
 [2490] do_command(/home/p/test3.sh, (p,1000,100))
 [2490] main process returning to work
 [3145] child_process('/home/p/test4.sh ')
 [3274] child_process('/home/p/test3.sh')
 [839] grandchild process vfork()'ed
 [840] grandchild process vfork()'ed
 log_it: (p 839) CMD START (/home/p/test4.sh )
 log_it: (p 840) CMD START (/home/p/test3.sh)
 [3145] child continues, closing pipes
 [3274] child continues, closing pipes
 [3274] child reading output from grandchild
 [3145] child reading output from grandchild
 [3274] got data (74:t) from grandchild
 [3145] got data (74:t) from grandchild
 [3274] aborting pipe to mail
 [3145] closing pipe to mail
 [2490] sigchld...pid #3274 died, stat=0
 [2490] sigchld...no dead kids
 [3145] got EOF from grandchild
 log_it: (p 3145) CMD FINISH (/home/p/test4.sh )
 [3145] child process done (rc=0), exiting
 [2490] sigchld...pid #3145 died, stat=0
 [2490] sigchld...no children
 ....
 ================================


 Bye
 Nicola


 On Sun-21-Jul-2024 21:50, Christos Zoulas wrote:
 > The following reply was made to PR bin/58408; it has been noted by GNATS.
 >
 > From: Christos Zoulas <christos@zoulas.com>
 > To: gnats-bugs@netbsd.org
 > Cc: gnats-admin@netbsd.org,
 >   netbsd-bugs@netbsd.org
 > Subject: Re: bin/58408: cron ignores parameter "-n" in crontab
 > Date: Sun, 21 Jul 2024 15:45:07 -0400
 >
 >   I just tried your example and it worked as expected
 >   
 >   log_it: (christos 5384) CMD START (/u/christos/cron1)
 >   log_it: (christos 15992) CMD START (/u/christos/cron2)
 >   [4179] child continues, closing pipes
 >   [4179] child reading output from grandchild
 >   [13945] child continues, closing pipes
 >   [13945] child reading output from grandchild
 >   [7886] child continues, closing pipes
 >   [7886] child reading output from grandchild
 >   [4179] got EOF from grandchild [0]
 >   log_it: (christos 4179) CMD FINISH (/usr/bin/true)
 >   [4179] child process done (rc=3D0), exiting
 >   [20135] sigchld...pid #4179 died, stat=3D0
 >   [20135] sigchld...no dead kids
 >   [7886] got data (77:w) from grandchild
 >   [7886] aborting pipe to mail
 >   [13945] got data (77:w) from grandchild
 >   [13945] closing pipe to mail
 >   [13945] got EOF from grandchild [0]
 >   log_it: (christos 13945) CMD FINISH (/u/christos/cron2)
 >   [13945] child process done (rc=3D0), exiting
 >   [20135] sigchld...pid #13945 died, stat=3D0
 >   [20135] sigchld...no dead kids
 >   
 >   you can try running cron -x proc
 >   
 >   
 >   christos
 >   
 >   > On Jul 9, 2024, at 3:35=E2=80=AFAM, nmingotti@gmail.com wrote:
 >   >=20
 >   >> Number:         58408
 >   >> Category:       bin
 >   >> Synopsis:       cron ignores parameter "-n" in crontab
 >   >> Confidential:   no
 >   >> Severity:       non-critical
 >   >> Priority:       medium
 >   >> Responsible:    bin-bug-people
 >   >> State:          open
 >   >> Class:          sw-bug
 >   >> Submitter-Id:   net
 >   >> Arrival-Date:   Tue Jul 09 07:35:00 +0000 2024
 >   >> Originator:     Dr. Nicola Mingotti
 >   >> Release:        10.0
 >   >> Organization:
 >   > Borghi SRL
 >   >> Environment:
 >   > NetBSD pulce4 10.0 NetBSD 10.0 (GENERIC) #0: Thu Mar 28 08:33:33 UTC =
 >   2024  =
 >   mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/evbarm/compile/GENERIC =
 >   evbarm
 >   >=20
 >   >> Description:
 >   > According to man page crontab (5), if the modifier '-n' is used before =
 >   a command no mail should be sent on successful run. This is not the =
 >   case, parameter '-n' is ignored. Example below.=20
 >   >=20
 >   >=20
 >   >=20
 >   >=20
 >   >> How-To-Repeat:
 >   >=20
 >   > ---- /home/p/bin/test3.sh ----------
 >   > #!/bin/sh
 >   > echo "test3.sh -- `date` " >> /home/p/bin/test.log
 >   > echo "write something and quit. "
 >   > exit 0
 >   > ------------------------------------
 >   >=20
 >   > ---- /home/p/bin/test4.sh ----------
 >   > #!/bin/sh
 >   > echo "test4.sh -- `date` " >> /home/p/bin/test.log
 >   > echo "write something and fail"
 >   > exit 1
 >   > ------------------------------------
 >   >=20
 >   > p@pulce4 $> crontab -l=20
 >   > -----------
 >   > #
 >   > #minute hour    mday    month   wday    command
 >   > */1     *       *       *       *        -n /home/p/bin/test3.sh
 >   > */1     *       *       *       *        -n /home/p/bin/test4.sh
 >   > -----------
 >   >=20
 >   > . wait a bit
 >   > p@pulce4> mail=20
 >   > ----
 >   > N 14 root@pulce4.localdom  Tue Jul  9 08:55   3/695   "Cron <p@pulce4> =
 >   /home/p/bin/test3.sh"
 >   > N 15 root@pulce4.localdom  Tue Jul  9 08:56   3/693   "Cron <p@pulce4> =
 >   /home/p/bin/test4.sh"
 >   > N 16 root@pulce4.localdom  Tue Jul  9 08:56   3/695   "Cron <p@pulce4> =
 >   /home/p/bin/test3.sh"
 >   > N 17 root@pulce4.localdom  Tue Jul  9 08:57   3/693   "Cron <p@pulce4> =
 >   /home/p/bin/test4.sh"
 >   > N 18 root@pulce4.localdom  Tue Jul  9 08:57   3/695   "Cron <p@pulce4> =
 >   /home/p/bin/test3.sh"
 >   > N 19 root@pulce4.localdom  Tue Jul  9 08:58   3/693   "Cron <p@pulce4> =
 >   /home/p/bin/test4.sh"
 >   > N 20 root@pulce4.localdom  Tue Jul  9 08:58   3/695   "Cron <p@pulce4> =
 >   /home/p/bin/test3.sh"
 >   > N 21 root@pulce4.localdom  Tue Jul  9 08:59   3/693   "Cron <p@pulce4> =
 >   /home/p/bin/test4.sh"
 >   > N 22 root@pulce4.localdom  Tue Jul  9 08:59   3/695   "Cron <p@pulce4> =
 >   /home/p/bin/test3.sh"
 >   > ----
 >   >=20
 >   >=20
 >   >=20
 >   >=20
 >   >=20
 >   >=20
 >   >> Fix:
 >   >=20
 >   

From: RVP <rvp@SDF.ORG>
To: gnats-bugs@netbsd.org
Cc: "Dr. Nicola Mingotti" <nmingotti@gmail.com>
Subject: Re: bin/58408: cron ignores parameter "-n" in crontab
Date: Wed, 24 Jul 2024 09:43:37 +0000 (UTC)

 On Mon, 22 Jul 2024, Dr. Nicola Mingotti wrote:

 > To ease the reproduction of the problem I re-do it all in a VM.
 >

 Can you try the patch below?

 --- START ---
 diff -urN cron.orig/dist/do_command.c cron/dist/do_command.c
 --- cron.orig/dist/do_command.c	2020-04-18 19:32:19.000000000 +0000
 +++ cron/dist/do_command.c	2024-07-24 08:23:44.648613785 +0000
 @@ -254,12 +254,16 @@
   				log_it("CRON", getpid(), "error",
   				    "no job pid");
   			else {
 -				while (waitpid(jobpid, &jstatus, WNOHANG) == -1)
 +				int rc;
 +				while ((rc = waitpid(jobpid, &jstatus, WNOHANG)) <= 0) {
 +					if (rc == 0)
 +						continue;	/* no stat. change */
   					if (errno != EINTR) {
   						log_it("CRON", getpid(),
   						    "error", "no job pid");
   						break;
   					}
 +				}
   			}
   			/* If everything went well, and -n was set, _and_ we
   			 * have mail, we won't be mailing... so shoot the
 diff -urN cron.orig/dist/popen.c cron/dist/popen.c
 --- cron.orig/dist/popen.c	2018-06-14 22:04:28.000000000 +0000
 +++ cron/dist/popen.c	2024-07-24 08:43:41.156198413 +0000
 @@ -90,7 +90,7 @@
   			break;
   	argv[MAX_ARGV-1] = NULL;

 -	switch (pid = vfork()) {
 +	switch (pid = fork()) {
   	case -1:			/* error */
   		(void)close(pdes[0]);
   		(void)close(pdes[1]);
 --- END ---

 In addition to mailing on success (with -n), cron doesn't seem to
 kill the mailer process properly either. (I didn't realize 'til
 now how cron worked for `-n' in crontab: Without the `-n', cron
 reads the output of the job, then runs a mailer process and writes
 the output to it. If you add `-n' it does _the same_ thing, then
 instead of closing the pipe on EOF, _kills_ the mailer process.
 This aborts the sending of the collected mail data--a _very_ odd
 way to do things...)

 I'll look at this more fully this weekend maybe.

 -RVP

From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/58408: cron ignores parameter "-n" in crontab
Date: Wed, 24 Jul 2024 18:05:00 +0700

     Date:        Wed, 24 Jul 2024 09:45:01 +0000 (UTC)
     From:        RVP <rvp@SDF.ORG>
     Message-ID:  <20240724094501.EADC31A923C@mollari.NetBSD.org>


   |  -				while (waitpid(jobpid, &jstatus, WNOHANG) == -1)
   |  +				int rc;
   |  +				while ((rc = waitpid(jobpid, &jstatus, WNOHANG)) <= 0) {
   |  +					if (rc == 0)
   |  +						continue;	/* no stat. change */


 That's not a good idea, that's just turning the nonsense code into
 a painful busy loop - it might help, but is going to use lots of CPU
 while doing it.   The real question here is just what WNOHANG is
 doing there?   That looks like it might have been added as a generic
 (always set that flag) rather than for anything useful.  Remove that
 and there won't be a 0 return possible, so the rest of the change would
 be a no-op.

   |  -	switch (pid = vfork()) {
   |  +	switch (pid = fork()) {

 If that one makes a difference, something is very broken indeed.

   |  In addition to mailing on success (with -n), cron doesn't seem to
   |  kill the mailer process properly either. (I didn't realize 'til
   |  now how cron worked for `-n' in crontab: Without the `-n', cron
   |  reads the output of the job, then runs a mailer process and writes
   |  the output to it. If you add `-n' it does _the same_ thing, then
   |  instead of closing the pipe on EOF, _kills_ the mailer process.
   |  This aborts the sending of the collected mail data--a _very_ odd
   |  way to do things...)

 That's attempting to avoid using either unbounded (possibly) memory,
 or needing to save the output in a temp file.   Whether the mail needs
 to be sent isn't known until the process completes, and all its output
 has been sent to cron - it needs to be saved somewhere.  So cron is just
 assuming that the output is wanted (if MAILTO is set) so opening a
 connection to the mailer, and sending the process' output as it appears.

 The pipe buffers and the mailer process manage the storage for that
 message.

 When it later discovers that the mail isn't wanted after all, it needs
 to do something to avoid it being sent.

 kre


From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/58408: cron ignores parameter "-n" in crontab
Date: Wed, 24 Jul 2024 18:44:42 +0700

 I said:

     When it later discovers that the mail isn't wanted after all, it needs
     to do something to avoid it being sent.

 That might easily be the problem, if we're talking about a regular
 user crontab, rather than a root one - the mailer is probably setuid,
 and the kill attempt might simply be being rejected.

 kre

From: RVP <rvp@SDF.ORG>
To: gnats-bugs@netbsd.org
Cc: Robert Elz <kre@munnari.OZ.AU>
Subject: Re: bin/58408: cron ignores parameter "-n" in crontab
Date: Wed, 24 Jul 2024 13:30:46 +0000 (UTC)

 On Wed, 24 Jul 2024, Robert Elz wrote:

 >   |  -				while (waitpid(jobpid, &jstatus, WNOHANG) == -1)
 >   |  +				int rc;
 >   |  +				while ((rc = waitpid(jobpid, &jstatus, WNOHANG)) <= 0) {
 >   |  +					if (rc == 0)
 >   |  +						continue;	/* no stat. change */
 >
 >
 > That's not a good idea, that's just turning the nonsense code into
 > a painful busy loop - it might help, but is going to use lots of CPU
 > while doing it.   The real question here is just what WNOHANG is
 > doing there?

 Yup (meant to make that change in the final cut).

 >   |  -	switch (pid = vfork()) {
 >   |  +	switch (pid = fork()) {
 >
 > If that one makes a difference, something is very broken indeed.
 >

 I've never trusted vfork(), and PAM functions are being called
 afterwards (and God knows what _they_ do internally)...  And,
 yeah the mailer processes were being killed properly after that
 change.

 > That's attempting to avoid using either unbounded (possibly) memory,
 > or needing to save the output in a temp file.   Whether the mail needs
 > to be sent isn't known until the process completes, and all its output
 > has been sent to cron - it needs to be saved somewhere.  So cron is just
 > assuming that the output is wanted (if MAILTO is set) so opening a
 > connection to the mailer, and sending the process' output as it appears.
 >
 > The pipe buffers and the mailer process manage the storage for that
 > message.
 >
 > When it later discovers that the mail isn't wanted after all, it needs
 > to do something to avoid it being sent.
 >

 Yeah I got that the first time around ;) -- just a bit surprised
 is all. I had expected cron to stash the output in a temp file (and
 only if the message exceeded some limit--1MB, say).


 > I said:
 >
 >     When it later discovers that the mail isn't wanted after all, it needs
 >     to do something to avoid it being sent.
 >
 > That might easily be the problem, if we're talking about a regular
 > user crontab, rather than a root one - the mailer is probably setuid,
 > and the kill attempt might simply be being rejected.
 >

 But, that should work on all Unixes, right? (Since the real-uids
 would be the same.) Otherwise, xinit couldn't kill the X server
 when the WM (or whatever) exits.

 No, something else is going on because: a) Postfix progs. aren't
 installed set-uid on NetBSD and b) not _every_ successful job run
 is mailed with `-n'. Only some of them are.

 I think the stuff in popen.c should be simplified: since cron_popen()
 is only called from one place, it can just return the mailer PID
 too instead of trying to emulate popen(3). Then, you can just kill
 the mailer directly w/o a cron_abort() at all. Gotta see what the
 newer Vixie cron on Github's doing...

 Thanks,

 -RVP

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2024 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.