cr: add container configuration header
PATCH 1/1 cr: add container configuration header
Add a container configuration section to the checkpoint header. This will contain information such as the LSM name and policy identifier, potentially network interface and container-wide mounts.
[ pulled out of the LSM c/r patchset ]
--- Documentation/checkpoint/readme.txt | 36 ++++++++++++++++++++++++++++++++-- checkpoint/checkpoint.c | 18 +++++++++++++++++ checkpoint/restart.c | 18 +++++++++++++++++ include/linux/checkpoint.h | 2 +- include/linux/checkpoint_hdr.h | 7 ++++++ 5 files changed, 77 insertions(+), 4 deletions(-)
Documentation/checkpoint/readme.txt +33 -3
@@ -161,9 +161,10 @@ in-userspace conversion tools. The general format of the checkpoint image is as follows: 1. Image header -2. Task hierarchy -3. Tasks' state -4. Image trailer +2. Container configuration +3. Task hierarchy +4. Tasks' state +5. Image trailer The image always begins with a general header that holds a magic number, an architecture identifier (little endian format), a format
@@ -172,6 +173,11 @@ version number (@rev), followed by information about the kernel checkpoint and the flags given to sys_checkpoint(). This header is followed by an arch-specific header. +The container configuration section contains details about the +security (LSM) configuration. Network configuration and +container-wide mounts may also go here, so that the userspace +restart coordinator can re-create a suitable environment. + The task hierarchy comes next so that userspace tools can read it early (even from a stream) and re-create the restarting tasks. This is basically an array of all checkpointed tasks, and their relationships
@@ -333,6 +339,30 @@ So that's why we don't want CAP_SYS_ADMIN required up-front. That way we will be forced to more carefully review each of those features. However, this can be controlled with a sysctl-variable. +LSM +=== + +Security modules use custom labels on subjects and objects to +further mediate access decisions beyond DAC controls. When +checkpoint applications, these labels are [ work in progress ] +checkpointed along with the objects. At restart, the +RESTART_KEEP_LSM flag tells the kernel whether re-created objects +whould keep their checkpointed labels, or get automatically +recalculated labels. Since checkpointed labels will only make +sense to the same LSM which was active at checkpoint time, +sys_restart() with the RESTART_KEEP_LSM flag will fail with +-EINVAL if the LSM active at restart is not the same as that +active at checkpoint. If RESTART_KEEP_LSM is not specified, +then objects will be given whatever default labels the LSM and +their optional policy decide. Of course, when RESTART_KEEP_LSM +is specified, the LSM may choose a different label than the +checkpointed one, or fail the entire restart if the caller +does not have permission to create objects with the checkpointed +label. + +It should always be safe to take a checkpoint of an application +under LSM_1, and restart it without the RESTART_KEEP_LSM flag +under LSM_2. Kernel interfaces =================
checkpoint/checkpoint.c +18 -0
@@ -354,6 +354,21 @@ static int checkpoint_write_header(struct ckpt_ctx *ctx)return checkpoint_write_header_arch (ctx); } +/* write the container configuration section */ +static int checkpoint_container (struct ckpt_ctx *ctx) +{ +struct ckpt_hdr_container *h; +int ret; + + h =ckpt_hdr_get_type (ctx,sizeof (*h),CKPT_HDR_CONTAINER ); +if (!h) +return -ENOMEM ; + ret =ckpt_write_obj (ctx, &h->h); +ckpt_hdr_put (ctx, h); + +return ret; +} +/* write the checkpoint trailer */ static int checkpoint_write_tail (struct ckpt_ctx *ctx) {
@@ -765,6 +780,9 @@ long do_checkpoint(struct ckpt_ctx *ctx, pid_t pid) ret =checkpoint_write_header (ctx);if (ret <0 ) goto out; + ret =checkpoint_container (ctx); +if (ret <0 ) + goto out; ret =checkpoint_tree (ctx);if (ret <0 ) goto out;
checkpoint/restart.c +18 -0
@@ -624,6 +624,20 @@ static int restore_read_header(struct ckpt_ctx *ctx)return ret; } +/* read the container configuration section */ +static int restore_container (struct ckpt_ctx *ctx) +{ +int ret =0 ; +struct ckpt_hdr_container *h; + + h =ckpt_read_obj_type (ctx,sizeof (*h),CKPT_HDR_CONTAINER ); +if (IS_ERR (h)) +return PTR_ERR (h); +ckpt_hdr_put (ctx, h); + +return ret; +} +/* read the checkpoint trailer */ static int restore_read_tail (struct ckpt_ctx *ctx) {
@@ -1162,6 +1176,10 @@ static int do_restore_coord(struct ckpt_ctx *ctx, pid_t pid)ckpt_debug ("restore header: %d\n" , ret);if (ret <0 )return ret; + ret =restore_container (ctx); +ckpt_debug ("restore container: %d\n" , ret); +if (ret <0 ) +return ret; ret =restore_read_tree (ctx);ckpt_debug ("restore tree: %d\n" , ret);if (ret <0 )
include/linux/checkpoint.h +1 -1
@@ -10,7 +10,7 @@* distribution for more details. */ -#define CHECKPOINT_VERSION 2 +#define CHECKPOINT_VERSION 3/* checkpoint user flags */ #define CHECKPOINT_SUBTREE 0x1
include/linux/checkpoint_hdr.h +7 -0
@@ -63,6 +63,8 @@ enum {#define CKPT_HDR_HEADER CKPT_HDR_HEADER CKPT_HDR_HEADER_ARCH,#define CKPT_HDR_HEADER_ARCH CKPT_HDR_HEADER_ARCH + CKPT_HDR_CONTAINER, +#define CKPT_HDR_CONTAINER CKPT_HDR_CONTAINER CKPT_HDR_BUFFER,#define CKPT_HDR_BUFFER CKPT_HDR_BUFFER CKPT_HDR_STRING,
@@ -247,6 +249,11 @@ struct ckpt_const {__u16 tty_termios_ncc; } __attribute__((aligned(8))); +/* container configuration section header */ +struct ckpt_hdr_container { +struct ckpt_hdr h; +}; +/* checkpoint image header */ struct ckpt_hdr_header {struct ckpt_hdr h;
Signature · 1 line
1.6.1
A message that is not in the archive (sent off-list or not yet received): 20091015184827.GA30444-r/[email protected]
PATCH 1/1 handle the container configuration section in ckpt header
--- restart.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)
restart.c +29 -0
@@ -264,6 +264,7 @@ struct ckpt_ctx {char header[BUFSIZE ];char header_arch[BUFSIZE ]; +char container[BUFSIZE ];char tree[BUFSIZE ];char buf[BUFSIZE ];struct args *args;
@@ -303,6 +304,7 @@ static int ckpt_write_obj(struct ckpt_ctx *ctx, struct ckpt_hdr *h);static int ckpt_write_header (struct ckpt_ctx *ctx);static int ckpt_write_header_arch (struct ckpt_ctx *ctx); +static int ckpt_write_container (struct ckpt_ctx *ctx);static int ckpt_write_tree (struct ckpt_ctx *ctx);static int _ckpt_read (int fd,void *buf,int count);
@@ -313,6 +315,7 @@ static int ckpt_read_obj_type(struct ckpt_ctx *ctx, void *b, int n, int type);static int ckpt_read_header (struct ckpt_ctx *ctx);static int ckpt_read_header_arch (struct ckpt_ctx *ctx); +static int ckpt_read_container (struct ckpt_ctx *ctx);static int ckpt_read_tree (struct ckpt_ctx *ctx);static int hash_init (struct ckpt_ctx *ctx);
@@ -693,6 +696,12 @@ int main(int argc, char *argv[])exit (1 ); } + ret =ckpt_read_container (&ctx); +if (ret <0 ) { +perror ("read c/r container section" ); +exit (1 ); + } + ret =ckpt_read_tree (&ctx);if (ret <0 ) {perror ("read c/r tree" );
@@ -1850,6 +1859,9 @@ static int ckpt_do_feeder(void *data)if (ckpt_write_header_arch (ctx) <0 )ckpt_abort (ctx,"write c/r header arch" ); +if (ckpt_write_container (ctx) <0 ) +ckpt_abort (ctx,"write container section" ); +if (ckpt_write_tree (ctx) <0 )ckpt_abort (ctx,"write c/r tree" );
@@ -2102,6 +2114,14 @@ static int ckpt_read_header_arch(struct ckpt_ctx *ctx)return 0 ; } +static int ckpt_read_container (struct ckpt_ctx *ctx) +{ +struct ckpt_hdr_container *h; + + h = (struct ckpt_hdr_container *) ctx->container; +return ckpt_read_obj_type (ctx, h,sizeof (*h),CKPT_HDR_CONTAINER ); +} +static int ckpt_read_tree (struct ckpt_ctx *ctx) {struct ckpt_hdr_tree *h;
@@ -2174,6 +2194,15 @@ static int ckpt_write_header_arch(struct ckpt_ctx *ctx)return ckpt_write_obj (ctx, (struct ckpt_hdr *) h); } +static int ckpt_write_container (struct ckpt_ctx *ctx) +{ +char *ptr; + + ptr = (char *) ctx->container; +/* write the container info section */ +return ckpt_write_obj (ctx, (struct ckpt_hdr *) ptr); +} +static int ckpt_write_tree (struct ckpt_ctx *ctx) {struct ckpt_hdr_tree *h;
Signature · 1 line
1.6.1.1
A message that is not in the archive (sent off-list or not yet received): 20091015184859.GA30490-r/[email protected]
Oren Laadan
AppliedRe: [PATCH user-cr] handle the container configuration section in ckpt header
Applied.
Quoted 87 lines · Serge E. Hallyn
Signed-off-by Serge E. Hallyn <serue-r/[email protected]>--- restart.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)restart.c +29
-0@@ -264,6 +264,7 @@ struct ckpt_ctx {char header[BUFSIZE ];char header_arch[BUFSIZE ]; +char container[BUFSIZE ];char tree[BUFSIZE ];char buf[BUFSIZE ];struct args *args;@@ -303,6 +304,7 @@ static int ckpt_write_obj(struct ckpt_ctx *ctx, struct ckpt_hdr *h);static int ckpt_write_header (struct ckpt_ctx *ctx);static int ckpt_write_header_arch (struct ckpt_ctx *ctx); +static int ckpt_write_container (struct ckpt_ctx *ctx);static int ckpt_write_tree (struct ckpt_ctx *ctx);static int _ckpt_read (int fd,void *buf,int count);@@ -313,6 +315,7 @@ static int ckpt_read_obj_type(struct ckpt_ctx *ctx, void *b, int n, int type);static int ckpt_read_header (struct ckpt_ctx *ctx);static int ckpt_read_header_arch (struct ckpt_ctx *ctx); +static int ckpt_read_container (struct ckpt_ctx *ctx);static int ckpt_read_tree (struct ckpt_ctx *ctx);static int hash_init (struct ckpt_ctx *ctx);@@ -693,6 +696,12 @@ int main(int argc, char *argv[])exit (1 ); } + ret =ckpt_read_container (&ctx); +if (ret <0 ) { +perror ("read c/r container section" ); +exit (1 ); + } + ret =ckpt_read_tree (&ctx);if (ret <0 ) {perror ("read c/r tree" );@@ -1850,6 +1859,9 @@ static int ckpt_do_feeder(void *data)if (ckpt_write_header_arch (ctx) <0 )ckpt_abort (ctx,"write c/r header arch" ); +if (ckpt_write_container (ctx) <0 ) +ckpt_abort (ctx,"write container section" ); +if (ckpt_write_tree (ctx) <0 )ckpt_abort (ctx,"write c/r tree" );@@ -2102,6 +2114,14 @@ static int ckpt_read_header_arch(struct ckpt_ctx *ctx)return 0 ; } +static int ckpt_read_container (struct ckpt_ctx *ctx) +{ +struct ckpt_hdr_container *h; + + h = (struct ckpt_hdr_container *) ctx->container; +return ckpt_read_obj_type (ctx, h,sizeof (*h),CKPT_HDR_CONTAINER ); +} +static int ckpt_read_tree (struct ckpt_ctx *ctx) {struct ckpt_hdr_tree *h;@@ -2174,6 +2194,15 @@ static int ckpt_write_header_arch(struct ckpt_ctx *ctx)return ckpt_write_obj (ctx, (struct ckpt_hdr *) h); } +static int ckpt_write_container (struct ckpt_ctx *ctx) +{ +char *ptr; + + ptr = (char *) ctx->container; +/* write the container info section */ +return ckpt_write_obj (ctx, (struct ckpt_hdr *) ptr); +} +static int ckpt_write_tree (struct ckpt_ctx *ctx) {struct ckpt_hdr_tree *h;
Thanks for pulling this part out. I applied it.
Note that I left out the text below about LSM - it belongs to your LSM series :)
Oren.
Quoted 187 lines · Serge E. Hallyn
Add a container configuration section to the checkpoint header. This will contain information such as the LSM name and policy identifier, potentially network interface and container-wide mounts.
[ pulled out of the LSM c/r patchset ]
Signed-off-by Serge E. Hallyn <serue-r/[email protected]>--- Documentation/checkpoint/readme.txt | 36 ++++++++++++++++++++++++++++++++-- checkpoint/checkpoint.c | 18 +++++++++++++++++ checkpoint/restart.c | 18 +++++++++++++++++ include/linux/checkpoint.h | 2 +- include/linux/checkpoint_hdr.h | 7 ++++++ 5 files changed, 77 insertions(+), 4 deletions(-)Documentation/checkpoint/readme.txt +33
-3@@ -161,9 +161,10 @@ in-userspace conversion tools. The general format of the checkpoint image is as follows: 1. Image header -2. Task hierarchy -3. Tasks' state -4. Image trailer +2. Container configuration +3. Task hierarchy +4. Tasks' state +5. Image trailer The image always begins with a general header that holds a magic number, an architecture identifier (little endian format), a format@@ -172,6 +173,11 @@ version number (@rev), followed by information about the kernel checkpoint and the flags given to sys_checkpoint(). This header is followed by an arch-specific header. +The container configuration section contains details about the +security (LSM) configuration. Network configuration and +container-wide mounts may also go here, so that the userspace +restart coordinator can re-create a suitable environment. + The task hierarchy comes next so that userspace tools can read it early (even from a stream) and re-create the restarting tasks. This is basically an array of all checkpointed tasks, and their relationships@@ -333,6 +339,30 @@ So that's why we don't want CAP_SYS_ADMIN required up-front. That way we will be forced to more carefully review each of those features. However, this can be controlled with a sysctl-variable. +LSM +=== + +Security modules use custom labels on subjects and objects to +further mediate access decisions beyond DAC controls. When +checkpoint applications, these labels are [ work in progress ] +checkpointed along with the objects. At restart, the +RESTART_KEEP_LSM flag tells the kernel whether re-created objects +whould keep their checkpointed labels, or get automatically +recalculated labels. Since checkpointed labels will only make +sense to the same LSM which was active at checkpoint time, +sys_restart() with the RESTART_KEEP_LSM flag will fail with +-EINVAL if the LSM active at restart is not the same as that +active at checkpoint. If RESTART_KEEP_LSM is not specified, +then objects will be given whatever default labels the LSM and +their optional policy decide. Of course, when RESTART_KEEP_LSM +is specified, the LSM may choose a different label than the +checkpointed one, or fail the entire restart if the caller +does not have permission to create objects with the checkpointed +label. + +It should always be safe to take a checkpoint of an application +under LSM_1, and restart it without the RESTART_KEEP_LSM flag +under LSM_2. Kernel interfaces =================checkpoint/checkpoint.c +18
-0@@ -354,6 +354,21 @@ static int checkpoint_write_header(struct ckpt_ctx *ctx)return checkpoint_write_header_arch (ctx); } +/* write the container configuration section */ +static int checkpoint_container (struct ckpt_ctx *ctx) +{ +struct ckpt_hdr_container *h; +int ret; + + h =ckpt_hdr_get_type (ctx,sizeof (*h),CKPT_HDR_CONTAINER ); +if (!h) +return -ENOMEM ; + ret =ckpt_write_obj (ctx, &h->h); +ckpt_hdr_put (ctx, h); + +return ret; +} +/* write the checkpoint trailer */ static int checkpoint_write_tail (struct ckpt_ctx *ctx) {@@ -765,6 +780,9 @@ long do_checkpoint(struct ckpt_ctx *ctx, pid_t pid) ret =checkpoint_write_header (ctx);if (ret <0 ) goto out; + ret =checkpoint_container (ctx); +if (ret <0 ) + goto out; ret =checkpoint_tree (ctx);if (ret <0 ) goto out;checkpoint/restart.c +18
-0@@ -624,6 +624,20 @@ static int restore_read_header(struct ckpt_ctx *ctx)return ret; } +/* read the container configuration section */ +static int restore_container (struct ckpt_ctx *ctx) +{ +int ret =0 ; +struct ckpt_hdr_container *h; + + h =ckpt_read_obj_type (ctx,sizeof (*h),CKPT_HDR_CONTAINER ); +if (IS_ERR (h)) +return PTR_ERR (h); +ckpt_hdr_put (ctx, h); + +return ret; +} +/* read the checkpoint trailer */ static int restore_read_tail (struct ckpt_ctx *ctx) {@@ -1162,6 +1176,10 @@ static int do_restore_coord(struct ckpt_ctx *ctx, pid_t pid)ckpt_debug ("restore header: %d\n" , ret);if (ret <0 )return ret; + ret =restore_container (ctx); +ckpt_debug ("restore container: %d\n" , ret); +if (ret <0 ) +return ret; ret =restore_read_tree (ctx);ckpt_debug ("restore tree: %d\n" , ret);if (ret <0 )include/linux/checkpoint.h +1
-1@@ -10,7 +10,7 @@* distribution for more details. */ -#define CHECKPOINT_VERSION 2 +#define CHECKPOINT_VERSION 3/* checkpoint user flags */ #define CHECKPOINT_SUBTREE 0x1include/linux/checkpoint_hdr.h +7
-0@@ -63,6 +63,8 @@ enum {#define CKPT_HDR_HEADER CKPT_HDR_HEADER CKPT_HDR_HEADER_ARCH,#define CKPT_HDR_HEADER_ARCH CKPT_HDR_HEADER_ARCH + CKPT_HDR_CONTAINER, +#define CKPT_HDR_CONTAINER CKPT_HDR_CONTAINER CKPT_HDR_BUFFER,#define CKPT_HDR_BUFFER CKPT_HDR_BUFFER CKPT_HDR_STRING,@@ -247,6 +249,11 @@ struct ckpt_const {__u16 tty_termios_ncc; } __attribute__((aligned(8))); +/* container configuration section header */ +struct ckpt_hdr_container { +struct ckpt_hdr h; +}; +/* checkpoint image header */ struct ckpt_hdr_header {struct ckpt_hdr h;