[virt-tools-list] [vhostmd] add SIGPIPE handler and do_reconnect function

Daniel P. Berrangé berrange at redhat.com
Thu Jun 14 10:24:25 UTC 2018


On Thu, Jun 14, 2018 at 12:16:21PM +0200, Michael Trapp wrote:
> vhostmd has no signal handler for SIGPIPE and a restart of libvirtd results in a
> stopped vhostmd. The root cause seems to be a UDS socket between vhostmd and
> libvirtd which is closed by a libvirtd restart. In addition to the signal handler
> the connection to libvirtd has to be opened again otherwise vhostmd can't read
> any data from libvirtd and doesn't update the metrics.

I don't know the vhostmd code, but the recommended approach to dealing wiht
lost connections is to use virConnectRegisterCloseCallback() to get a callback
notification when connection is lost. This requires that you have an event loop
impl provided to libvirt first though.

> 
> ---
>  vhostmd/vhostmd.c   |  2 ++
>  vhostmd/virt-util.c | 45 +++++++++++++++++++++++++++++++++++++++------
>  2 files changed, 41 insertions(+), 6 deletions(-)
> 
> diff --git a/vhostmd/vhostmd.c b/vhostmd/vhostmd.c
> index 7f04705..4cf4630 100644
> --- a/vhostmd/vhostmd.c
> +++ b/vhostmd/vhostmd.c
> @@ -117,6 +117,7 @@ static void sig_handler(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED,
>        case SIGQUIT:
>           down = 1;
>           break;
> +      case SIGPIPE:
>        default:
>           break;
>     }
> @@ -1053,6 +1054,7 @@ int main(int argc, char *argv[])
>     sigaction(SIGINT, &sig_action, NULL);
>     sigaction(SIGQUIT, &sig_action, NULL);
>     sigaction(SIGTERM, &sig_action, NULL);
> +   sigaction(SIGPIPE, &sig_action, NULL);
>  
>     xmlInitParser();
>  
> diff --git a/vhostmd/virt-util.c b/vhostmd/virt-util.c
> index 1c31305..c76e224 100644
> --- a/vhostmd/virt-util.c
> +++ b/vhostmd/virt-util.c
> @@ -44,17 +44,47 @@ do_connect (void)
>      return 0;
>  }
>  
> +static int
> +do_reconnect(void)
> +{
> +    if (conn != NULL)
> +	virConnectClose (conn);
> +
> +    conn = virConnectOpenReadOnly (libvirt_uri);
> +    if (conn == NULL) {
> +	vu_log (VHOSTMD_ERR, "Unable to open libvirt connection to %s",
> +		libvirt_uri ? libvirt_uri : "default hypervisor");
> +	return -1;
> +    }
> +    return 0;
> +}

If you're going to blindly reconnect on every possible error reported
by libvirt, at least put in a check to see if the connection is genuinely
broken or not. eg

   if (virConnectIsAlive())
       return -1;

so that the error is still treated as fatal if this is not a connection
lost scenario.


> +
>  int vu_num_vms(void)
>  {
> +   int rc;
> +
>     if (do_connect () == -1) return -1;
> +
> +   rc = virConnectNumOfDomains(conn);
> +   if (rc < 0) {
> +	if (do_reconnect()) return -1;
>     return virConnectNumOfDomains(conn);
> +   }
> +   return rc;
>  }
>  
>  int vu_get_vms(int *ids, int max_ids)
>  {
> -   if (do_connect () == -1) return -1;
> +   int rc;
> +
> +   if (do_connect() == -1) return -1;
>     
> -   return (virConnectListDomains(conn, ids, max_ids));
> +   rc = virConnectListDomains(conn, ids, max_ids);
> +   if (rc < 0) {
> +      if (do_reconnect()) return -1;
> +      return virConnectListDomains(conn, ids, max_ids);
> +   }
> +   return rc;
>  }
>  
>  vu_vm *vu_get_vm(int id)
> @@ -74,8 +104,11 @@ vu_vm *vu_get_vm(int id)
>     
>     dom = virDomainLookupByID(conn, id);
>     if (dom == NULL) {
> -       vu_log(VHOSTMD_ERR, "Failed to lookup domain for id %d", id);
> -       goto error;
> +      if (do_reconnect() ||
> +          (dom = virDomainLookupByID(conn, id)) == NULL) {
> +         vu_log(VHOSTMD_ERR, "Failed to lookup domain for id %d", id);
> +         goto error;
> +      }
>     }
>  
>     uuid[0] = '\0';
> @@ -98,8 +131,8 @@ vu_vm *vu_get_vm(int id)
>  void vu_vm_free(vu_vm *vm)
>  {
>     if (vm) {
> -      free(vm->name);
> -      free(vm->uuid);
> +      if (vm->name) free(vm->name);
> +      if (vm->uuid) free(vm->uuid);
>        free(vm);
>     }
>  }
> -- 
> 2.12.3
> 
> _______________________________________________
> virt-tools-list mailing list
> virt-tools-list at redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the virt-tools-list mailing list