[CRIU] [PATCH 1/2] libcriu: Add ability to request for notifications from service

Andrew Vagin avagin at parallels.com
Thu Jun 26 01:05:13 PDT 2014


On Wed, Jun 25, 2014 at 07:36:14PM +0400, Pavel Emelyanov wrote:
> This is achieved by supplying the callback. Every time a notification
> arrives the callback is called. Return value of 0 means continue,
> any other value aborst the request and the value is reported back
> to the caller (from criu_dump/criu_restore calls).
> 
> Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
> ---
>  lib/criu.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++------
>  lib/criu.h |  1 +
>  2 files changed, 52 insertions(+), 6 deletions(-)
> 
> diff --git a/lib/criu.c b/lib/criu.c
> index 4b1be8a..a827671 100644
> --- a/lib/criu.c
> +++ b/lib/criu.c
> @@ -19,6 +19,7 @@ const char *criu_lib_version = CRIU_VERSION;
>  
>  static char *service_address = CR_DEFAULT_SERVICE_ADDRESS;
>  static CriuOpts *opts;
> +static int (*notify)(char *action);
>  static int saved_errno;
>  
>  void criu_set_service_address(char *path)
> @@ -31,8 +32,10 @@ void criu_set_service_address(char *path)
>  
>  int criu_init_opts(void)
>  {
> -	if (opts)
> +	if (opts) {
> +		notify = NULL;
>  		criu_opts__free_unpacked(opts, NULL);
> +	}
>  
>  	opts = malloc(sizeof(CriuOpts));
>  	if (opts == NULL) {
> @@ -44,6 +47,13 @@ int criu_init_opts(void)
>  	return 0;
>  }
>  
> +void criu_set_notify(int (*cb)(char *action))

I wourld prefer to get pid in callbacks.

> +{
> +	notify = cb;
> +	opts->has_notify_scripts = true;
> +	opts->notify_scripts = true;
> +}
> +
>  void criu_set_pid(int pid)
>  {
>  	opts->has_pid	= true;
> @@ -192,6 +202,29 @@ err:
>  	return -1;
>  }
>  
> +static int send_notify_ack(int socket_fd, int ret)
> +{
> +	int send_ret;
> +	CriuReq req = CRIU_REQ__INIT;
> +
> +	req.type = CRIU_REQ_TYPE__NOTIFY;
> +	req.has_notify_success = true;
> +	req.notify_success = (ret == 0);
> +
> +	send_ret = send_req(socket_fd, &req);
> +
> +	/*
> +	 * If we're failing the notification then report
> +	 * back the original error code (and it will be
> +	 * propagated back to user).
> +	 *
> +	 * If the notification was OK, then report the
> +	 * result of acking it.
> +	 */
> +
> +	return ret ? : send_ret;
> +}
> +
>  static int criu_connect(void)
>  {
>  	int fd, ret;
> @@ -228,29 +261,41 @@ static int send_req_and_recv_resp_sk(int fd, CriuReq *req, CriuResp **resp)
>  	int ret = 0;
>  
>  	if (send_req(fd, req) < 0) {
> -		ret = ECOMM;
> +		ret = -ECOMM;
>  		goto exit;
>  	}
>  
> +again:
>  	*resp = recv_resp(fd);
>  	if (!*resp) {
>  		perror("Can't receive response");
> -		ret = ECOMM;
> +		ret = -ECOMM;
>  		goto exit;
>  	}
>  
> +	if ((*resp)->type == CRIU_REQ_TYPE__NOTIFY) {
> +		if (notify)
> +			ret = notify((*resp)->notify->script);
> +
> +		ret = send_notify_ack(fd, ret);
> +		if (!ret)
> +			goto again;
> +		else
> +			goto exit;
> +	}
> +
>  	if ((*resp)->type != req->type) {
>  		if ((*resp)->type == CRIU_REQ_TYPE__EMPTY &&
>  		    (*resp)->success == false)
> -			ret = EINVAL;
> +			ret = -EINVAL;
>  		else {
>  			perror("Unexpected response type");
> -			ret = EBADMSG;
> +			ret = -EBADMSG;
>  		}
>  	}
>  
>  exit:
> -	return -ret;
> +	return ret;
>  }
>  
>  static int send_req_and_recv_resp(CriuReq *req, CriuResp **resp)
> diff --git a/lib/criu.h b/lib/criu.h
> index 7c33897..c994fd6 100644
> --- a/lib/criu.h
> +++ b/lib/criu.h
> @@ -42,6 +42,7 @@ void criu_set_log_level(int log_level);
>  void criu_set_log_file(char *log_file);
>  void criu_set_cpu_cap(unsigned int cap);
>  int criu_set_exec_cmd(int argc, char *argv[]);
> +void criu_set_notify(int (*cb)(char *action));
>  
>  /* Here is a table of return values and errno's of functions
>   * from the list down below.
> -- 
> 1.8.4.2
> 
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list