diff --git a/lib/c/criu.c b/lib/c/criu.c index de57a65dc..d052f8d1f 100644 --- a/lib/c/criu.c +++ b/lib/c/criu.c @@ -1668,3 +1668,68 @@ int criu_restore_child(void) { return criu_local_restore_child(global_opts); } + +int criu_local_get_version(criu_opts *opts) +{ + int ret = -1; + CriuReq req = CRIU_REQ__INIT; + CriuResp *resp = NULL; + + saved_errno = 0; + + req.type = CRIU_REQ_TYPE__VERSION; + req.opts = opts->rpc; + + ret = send_req_and_recv_resp(opts, &req, &resp); + if (ret) + goto exit; + + if (resp->success) { + ret = resp->version->major_number * 10000; + ret += resp->version->minor_number * 100; + if (resp->version->has_sublevel) + ret += resp->version->sublevel; + if (resp->version->gitid) { + /* Taken from runc: a git release -> minor + 1 */ + ret -= (ret % 100); + ret += 100; + } + } else { + ret = -EBADE; + } + +exit: + if (resp) + criu_resp__free_unpacked(resp, NULL); + + swrk_wait(opts); + + errno = saved_errno; + + return ret; +} + +int criu_get_version(void) +{ + return criu_local_get_version(global_opts); +} + +int criu_local_check_version(criu_opts *opts, int minimum) +{ + int version; + + version = criu_local_get_version(opts); + + if (version < 0) + return version; + + if (minimum <= version) + return 1; + + return 0; +} + +int criu_check_version(int minimum) +{ + return criu_local_check_version(global_opts, minimum); +} diff --git a/lib/c/criu.h b/lib/c/criu.h index 3a9204f5b..49f7a7005 100644 --- a/lib/c/criu.h +++ b/lib/c/criu.h @@ -158,6 +158,35 @@ int criu_restore_child(void); typedef void *criu_predump_info; int criu_dump_iters(int (*more)(criu_predump_info pi)); +/* + * Get the version of the actual binary used for RPC. + * + * As this library is just forwarding all tasks to an + * independent (of this library) CRIU binary, the actual + * version of the CRIU binary can be different then the + * hardcoded values in the libary (version.h). + * To be able to easily check the version of the CRIU binary + * the function criu_get_version() returns the version + * in the following format: + * + * (major * 10000) + (minor * 100) + sublevel + * + * If the CRIU binary has been built from a git checkout + * minor will increased by one. + */ +int criu_get_version(void); + +/* + * Check if the version of the CRIU binary is at least + * 'minimum'. Version has to be in the same format as + * described for criu_get_version(). + * + * Returns 1 if CRIU is at least 'minimum'. + * Returns 0 if CRIU is too old. + * Returns < 0 if there was an error. + */ +int criu_check_version(int minimum); + /* * Same as the list above, but lets you have your very own options * structure and lets you set individual options in it. @@ -229,6 +258,9 @@ int criu_local_restore(criu_opts *opts); int criu_local_restore_child(criu_opts *opts); int criu_local_dump_iters(criu_opts *opts, int (*more)(criu_predump_info pi)); +int criu_local_get_version(criu_opts *opts); +int criu_local_check_version(criu_opts *opts, int minimum); + #ifdef __GNUG__ } #endif