Commit 22140b97 authored by Pavel Tikhomirov's avatar Pavel Tikhomirov Committed by Pavel Emelyanov

Add ability to restore with missing sysctls on the target node

Do it through new --weak-sysctls option to "criu restore".

When we migrate from source with newer kernel with some modern sysctl
to destination with older kernel without it or just with a kernel
configured without it (e.g. no CONFIG_IPV6_ROUTER_PREF), we face a
problem that not all of dumped sysctls can be successfuly restored
on the destination. So to address these problem introduce weak sysctls
migration, where we restore only available sysctls and skip others.

https://github.com/xemul/criu/issues/248

While on it, fix workaround for stable_secret eio skip.

travis-ci: success for Add ability to restore with missing sysctls on the target node
Signed-off-by: 's avatarPavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 26ccb06a
...@@ -281,6 +281,7 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -281,6 +281,7 @@ int main(int argc, char *argv[], char *envp[])
{ SK_INFLIGHT_PARAM, no_argument, 0, 1083 }, { SK_INFLIGHT_PARAM, no_argument, 0, 1083 },
{ "deprecated", no_argument, 0, 1084 }, { "deprecated", no_argument, 0, 1084 },
{ "display-stats", no_argument, 0, 1086 }, { "display-stats", no_argument, 0, 1086 },
{ "weak-sysctls", no_argument, 0, 1087 },
{ }, { },
}; };
...@@ -596,6 +597,10 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -596,6 +597,10 @@ int main(int argc, char *argv[], char *envp[])
case 1086: case 1086:
opts.display_stats = true; opts.display_stats = true;
break; break;
case 1087:
pr_msg("Will skip non-existant sysctls on restore\n");
opts.weak_sysctls = true;
break;
case 'V': case 'V':
pr_msg("Version: %s\n", CRIU_VERSION); pr_msg("Version: %s\n", CRIU_VERSION);
if (strcmp(CRIU_GITID, "0")) if (strcmp(CRIU_GITID, "0"))
...@@ -814,6 +819,9 @@ usage: ...@@ -814,6 +819,9 @@ usage:
" --exec-cmd execute the command specified after '--' on successful\n" " --exec-cmd execute the command specified after '--' on successful\n"
" restore making it the parent of the restored process\n" " restore making it the parent of the restored process\n"
" --freeze-cgroup use cgroup freezer to collect processes\n" " --freeze-cgroup use cgroup freezer to collect processes\n"
" --weak-sysctls silently skip restoring sysctl if it is not available,\n"
" these helps to overcome problems with restore on older\n"
" kernel or with some kernel configuration disabled\n"
"\n" "\n"
"* External resources support:\n" "* External resources support:\n"
" --external RES dump objects from this list as external resources:\n" " --external RES dump objects from this list as external resources:\n"
......
...@@ -116,6 +116,7 @@ struct cr_options { ...@@ -116,6 +116,7 @@ struct cr_options {
*/ */
bool deprecated_ok; bool deprecated_ok;
bool display_stats; bool display_stats;
bool weak_sysctls;
}; };
extern struct cr_options opts; extern struct cr_options opts;
......
...@@ -185,6 +185,9 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto ...@@ -185,6 +185,9 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto
if (n > size) if (n > size)
pr_warn("The image contains unknown sysctl-s\n"); pr_warn("The image contains unknown sysctl-s\n");
if (opts.weak_sysctls)
flags = CTL_FLAGS_OPTIONAL;
rconf = xmalloc(sizeof(SysctlEntry *) * size); rconf = xmalloc(sizeof(SysctlEntry *) * size);
if (!rconf) if (!rconf)
return -1; return -1;
...@@ -216,6 +219,7 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto ...@@ -216,6 +219,7 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto
snprintf(path[i], MAX_CONF_OPT_PATH, CONF_OPT_PATH, proto, tgt, devconfs[i]); snprintf(path[i], MAX_CONF_OPT_PATH, CONF_OPT_PATH, proto, tgt, devconfs[i]);
req[ri].name = path[i]; req[ri].name = path[i];
req[ri].flags = flags;
switch (conf[i]->type) { switch (conf[i]->type) {
case SYSCTL_TYPE__CTL_32: case SYSCTL_TYPE__CTL_32:
req[ri].type = CTL_32; req[ri].type = CTL_32;
...@@ -228,7 +232,7 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto ...@@ -228,7 +232,7 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto
break; break;
case SYSCTL_TYPE__CTL_STR: case SYSCTL_TYPE__CTL_STR:
req[ri].type = CTL_STR(MAX_STR_CONF_LEN); req[ri].type = CTL_STR(MAX_STR_CONF_LEN);
flags |= op == CTL_READ && !strcmp(devconfs[i], "stable_secret") req[ri].flags |= op == CTL_READ && !strcmp(devconfs[i], "stable_secret")
? CTL_FLAGS_READ_EIO_SKIP : 0; ? CTL_FLAGS_READ_EIO_SKIP : 0;
/* skip non-existing sysctl */ /* skip non-existing sysctl */
...@@ -240,7 +244,6 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto ...@@ -240,7 +244,6 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto
default: default:
continue; continue;
} }
req[ri].flags = flags;
rconf[ri] = conf[i]; rconf[ri] = conf[i];
ri++; ri++;
} }
......
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