Jira (PUP-11897) 100% usage of a CPU core when an exec command sends EOF

5 views
Skip to first unread message

Corey Hickey (Jira)

unread,
Jun 22, 2023, 5:57:02 PM6/22/23
to puppe...@googlegroups.com
Corey Hickey created an issue
 
Puppet / Bug PUP-11897
100% usage of a CPU core when an exec command sends EOF
Issue Type: Bug Bug
Affects Versions: PUP 8.0.1
Assignee: Unassigned
Components: Types and Providers
Created: 2023/06/22 2:56 PM
Priority: Normal Normal
Reporter: Corey Hickey

Puppet Version:{}

Seen in 7.14.0, 7.23.0, and current git 61234be0e4d6.

The code originates in d4c1582ed0c2a3e.

Puppet Server Version:

N/A; reproducible via puppet apply.
**

OS Name/Version:{}

Seen in AlmaLinux 8.7 and Debian Unstable.

This is probably POSIX-specific; the affected code runs under if Puppet.features.posix?

Describe your issue in as much detail as possible…

When puppet applies an exec resource, and the command run by that exec returns an EOF on the pipe handling stdout and stdterr, puppet ignores the EOF. This results in puppet rapidly looping over these system calls:

1359029 wait4(1359100, 0x7ffce8537cb8, WNOHANG, NULL) = 0
1359029 getpid()                        = 1359029
1359029 pselect6(7, [6], [], [], {tv_sec=0, tv_nsec=100000000}, NULL) = 1 (in [6], left {tv_sec=0, tv_nsec=99998955})
1359029 fcntl(6, F_GETFL)               = 0x800 (flags O_RDONLY|O_NONBLOCK)
1359029 read(6, "", 4096)               = 0

There is no blocking in the loop, so puppet consumes 100% of a CPU core until the child process exits.

Describe steps to reproduce…

Use a manifest like /tmp/test.pp

$c1 = [
    '/bin/bash', '-c',
    'exec /bin/sleep 10 >/dev/null 2>&1',
]
exec { 'c1':
    command => $c1,
}

Then run:

time puppet apply /tmp/test.pp

Desired Behavior:

The timing output should be like:

real    0m13.554s
user    0m2.857s
sys    0m0.516s

Real time is expected to be high, due to the 10 second sleep, but user time should be relatively low.

Actual Behavior:

The timing output is:

real    0m13.486s
user    0m11.048s
sys    0m2.265s

Note the high user time; this is because puppet is busy-looping while the child sleeps for 10 seconds.

I will submit a patch for this.

Add Comment Add Comment
 
This message was sent by Atlassian Jira (v8.20.21#820021-sha1:38274c8)
Atlassian logo

Corey Hickey (Jira)

unread,
Jun 22, 2023, 6:00:03 PM6/22/23
to puppe...@googlegroups.com
Corey Hickey commented on Bug PUP-11897
 
Re: 100% usage of a CPU core when an exec command sends EOF

There are different ways to construct a command which will return an EOF. Here are several more examples:

$c2 = [
    '/bin/bash', '-c',
    'exec >/dev/null 2>&1; sleep 10',
]
exec { 'c2':
    command => $c2,
}
 
$c3 = [
    '/usr/bin/perl', '-e',
    'close(STDOUT); close(STDERR); sleep 10'
]
exec { 'c3':
    command => $c3,
}
 
$c4 = 'exec /bin/sleep 10 >/dev/null 2>&1'
exec { 'c4':
    command  => $c4,
    provider => 'shell',
}

Corey Hickey (Jira)

unread,
Jun 22, 2023, 6:10:02 PM6/22/23
to puppe...@googlegroups.com

Corey Hickey (Jira)

unread,
Jun 22, 2023, 6:39:02 PM6/22/23
to puppe...@googlegroups.com
Corey Hickey updated an issue
 
Change By: Corey Hickey
{ * } Puppet Version: { * }{*}{*}

Seen in 7.14.0, 7.23.0, and current git 61234be0e4d6.

The code originates in d4c1582ed0c2a3e.

*Puppet Server Version:*

N/A; reproducible via {{{}puppet apply{}}}.
**

{
* } OS Name/Version: { * }{*}{*}

Seen in AlmaLinux 8.7 and Debian Unstable.

This is probably POSIX-specific; the affected code runs under {{if Puppet.features.posix?}}

*Describe your issue in as much detail as possible…*


When puppet applies an {{exec}} resource, and the command run by that exec returns an EOF on the pipe handling stdout and stdterr, puppet ignores the EOF. This results in puppet rapidly looping over these system calls:
{code:java}
1359029 wait4(1359100, 0x7ffce8537cb8, WNOHANG, NULL) = 0
1359029 getpid()                        = 1359029
1359029 pselect6(7, [6], [], [], {tv_sec=0, tv_nsec=100000000}, NULL) = 1 (in [6], left {tv_sec=0, tv_nsec=99998955})
1359029 fcntl(6, F_GETFL)               = 0x800 (flags O_RDONLY|O_NONBLOCK)
1359029 read(6, "", 4096)               = 0
{code}

There is no blocking in the loop, so puppet consumes 100% of a CPU core until the child process exits.

*Describe steps to reproduce…*


Use a manifest like {{/tmp/test.pp}}
{code:java}
$c1 = [
    '/bin/bash', '-c',

    'exec /bin/sleep 10 >/dev/null 2>&1',
]
exec { 'c1':
    command => $c1,
}
{code}
Then run:
{code:java}

time puppet apply /tmp/test.pp{code}
*Desired Behavior:*


The timing output should be like:
{code:java}
real    0m13.554s
user    0m2.857s
sys    0m0.516s
{code}

Real time is expected to be high, due to the 10 second sleep, but user time should be relatively low.

*Actual Behavior:*

The timing output is:
{code:java}

real    0m13.486s
user    0m11.048s
sys    0m2.265s
{code}

Note the high user time; this is because puppet is busy-looping while the child sleeps for 10 seconds.

I will submit a patch for this.
Reply all
Reply to author
Forward
0 new messages