* [PATCH] cr: add container configuration header
@ 2009-10-15 18:48 Serge E. Hallyn
[not found] ` <20091015184827.GA30444-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 4+ messages in thread
From: Serge E. Hallyn @ 2009-10-15 18:48 UTC (permalink / raw)
To: Oren Laadan; +Cc: Linux Containers
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/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
---
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(-)
diff --git a/Documentation/checkpoint/readme.txt b/Documentation/checkpoint/readme.txt
index 571c469..3eb3dfa 100644
--- a/Documentation/checkpoint/readme.txt
+++ b/Documentation/checkpoint/readme.txt
@@ -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
=================
diff --git a/checkpoint/checkpoint.c b/checkpoint/checkpoint.c
index 5a76d2b..6eb8f3b 100644
--- a/checkpoint/checkpoint.c
+++ b/checkpoint/checkpoint.c
@@ -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;
diff --git a/checkpoint/restart.c b/checkpoint/restart.c
index 6679472..32a9fc5 100644
--- a/checkpoint/restart.c
+++ b/checkpoint/restart.c
@@ -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)
diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h
index 4b61378..914176c 100644
--- a/include/linux/checkpoint.h
+++ b/include/linux/checkpoint.h
@@ -10,7 +10,7 @@
* distribution for more details.
*/
-#define CHECKPOINT_VERSION 2
+#define CHECKPOINT_VERSION 3
/* checkpoint user flags */
#define CHECKPOINT_SUBTREE 0x1
diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h
index ca2500d..ff2e4aa 100644
--- a/include/linux/checkpoint_hdr.h
+++ b/include/linux/checkpoint_hdr.h
@@ -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;
--
1.6.1
^ permalink raw reply related [flat|nested] 4+ messages in thread[parent not found: <20091015184827.GA30444-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>]
* [PATCH user-cr] handle the container configuration section in ckpt header [not found] ` <20091015184827.GA30444-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> @ 2009-10-15 18:48 ` Serge E. Hallyn [not found] ` <20091015184859.GA30490-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> 2009-10-17 0:04 ` [PATCH] cr: add container configuration header Oren Laadan 1 sibling, 1 reply; 4+ messages in thread From: Serge E. Hallyn @ 2009-10-15 18:48 UTC (permalink / raw) To: Oren Laadan; +Cc: Linux Containers Signed-off-by: Serge E. Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> --- restart.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-) diff --git a/restart.c b/restart.c index e6e72ac..cb81293 100644 --- a/restart.c +++ b/restart.c @@ -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; -- 1.6.1.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
[parent not found: <20091015184859.GA30490-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH user-cr] handle the container configuration section in ckpt header [not found] ` <20091015184859.GA30490-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> @ 2009-10-17 0:04 ` Oren Laadan 0 siblings, 0 replies; 4+ messages in thread From: Oren Laadan @ 2009-10-17 0:04 UTC (permalink / raw) To: Serge E. Hallyn; +Cc: Linux Containers Applied. Serge E. Hallyn wrote: > Signed-off-by: Serge E. Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> > --- > restart.c | 29 +++++++++++++++++++++++++++++ > 1 files changed, 29 insertions(+), 0 deletions(-) > > diff --git a/restart.c b/restart.c > index e6e72ac..cb81293 100644 > --- a/restart.c > +++ b/restart.c > @@ -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; ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] cr: add container configuration header [not found] ` <20091015184827.GA30444-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> 2009-10-15 18:48 ` [PATCH user-cr] handle the container configuration section in ckpt header Serge E. Hallyn @ 2009-10-17 0:04 ` Oren Laadan 1 sibling, 0 replies; 4+ messages in thread From: Oren Laadan @ 2009-10-17 0:04 UTC (permalink / raw) To: Serge E. Hallyn; +Cc: Linux Containers 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. Serge E. Hallyn wrote: > 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/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> > --- > 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(-) > > diff --git a/Documentation/checkpoint/readme.txt b/Documentation/checkpoint/readme.txt > index 571c469..3eb3dfa 100644 > --- a/Documentation/checkpoint/readme.txt > +++ b/Documentation/checkpoint/readme.txt > @@ -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 > ================= > diff --git a/checkpoint/checkpoint.c b/checkpoint/checkpoint.c > index 5a76d2b..6eb8f3b 100644 > --- a/checkpoint/checkpoint.c > +++ b/checkpoint/checkpoint.c > @@ -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; > diff --git a/checkpoint/restart.c b/checkpoint/restart.c > index 6679472..32a9fc5 100644 > --- a/checkpoint/restart.c > +++ b/checkpoint/restart.c > @@ -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) > diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h > index 4b61378..914176c 100644 > --- a/include/linux/checkpoint.h > +++ b/include/linux/checkpoint.h > @@ -10,7 +10,7 @@ > * distribution for more details. > */ > > -#define CHECKPOINT_VERSION 2 > +#define CHECKPOINT_VERSION 3 > > /* checkpoint user flags */ > #define CHECKPOINT_SUBTREE 0x1 > diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h > index ca2500d..ff2e4aa 100644 > --- a/include/linux/checkpoint_hdr.h > +++ b/include/linux/checkpoint_hdr.h > @@ -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; ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-10-17 0:04 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-15 18:48 [PATCH] cr: add container configuration header Serge E. Hallyn
[not found] ` <20091015184827.GA30444-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-10-15 18:48 ` [PATCH user-cr] handle the container configuration section in ckpt header Serge E. Hallyn
[not found] ` <20091015184859.GA30490-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-10-17 0:04 ` Oren Laadan
2009-10-17 0:04 ` [PATCH] cr: add container configuration header Oren Laadan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox