This was already implemented in PVE::LXC::lock_aquire() and
lock_release(). Enabling refcounting in the general
PVE::Tools::lock_file() and lock_file_full() methods allows
us to use one code base for flocking.
Furthermore, we could get rid of various xx_no_lock methods
that were required because the old non-refcounting version
did not support nested flocks (the inner most flock would
close the file handle and thus release the flock).
If we can't acquire the lock in lock_file_full and get interrupted
by a signal inqeual to EINTR (e.g. SIGTERM), output also it's name
in the error message to allow better debugging.
Also fix a typo.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Allow to return the exit code of the executed command.
And as we do not reach the return of the exit code if it was not 0,
a noerr parameter is also needed so we can suppress the 'command
failed' die in case of an exit code unequal to 0.
This is required as some programs return another value than 0 when
they succeed, For example `systemctl list-jobs` returns a value
>= 0 on a successful execution, normally 1.
Without this patch a run_command call to `systemctl list-jobs` gets
marked as failed although it was successful.
This does not break current behaviour in any way as setting the
noerr parameter is required to return something other than 0 or
undef, which are equal in a boolean comparison.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Most syscall wrappers in perl return 1 on success and our
current use of Tools::unshare isn't using the return value
(yet), so let's fix this while we can.
Also it seems to make sense to use prototyping on syscalls
to add some compile-time argument checking.
In an alternation /a|b|c/ the first match matches, so while
'1.1.1.121' matches /^$IPV4RE$/ (note the ^ and $ anchors),
parsing a line like /nameserver ($IPV4RE)/ would only
extract '1.1.1.12', ignoring the last '1' due to the /[1-9]/
alternative matching before the /1[0-9]/ one.
Passing an array of arrays to run_command will cause each
array to be treated like a command piped to the following
command. Each argument is shell-quoted unless its passed by
reference.
The following situations could lead to the 'unknown error':
1) As commented, when the alarm triggered after the first
signal handler was installed and before the new alarm was
installed. In this case the $signalcount was increased,
and worse: the original signal handler was never called.
2) When $code died, since the call itself wasn't in an eval
block, we'd leave the eval block containing the inner alarm
signal handler. Then there's a time window from leaving the
signal block (and with that restoring the first installed
only-counting signal-handler) and reaching the code to
restore the previous alarm where the counting alarm handler
could get triggered by our own alarm set before running
$code. In this case at least the the old alarm would be
restored, but we'd still trigger the 'unknown error'.
The new code starts off by suspending the original alarm
before installing any signal handler, then installing the
timeout handler inside the first eval block. The $code is
then run inside another eval block to make sure we reach the
alarm(0) statement before restoring the old signal handler
and alarm timeout.
Added a generic function to split a host+port string to the
host and port part supporting the two most common ipv6
notations beside domains and ipv4: with brackets for the
address or a dot as port separator.
perl's IO::Socket::IP passes AI_ADDRCONFIG if no GetAddrInfoFlags are passed,
which is often useful but also causes it to error when explicitly trying to
bind to 127.0.0.1 when there are no _other_ IPv4 addresses present.
Instead of assuming a local address of 0.0.0.0, the next_*_port family
of functions now takes an optional packet family argument (AF_INET/AF_INET6),
used for ipv6 support.