int cr_service_work(int sk) { int ret = -1; CriuReq *msg = 0; more: if (recv_criu_msg(sk, &msg) == -1) { pr_perror("Can't recv request"); goto err; } if (chk_keepopen_req(msg)) goto err; switch (msg->type) { case CRIU_REQ_TYPE__DUMP: ret = dump_using_req(sk, msg->opts); break; case CRIU_REQ_TYPE__RESTORE: ret = restore_using_req(sk, msg->opts); break; case CRIU_REQ_TYPE__CHECK: ret = check(sk); break; case CRIU_REQ_TYPE__PRE_DUMP: ret = pre_dump_loop(sk, msg); break; case CRIU_REQ_TYPE__PAGE_SERVER: ret = start_page_server_req(sk, msg->opts); break; case CRIU_REQ_TYPE__CPUINFO_DUMP: case CRIU_REQ_TYPE__CPUINFO_CHECK: ret = handle_cpuinfo(sk, msg); break; case CRIU_REQ_TYPE__FEATURE_CHECK: ret = handle_feature_check(sk, msg); break; default: send_criu_err(sk, "Invalid req"); break; } if (!ret && msg->keep_open) { criu_req__free_unpacked(msg, NULL); ret = -1; goto more; } err: return ret; }
int send_criu_rpc_script(enum script_actions act, char *name, int fd) { int ret; CriuResp msg = CRIU_RESP__INIT; CriuReq *req; CriuNotify cn = CRIU_NOTIFY__INIT; msg.type = CRIU_REQ_TYPE__NOTIFY; msg.success = true; msg.notify = &cn; cn.script = name; switch (act) { case ACT_SETUP_NS: case ACT_POST_RESTORE: /* * FIXME pid is required only once on * restore. Need some more sane way of * checking this. */ cn.has_pid = true; cn.pid = root_item->pid.real; break; default: break; } ret = send_criu_msg(fd, &msg); if (ret < 0) return ret; ret = recv_criu_msg(fd, &req); if (ret < 0) return ret; if (req->type != CRIU_REQ_TYPE__NOTIFY || !req->notify_success) { pr_err("RPC client reported script error\n"); return -1; } criu_req__free_unpacked(req, NULL); return 0; }
int send_criu_rpc_script(char *script, int fd) { int ret; CriuResp msg = CRIU_RESP__INIT; CriuReq *req; CriuNotify cn = CRIU_NOTIFY__INIT; msg.type = CRIU_REQ_TYPE__NOTIFY; msg.success = true; msg.notify = &cn; cn.script = script; if (!strcmp(script, "setup-namespaces")) { /* * FIXME pid is required only once on * restore. Need some more sane way of * checking this. */ cn.has_pid = true; cn.pid = root_item->pid.real; } ret = send_criu_msg(fd, &msg); if (ret < 0) return ret; ret = recv_criu_msg(fd, &req); if (ret < 0) return ret; if (req->type != CRIU_REQ_TYPE__NOTIFY || !req->notify_success) { pr_err("RPC client reported script error\n"); return -1; } criu_req__free_unpacked(req, NULL); return 0; }
static int pre_dump_loop(int sk, CriuReq *msg) { int ret; do { ret = pre_dump_using_req(sk, msg->opts); if (ret < 0) return ret; criu_req__free_unpacked(msg, NULL); if (recv_criu_msg(sk, &msg) == -1) { pr_perror("Can't recv request"); return -1; } } while (msg->type == CRIU_REQ_TYPE__PRE_DUMP); if (msg->type != CRIU_REQ_TYPE__DUMP) { send_criu_err(sk, "Bad req seq"); return -1; } return dump_using_req(sk, msg->opts); }