[lxc-devel] [RFC 1/2] lxc-start: added --start-frozen
Wolfgang Bumiller
w.bumiller at proxmox.com
Thu Jan 14 13:30:19 UTC 2016
Add the possibility to start a container in a frozen state.
Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
---
doc/lxc-start.sgml.in | 12 ++++++++++++
src/lxc/arguments.h | 3 +++
src/lxc/conf.h | 1 +
src/lxc/lxc_start.c | 7 +++++++
src/lxc/lxccontainer.c | 16 ++++++++++++++++
src/lxc/lxccontainer.h | 10 ++++++++++
src/lxc/start.c | 17 +++++++++++++++++
7 files changed, 66 insertions(+)
diff --git a/doc/lxc-start.sgml.in b/doc/lxc-start.sgml.in
index 1770ac2..46bfcc7 100644
--- a/doc/lxc-start.sgml.in
+++ b/doc/lxc-start.sgml.in
@@ -59,6 +59,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<arg choice="opt">-s KEY=VAL</arg>
<arg choice="opt">-C</arg>
<arg choice="opt">--share-[net|ipc|uts] <replaceable>name|pid</replaceable></arg>
+ <arg choice="opt">--start-frozen</arg>
<arg choice="opt">command</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -245,6 +246,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>--start-frozen</option>
+ </term>
+ <listitem>
+ <para>
+ Freeze the container before starting its init process.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h
index 38cb0da..79a4758 100644
--- a/src/lxc/arguments.h
+++ b/src/lxc/arguments.h
@@ -81,6 +81,9 @@ struct lxc_arguments {
/* close fds from parent? */
int close_all_fds;
+ /* freeze before starting init */
+ int start_frozen;
+
/* lxc-create */
char *bdevtype, *configfile, *template;
char *fstype;
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index b0274ec..5c84f5f 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -312,6 +312,7 @@ struct lxc_conf {
struct lxc_rootfs rootfs;
char *ttydir;
int close_all_fds;
+ int start_frozen;
struct lxc_list hooks[NUM_LXC_HOOKS];
char *lsm_aa_profile;
diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c
index 6b942ac..73e27e3 100644
--- a/src/lxc/lxc_start.c
+++ b/src/lxc/lxc_start.c
@@ -53,6 +53,7 @@
#define OPT_SHARE_NET OPT_USAGE+1
#define OPT_SHARE_IPC OPT_USAGE+2
#define OPT_SHARE_UTS OPT_USAGE+3
+#define OPT_START_FROZEN OPT_USAGE+4
lxc_log_define(lxc_start_ui, lxc);
@@ -154,6 +155,7 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
case OPT_SHARE_NET: args->share_ns[LXC_NS_NET] = arg; break;
case OPT_SHARE_IPC: args->share_ns[LXC_NS_IPC] = arg; break;
case OPT_SHARE_UTS: args->share_ns[LXC_NS_UTS] = arg; break;
+ case OPT_START_FROZEN: args->start_frozen = 1; break;
}
return 0;
}
@@ -170,6 +172,7 @@ static const struct option my_longopts[] = {
{"share-net", required_argument, 0, OPT_SHARE_NET},
{"share-ipc", required_argument, 0, OPT_SHARE_IPC},
{"share-uts", required_argument, 0, OPT_SHARE_UTS},
+ {"start-frozen", no_argument, 0, OPT_START_FROZEN},
LXC_COMMON_OPTIONS
};
@@ -193,6 +196,7 @@ Options :\n\
Note: --daemon implies --close-all-fds\n\
-s, --define KEY=VAL Assign VAL to configuration variable KEY\n\
--share-[net|ipc|uts]=NAME Share a namespace with another container or pid\n\
+ --start-frozen Freeze the container before starting its init\n\
",
.options = my_longopts,
.parser = my_parser,
@@ -335,6 +339,9 @@ int main(int argc, char *argv[])
if (my_args.close_all_fds)
c->want_close_all_fds(c, true);
+ if (my_args.start_frozen)
+ c->set_start_frozen(c, true);
+
if (args == default_args)
err = c->start(c, 0, NULL) ? 0 : 1;
else
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 802a930..166f507 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -590,6 +590,21 @@ static bool do_lxcapi_want_close_all_fds(struct lxc_container *c, bool state)
WRAP_API_1(bool, lxcapi_want_close_all_fds, bool)
+static bool do_lxcapi_set_start_frozen(struct lxc_container *c, bool state)
+{
+ if (!c || !c->lxc_conf)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+ c->lxc_conf->start_frozen = state;
+ container_mem_unlock(c);
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_set_start_frozen, bool)
+
static bool do_lxcapi_wait(struct lxc_container *c, const char *state, int timeout)
{
int ret;
@@ -4074,6 +4089,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c->load_config = lxcapi_load_config;
c->want_daemonize = lxcapi_want_daemonize;
c->want_close_all_fds = lxcapi_want_close_all_fds;
+ c->set_start_frozen = lxcapi_set_start_frozen;
c->start = lxcapi_start;
c->startl = lxcapi_startl;
c->stop = lxcapi_stop;
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index 6d155a1..454f029 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -245,6 +245,16 @@ struct lxc_container {
bool (*want_close_all_fds)(struct lxc_container *c, bool state);
/*!
+ * \brief Specify whether the container wishes start in a frozen state.
+ *
+ * \param c Container.
+ * \param state Value for the start_frozen bit (0 or 1).
+ *
+ * \return \c true on success, else \c false.
+ */
+ bool (*set_start_frozen)(struct lxc_container *c, bool state);
+
+ /*!
* \brief Return current config file name.
*
* \param c Container.
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 79dbe33..84a05f9 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1343,6 +1343,23 @@ static int start(struct lxc_handler *handler, void* data)
{
struct start_args *arg = data;
+ if (handler->conf->start_frozen) {
+ char *cgfile = NULL;
+ NOTICE("freezing '%s'", arg->argv[0]);
+ /* Let the monitor know we reached this point. */
+ lxc_sync_fini_child(handler);
+ if (asprintf(&cgfile, "/sys/fs/cgroup/freezer/lxc/%s/freezer.state", handler->name) == -1) {
+ ERROR("failed to allocate memory trying to freezed container '%s'", handler->name);
+ return -1;
+ }
+ if (lxc_write_to_file(cgfile, "FROZEN", sizeof("FROZEN")-1, false) == -1) {
+ ERROR("error freezing container '%s' at startup", handler->name);
+ free(cgfile);
+ return -1;
+ }
+ free(cgfile);
+ }
+
NOTICE("exec'ing '%s'", arg->argv[0]);
execvp(arg->argv[0], arg->argv);
--
2.1.4
More information about the lxc-devel
mailing list