Quoting Dan Smith (danms@xxxxxxxxxx): > Read the namespace records from the restore stream and do the unshare() > necessary to create a new namespace. For UTS, set hostname and domainname > to match what was stored in the checkpoint. > > Signed-off-by: Dan Smith <danms@xxxxxxxxxx> > --- > mktree.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 66 insertions(+), 0 deletions(-) > > diff --git a/mktree.c b/mktree.c > index 55149dd..e0898db 100644 > --- a/mktree.c > +++ b/mktree.c > @@ -14,6 +14,7 @@ > #include <unistd.h> > #include <errno.h> > #include <signal.h> > +#include <sched.h> > #include <sys/types.h> > #include <sys/wait.h> > #include <asm/unistd.h> > @@ -101,6 +102,7 @@ static int cr_read_obj_type(struct cr_ctx *ctx, void *buf, int n, int type); > > static int cr_read_head(struct cr_ctx *ctx); > static int cr_read_head_arch(struct cr_ctx *ctx); > +static int cr_read_namespaces(struct cr_ctx *ctx); > static int cr_read_tree(struct cr_ctx *ctx); > > struct pid_swap { > @@ -191,6 +193,12 @@ int main(int argc, char *argv[]) > exit(1); > } > > + ret = cr_read_namespaces(&ctx); > + if (ret < 0) { > + perror("read c/r namespaces"); > + exit(1); > + } > + > ret = cr_fork_feeder(&ctx); > if (ret < 0) > exit(1); > @@ -557,6 +565,64 @@ static int cr_read_head_arch(struct cr_ctx *ctx) > return 0; > } > > +static int cr_read_task_namespaces(struct cr_ctx *ctx) > +{ > + > + struct cr_hdr_nsproxy hhn; > + struct cr_hdr_utsns hhu; > + int parent; > + > + parent = cr_read_obj_type(ctx, &hhn, sizeof(hhn), CR_HDR_NSP); > + if (parent < 0) > + return parent; > + else if (parent != 0) { > + errno = -EINVAL; > + return -1; > + } > + > + if (hhn.types == 0) > + return 0; > + > + if (unshare(CLONE_NEWUTS) != 0) { > + perror("unshare(CLONE_NEWUTS)"); > + return -1; > + } > + > + if (hhn.types & CR_NSP_UTS) { > + parent = cr_read_obj_type(ctx, &hhu, sizeof(hhu), > + CR_HDR_UTSNS); > + if (parent < 0) > + return parent; Man this reinforces the point someone (Oren?) was making about not being able to error out gracefully from a restart. If we fail right here, we're suddenly in our own uts namespace. Which coudl be fine for awhile, but could really mess with an admin's mind. Sure we could move the unshare() to after we've read all of the namespace data, but then the same thing could happen if the first step in fork_feeder fails. > + else if (parent != 0) { > + errno = -EINVAL; > + return -1; > + } > + > + cr_dbg("UTS namespace nn=%s dn=%s\n", > + hhu.nodename, > + hhu.domainname); > + > + sethostname(hhu.nodename, strlen(hhu.nodename)); > + setdomainname(hhu.domainname, strlen(hhu.domainname)); *these *shoudln't* fail (if unshare succeeded), but it's still worth checking. > + } > + > + return 0; > +} > + > +static int cr_read_namespaces(struct cr_ctx *ctx) > +{ > + int n; > + int ret = 0; > + > + for (n = 0; n < ctx->pids_nr; n++) { > + ret = cr_read_task_namespaces(ctx); > + if (ret < 0) > + break; > + } > + > + return ret; > +} > + > static int cr_read_tree(struct cr_ctx *ctx) > { > struct cr_hdr *h = (struct cr_hdr *) ctx->buf; > -- > 1.5.6.3 > > _______________________________________________ > Containers mailing list > Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx > https://lists.linux-foundation.org/mailman/listinfo/containers _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers