On 9/26/26 19:28, Roman Bogorodskiy wrote:
> In virBhyveProcessStartImpl() we call virBhyveProcessStop(), and
> even though we use ignore_value() it overrides the original error.
> So preserve last error in the cleanup routine and restore it before
> returning.
> 
> While here, relax error handling for devicemap removal, it is not
> critical enough to raise an error.
> 
> Additionally, apply a similar pattern to virBhyveProcessStart()
> so errors running hooks do not override domain startup errors.
> 
> Signed-off-by: Roman Bogorodskiy <[email protected]>
> ---
>  src/bhyve/bhyve_process.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c
> index 65cf61c578..155037e99a 100644
> --- a/src/bhyve/bhyve_process.c
> +++ b/src/bhyve/bhyve_process.c
> @@ -302,6 +302,7 @@ virBhyveProcessStartImpl(struct _bhyveConn *driver,
>      VIR_AUTOCLOSE logfd = -1;
>      g_autoptr(virCommand) cmd = NULL;
>      g_autoptr(virCommand) load_cmd = NULL;
> +    virErrorPtr save_err = NULL;
>      bhyveDomainObjPrivate *priv = vm->privateData;
>      g_autofree char *domain_vmm_path = NULL;
>      virTimeBackOffVar timebackoff;
> @@ -430,16 +431,21 @@ virBhyveProcessStartImpl(struct _bhyveConn *driver,
>      ret = 0;
>  
>   cleanup:
> +    if (ret < 0)
> +        virErrorPreserveLast(&save_err);
> +

This check is not necessary and virErrorPreserveLast() can be called
unconditionally. If there no error reported then the function is NOP
(apart from setting save_err to NULL).

>      if (devicemap != NULL) {
>          rc = unlink(devmap_file);
>          if (rc < 0 && errno != ENOENT)
> -            virReportSystemError(errno, _("cannot unlink file '%1$s'"),
> -                                 devmap_file);
> +            VIR_WARN("cannot unlink file '%s': %s",
> +                     devmap_file, g_strerror(errno));
>      }
>  
> -    if (ret < 0)
> +    if (ret < 0) {
>          ignore_value(virBhyveProcessStop(driver, vm,
>                                           VIR_DOMAIN_SHUTOFF_FAILED, true));
> +        virErrorRestore(&save_err);
> +    }
>  

If save_err is NULL (i.e. no error was preserved when entering the
cleanup label, then this is NOP. Thus, it too does not need the ret < 0
check.

Additionally, virBhyveProcessStop(), well virBhyveProcessStopImpl() can
be made so that it does not overwrite an error. I mean, the first thing
it would call is virErrorPreserveLast() and the very last thing it would
call is virErrorRestore(). This is because virBhyveProcessStop() is also
called from other (cleanup) places.

>      return ret;
>  }
> @@ -593,6 +599,8 @@ virBhyveProcessStart(bhyveConn *driver,
>                       virDomainRunningReason reason,
>                       unsigned int flags)
>  {
> +    virErrorPtr save_err = NULL;
> +
>      if (virDomainObjSetDefTransient(driver->xmlopt, vm, NULL) < 0)
>          return -1;
>  
> @@ -612,9 +620,11 @@ virBhyveProcessStart(bhyveConn *driver,
>      return virBhyveProcessStartImpl(driver, vm, reason);
>  
>   cleanup:
> +    virErrorPreserveLast(&save_err);
>      bhyveProcessStopHook(driver, vm, VIR_HOOK_BHYVE_OP_STOPPED);
>      bhyveProcessStopHook(driver, vm, VIR_HOOK_BHYVE_OP_RELEASE);
>      virDomainObjRemoveTransientDef(vm);
> +    virErrorRestore(&save_err);
>  
>      return -1;
>  }

ACK to this hunk.

Michal

Reply via email to