Commit 4562c3df authored by Pavel Emelyanov's avatar Pavel Emelyanov

libcriu: Add ability to request for notifications from service

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 714dfdb7
...@@ -19,6 +19,7 @@ const char *criu_lib_version = CRIU_VERSION; ...@@ -19,6 +19,7 @@ const char *criu_lib_version = CRIU_VERSION;
static char *service_address = CR_DEFAULT_SERVICE_ADDRESS; static char *service_address = CR_DEFAULT_SERVICE_ADDRESS;
static CriuOpts *opts; static CriuOpts *opts;
static int (*notify)(char *action);
static int saved_errno; static int saved_errno;
void criu_set_service_address(char *path) void criu_set_service_address(char *path)
...@@ -31,8 +32,10 @@ void criu_set_service_address(char *path) ...@@ -31,8 +32,10 @@ void criu_set_service_address(char *path)
int criu_init_opts(void) int criu_init_opts(void)
{ {
if (opts) if (opts) {
notify = NULL;
criu_opts__free_unpacked(opts, NULL); criu_opts__free_unpacked(opts, NULL);
}
opts = malloc(sizeof(CriuOpts)); opts = malloc(sizeof(CriuOpts));
if (opts == NULL) { if (opts == NULL) {
...@@ -44,6 +47,13 @@ int criu_init_opts(void) ...@@ -44,6 +47,13 @@ int criu_init_opts(void)
return 0; return 0;
} }
void criu_set_notify_cb(int (*cb)(char *action))
{
notify = cb;
opts->has_notify_scripts = true;
opts->notify_scripts = true;
}
void criu_set_pid(int pid) void criu_set_pid(int pid)
{ {
opts->has_pid = true; opts->has_pid = true;
...@@ -291,6 +301,29 @@ err: ...@@ -291,6 +301,29 @@ err:
return -1; 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) static int criu_connect(void)
{ {
int fd, ret; int fd, ret;
...@@ -327,29 +360,41 @@ static int send_req_and_recv_resp_sk(int fd, CriuReq *req, CriuResp **resp) ...@@ -327,29 +360,41 @@ static int send_req_and_recv_resp_sk(int fd, CriuReq *req, CriuResp **resp)
int ret = 0; int ret = 0;
if (send_req(fd, req) < 0) { if (send_req(fd, req) < 0) {
ret = ECOMM; ret = -ECOMM;
goto exit; goto exit;
} }
again:
*resp = recv_resp(fd); *resp = recv_resp(fd);
if (!*resp) { if (!*resp) {
perror("Can't receive response"); perror("Can't receive response");
ret = ECOMM; ret = -ECOMM;
goto exit; 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 != req->type) {
if ((*resp)->type == CRIU_REQ_TYPE__EMPTY && if ((*resp)->type == CRIU_REQ_TYPE__EMPTY &&
(*resp)->success == false) (*resp)->success == false)
ret = EINVAL; ret = -EINVAL;
else { else {
perror("Unexpected response type"); perror("Unexpected response type");
ret = EBADMSG; ret = -EBADMSG;
} }
} }
exit: exit:
return -ret; return ret;
} }
static int send_req_and_recv_resp(CriuReq *req, CriuResp **resp) static int send_req_and_recv_resp(CriuReq *req, CriuResp **resp)
......
...@@ -50,6 +50,7 @@ void criu_set_root(char *root); ...@@ -50,6 +50,7 @@ void criu_set_root(char *root);
int criu_set_exec_cmd(int argc, char *argv[]); int criu_set_exec_cmd(int argc, char *argv[]);
int criu_add_ext_mount(char *key, char *val); int criu_add_ext_mount(char *key, char *val);
int criu_add_veth_pair(char *in, char *out); int criu_add_veth_pair(char *in, char *out);
void criu_set_notify_cb(int (*cb)(char *action));
/* Here is a table of return values and errno's of functions /* Here is a table of return values and errno's of functions
* from the list down below. * from the list down below.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment