[pve-devel] [PATCH cluster] config_change: correctly propagate $@ with nested locks

Thomas Lamprecht t.lamprecht at proxmox.com
Tue Jul 16 15:16:35 CEST 2019


On 7/16/19 2:18 PM, Fabian Grünbichler wrote:
> PVE::Cluster::cfs_lock_file sets $@ and returns undef for all errors,
> including when $code dies. PVE::Tools::lock_file runs $code inside an
> eval as well, so just setting $@ is not enough when nesting these two
> types of locks.
> 
> re-die with the inner error to actually propagate error messages and
> fail instead of proceeding. this triggered (probably among other cases)
> when attempting to join an existing cluster without specifying all
> needed links.
> 
> Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
> ---
>  data/PVE/API2/ClusterConfig.pm | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/data/PVE/API2/ClusterConfig.pm b/data/PVE/API2/ClusterConfig.pm
> index 6d23056..767bda9 100644
> --- a/data/PVE/API2/ClusterConfig.pm
> +++ b/data/PVE/API2/ClusterConfig.pm
> @@ -172,7 +172,10 @@ my $config_change_lock = sub {
>  	PVE::Cluster::cfs_update(1);
>  	my $members = PVE::Cluster::get_members();
>  	if (scalar(keys %$members) > 1) {
> -	    return PVE::Cluster::cfs_lock_file('corosync.conf', 10, $code);
> +	    my $res = PVE::Cluster::cfs_lock_file('corosync.conf', 10, $code);
> +	    # cfs_lock_file only sets $@
> +	    # lock_file does not propagate $@ unless we die here
> +	    die $@ if !defined($res) && defined($@);

Do you think the !defined($res) is important here? For a perl "exception"
the $@ is normally enough, and we could just do a
$@ = undef;

before the cfs_lock_file and omit the defined-ness check on $res. Would
guard a bit more against changing behavior (al thought such a change should
not happen without close looks at the users).

Also, you now do not return $res anymore, any reason for that? It probably
even works, as in the normal case the  "my $res = .." is the last executed
statement and thus gets indirectly returned (perldoc 'perlsub'), but
1. the docs are a bit unclear how the last statement is defined
   (is it really the last executed one even for post-if)
2. Even if 1. would be defined clearly, I do not want such magic behaviour
   especially for locking helpers ^^

>  	} else {
>  	    return $code->();
>  	}
> 






More information about the pve-devel mailing list