[lxc-devel] [PATCH 1/1] lxc_abstract_unix_connect: accomodate containers started before Oct 28
commit aae93dd3dd20dd12c6b8f9f0490e2fb877ee3f09 fixed the command socket name to use the right pathlen instead of always passing in the max socket namelen. However, this breaks lxc-info/lxc-list/etc for containers started before that commit. So if the correct command sock name doesn't work, try the preexising one. Note we can probably undo this "after awhile". Maybe in august 2014. Signed-off-by: Serge Hallyn --- src/lxc/af_unix.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c index ab73963..6f0183d 100644 --- a/src/lxc/af_unix.c +++ b/src/lxc/af_unix.c @@ -135,6 +135,9 @@ int lxc_abstract_unix_connect(const char *path) if (connect(fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + len)) { int tmp = errno; + /* special case to connect to older containers */ + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == 0) + return fd; process_lock(); close(fd); process_unlock(); -- 1.8.3.2 -- November Webinars for C, C++, Fortran Developers Accelerate application performance with scalable programming models. Explore techniques for threading, error checking, porting, and tuning. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH 1/1] lxc_abstract_unix_connect: accomodate containers started before Oct 28
On Mon, Nov 11, 2013 at 12:34:51PM -0600, Serge Hallyn wrote: > > commit aae93dd3dd20dd12c6b8f9f0490e2fb877ee3f09 fixed the command socket > name to use the right pathlen instead of always passing in the max > socket namelen. However, this breaks lxc-info/lxc-list/etc for > containers started before that commit. So if the correct command > sock name doesn't work, try the preexising one. > > Note we can probably undo this "after awhile". Maybe in august 2014. > > Signed-off-by: Serge Hallyn Acked-by: Stéphane Graber > --- > src/lxc/af_unix.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c > index ab73963..6f0183d 100644 > --- a/src/lxc/af_unix.c > +++ b/src/lxc/af_unix.c > @@ -135,6 +135,9 @@ int lxc_abstract_unix_connect(const char *path) > > if (connect(fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, > sun_path) + len)) { > int tmp = errno; > + /* special case to connect to older containers */ > + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == 0) > + return fd; > process_lock(); > close(fd); > process_unlock(); > -- > 1.8.3.2 > > > -- > November Webinars for C, C++, Fortran Developers > Accelerate application performance with scalable programming models. Explore > techniques for threading, error checking, porting, and tuning. Get the most > from the latest Intel processors and coprocessors. See abstracts and register > http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk > ___ > Lxc-devel mailing list > Lxc-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/lxc-devel -- Stéphane Graber Ubuntu developer http://www.ubuntu.com signature.asc Description: Digital signature -- November Webinars for C, C++, Fortran Developers Accelerate application performance with scalable programming models. Explore techniques for threading, error checking, porting, and tuning. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] Protect global variables in log module via mutex
Quoting S.Çağlar Onur (cag...@10ur.org): > Log module contains multiple global variables so protect them introducing a > new mutex and serialize accessing log functions. > Also gather all locking related code into src/lxc/lxclock.c > > Signed-off-by: S.Çağlar Onur Really the log stuff should be re-thought. What should happen right now if two threads both call lxcapi_start() on containers with lxc.logfile entries? Perhaps we need two sets of log info. One for the program being used, and one for the running container. Anything done after src/lxc/start.c:lxc_start() logs to the container log info - that's anyhthing relating to container setup, container monitor stuff, hooks, and the running of the container. Anything else is done to the global log info - as that'll be shared by all threads. Hopefully someone finds this interesting enough to write a patch :) In the meantime - the infrastructure of this patch seems good, but I don't think it really achieves protection of those variables. log_fname and lxc_log_fd especially, because __lxc_log_set_file() can close/free them concurrent with other __lxc_log_set_file() runs and concurrent with lxc_log_get_file(). What do you think would be the best way to achieve that? > --- > src/lxc/log.c | 16 ++ > src/lxc/log.h | 4 +++ > src/lxc/lxclock.c | 87 > ++- > src/lxc/lxclock.h | 5 > src/lxc/utils.c | 57 +--- > 5 files changed, 100 insertions(+), 69 deletions(-) > > diff --git a/src/lxc/log.c b/src/lxc/log.c > index d6ce361..8a5c511 100644 > --- a/src/lxc/log.c > +++ b/src/lxc/log.c > @@ -265,11 +265,15 @@ static int __lxc_log_set_file(const char *fname, int > create_dirs) > return -1; > } > > + log_lock(); > lxc_log_fd = log_open(fname); > + log_unlock(); > if (lxc_log_fd == -1) > return -1; > > + log_lock(); > log_fname = strdup(fname); > + log_unlock(); > return 0; > } > > @@ -306,15 +310,19 @@ extern int lxc_log_init(const char *name, const char > *file, > return -1; > } > > + log_lock(); > lxc_loglevel_specified = 1; > lxc_priority = lxc_log_priority_to_int(priority); > + log_unlock(); > } > > + log_lock(); > lxc_log_category_lxc.priority = lxc_priority; > lxc_log_category_lxc.appender = &log_appender_logfile; > > if (!quiet) > lxc_log_category_lxc.appender->next = &log_appender_stderr; > + log_unlock(); > > if (prefix) > lxc_log_set_prefix(prefix); > @@ -322,7 +330,9 @@ extern int lxc_log_init(const char *name, const char > *file, > if (file) { > if (strcmp(file, "none") == 0) > return 0; > + log_lock(); > lxc_logfile_specified = 1; > + log_unlock(); > ret = __lxc_log_set_file(file, 1); > } else { > ret = -1; > @@ -368,8 +378,10 @@ extern int lxc_log_set_level(int level) > ERROR("invalid log priority %d", level); > return -1; > } > + log_lock(); > lxc_loglevel_specified = 1; > lxc_log_category_lxc.priority = level; > + log_unlock(); > return 0; > } > > @@ -397,7 +409,9 @@ extern int lxc_log_set_file(const char *fname) > { > if (lxc_logfile_specified) > return 0; > + log_lock(); > lxc_logfile_specified = 1; > + log_unlock(); > return __lxc_log_set_file(fname, 0); > } > > @@ -408,8 +422,10 @@ extern const char *lxc_log_get_file(void) > > extern void lxc_log_set_prefix(const char *prefix) > { > + log_lock(); > strncpy(log_prefix, prefix, sizeof(log_prefix)); > log_prefix[sizeof(log_prefix) - 1] = 0; > + log_unlock(); > } > > extern const char *lxc_log_get_prefix(void) > diff --git a/src/lxc/log.h b/src/lxc/log.h > index d3c40fb..59e8dd6 100644 > --- a/src/lxc/log.h > +++ b/src/lxc/log.h > @@ -30,6 +30,8 @@ > #include > #include > > +#include "lxclock.h" > + > #ifndef O_CLOEXEC > #define O_CLOEXEC 0200 > #endif > @@ -183,6 +185,7 @@ static inline void LXC_##PRIORITY(struct lxc_log_locinfo > *, \ > static inline void LXC_##PRIORITY(struct lxc_log_locinfo* locinfo, \ > const char* format, ...) \ > {\ > + log_lock(); \ > if (lxc_log_priority_is_enabled(acategory, \ > LXC_LOG_PRIORITY_##PRIORITY)) { \ > struct lxc_log_event evt = {\ > @@ -200,6 +203,7 @@ static inline void LXC_##PRIORITY(struct lxc_log_locinfo* > locinfo,\ > __lxc_log(a
[lxc-devel] [lxc/lxc] bdb3f4: lxc_abstract_unix_connect: accomodate containers s...
Branch: refs/heads/master Home: https://github.com/lxc/lxc Commit: bdb3f44147bc1a55a97131b4b39d42844ae4fb9e https://github.com/lxc/lxc/commit/bdb3f44147bc1a55a97131b4b39d42844ae4fb9e Author: Serge Hallyn Date: 2013-11-11 (Mon, 11 Nov 2013) Changed paths: M src/lxc/af_unix.c Log Message: --- lxc_abstract_unix_connect: accomodate containers started before Oct 28 commit aae93dd3dd20dd12c6b8f9f0490e2fb877ee3f09 fixed the command socket name to use the right pathlen instead of always passing in the max socket namelen. However, this breaks lxc-info/lxc-list/etc for containers started before that commit. So if the correct command sock name doesn't work, try the preexising one. Note we can probably undo this "after awhile". Maybe in august 2014. Signed-off-by: Serge Hallyn Acked-by: Stéphane Graber -- November Webinars for C, C++, Fortran Developers Accelerate application performance with scalable programming models. Explore techniques for threading, error checking, porting, and tuning. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] Patch [0/2] Some work on autodev, devtmpfs, and systemd stuff and all.
Hey all, Following is my promised patches for the devtempfs stuff that I discussed with Serge at LinuxPlumbers and modified by some of our discussion over the last several week. The first patch will involve adapting to using subdirectories under /dev/ in the case where /dev/ is a devtmpfs mount. The second patch includes a file to pre-configure /dev/ for lxc in order to allow for unpriv users to setup similar bind mounts to priv users and includes an lxc.service file for systemd. A minor gotcha with the second patch is that it does NOT include a file that it references, /usr/libexec/lxc/lxc-startup. This is a script I'm currently using to autoboot containers. I'm not including that script specifically because I know Stéphane is specifically looking at the startup code, which is what this does. I'll post my lxc-startup script later as my opinion of how this should be done (but it has a lot of warts for the general case). I just don't want to presume and step on whatever he's doing. This works for me on Fedora. I'm open to objections and discussion but I got no feedback from anyone other than Serge, who provided me with very valuable feedback and made me revise several things to deal with his points... Regards, Mike -- Michael H. Warfield (AI4NB) | (770) 978-7061 | m...@wittsend.com /\/\|=mhw=|\/\/ | (678) 463-0932 | http://www.wittsend.com/mhw/ NIC whois: MHW9 | An optimist believes we live in the best of all PGP Key: 0x674627FF| possible worlds. A pessimist is sure of it! signature.asc Description: This is a digitally signed message part -- November Webinars for C, C++, Fortran Developers Accelerate application performance with scalable programming models. Explore techniques for threading, error checking, porting, and tuning. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH 1/2] Setup devtmpfs and /dev for autodev bind mounts.
If autodev is not specifically set to 0 or 1, attempts to determine if systemd is being utilized and forces autodev=1 to prevent host system conflicts and collisions. If autodev is enabled and the host /dev is mounted with devtmpfs or /dev/.lxc is mounted with another file system... Each container created by a privileged user gets a /dev directory mapped off the host /dev here: /dev/.lxc/${name}.$( hash $lxcpath/$name ) Each container created by a non-privileged user gets a /dev/directory mapped off the host /dev here: /dev/.lxc/user/${name}.$( hash $lxcpath/$name ) The /dev/.lxc/user is mode 1777 to allow unpriv access. The /dev/.lxc/{containerdev} is bind mounted into the container /dev. Fallback on failure is to mount tmpfs into the container /dev. A symlink is created from $lxcpath/$name/rootfs.dev back to the /dev relative directory to provid a code consistent reference for updating container devs. --- src/lxc/conf.c | 369 ++-- src/lxc/conf.h | 4 +- src/lxc/start.c | 2 +- 3 files changed, 363 insertions(+), 12 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index a756731..d17cb2a 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -1164,20 +1165,275 @@ static int setup_rootfs_pivot_root(const char *rootfs, const char *pivotdir) return 0; } + +/* + * Note: This is a verbatum copy of what is in monitor.c. We're just + * usint it here to generate a safe subdirectory in /dev/ for the + * containers /dev/ + */ + +/* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS. + * FNV has good anti collision properties and we're not worried + * about pre-image resistance or one-way-ness, we're just trying to make + * the name unique in the 108 bytes of space we have. + */ +#define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL) +static uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval) +{ + unsigned char *bp; + + for(bp = buf; bp < (unsigned char *)buf + len; bp++) + { + /* xor the bottom with the current octet */ + hval ^= (uint64_t)*bp; + + /* gcc optimised: +* multiply by the 64 bit FNV magic prime mod 2^64 +*/ + hval += (hval << 1) + (hval << 4) + (hval << 5) + + (hval << 7) + (hval << 8) + (hval << 40); + } + + return hval; +} + +/* + * Check to see if a directory has something mounted on it and, + * if it does, return the fstype. + * + * Code largely based on detect_shared_rootfs below + * + * Returns: # of matching entries in /proc/self/mounts + * if != 0 fstype is filled with the last filesystem value. + * if == 0 no matches found, fstype unchanged. + * + * ToDo: Maybe return the mount options in another parameter... + */ + +#define LINELEN 4096 +#define MAX_FSTYPE_LEN 128 +int mount_check_fs( const char *dir, char *fstype ) +{ + char buf[LINELEN], *p; + struct stat s; + FILE *f; + int found_fs = 0; + char *p2; + + DEBUG("entering mount_check_fs for %s\n", dir); + + if ( 0 != access(dir, F_OK) || 0 != stat(dir, &s) || 0 == S_ISDIR(s.st_mode) ) { + return 0; + } + + process_lock(); + f = fopen("/proc/self/mounts", "r"); + process_unlock(); + if (!f) + return 0; + while ((p = fgets(buf, LINELEN, f))) { + p = index(buf, ' '); + if( !p ) + continue; + *p = '\0'; + p2 = p + 1; + + p = index(p2, ' '); + if( !p ) + continue; + *p = '\0'; + + /* Compare the directory in the entry to desired */ + if( strcmp( p2, dir ) ) { + continue; + } + + p2 = p + 1; + p = index( p2, ' '); + if( !p ) + continue; + *p = '\0'; + + ++found_fs; + + if( fstype ) { + strncpy( fstype, p2, MAX_FSTYPE_LEN - 1 ); + fstype [ MAX_FSTYPE_LEN - 1 ] = '\0'; + } + } + + process_lock(); + fclose(f); + process_unlock(); + + DEBUG("mount_check_fs returning %d last %s\n", found_fs, fstype); + + return found_fs; +} + +/* + * Locate a devtmpfs mount (should be on /dev) and create a container + * subdirectory on it which we can then bind mount to the container + * /dev instead of mounting a tmpfs there. + * If we fail, return NULL. + * Else return the pointer to the name buffer with the string to + * the devtmpfs subdirectory. + */ + +char *mk_devtmpfs(const char *name, char *path, const char *lxcpath) +{ + int ret; + struct stat s; + char tmp_path[MAXPATHLE
[lxc-devel] [PATCH 2/2] Support files for systemd on Fedora.
Added a file "lxc.service" for a systemd service file. Added a file "lxc-devsetup" to setup /dev/ on startup to support autodev in containers. Service file references lxc-devsetup as an ExecStartPre command. The lxc-devsetup script is not dependent on systemd or Fedora and can be used at bootup on any system. Modified lxc.spec.in to install the two new files on Fedora. The systemd specific code in the lxc.spec file may need some review and conditionalize for systemd on non-systemd rpm-based systems. --- lxc.spec.in | 8 src/lxc/lxc-devsetup | 26 ++ src/lxc/lxc.service | 18 ++ 3 files changed, 52 insertions(+) create mode 100755 src/lxc/lxc-devsetup create mode 100644 src/lxc/lxc.service diff --git a/lxc.spec.in b/lxc.spec.in index a6c96a2..3ef5881 100644 --- a/lxc.spec.in +++ b/lxc.spec.in @@ -102,6 +102,11 @@ rm -rf %{buildroot} make install DESTDIR=%{buildroot} find %{buildroot} -type f -name '*.la' -exec rm -f {} ';' +# Install some of our systemd stuff... +install -d -m 755 %{buildroot}/lib/systemd/system +install -c -m 644 src/lxc/lxc.service %{buildroot}/lib/systemd/system +install -c -m 755 src/lxc/lxc-devsetup %{buildroot}/%{_libexecdir}/%{name} + %clean rm -rf %{buildroot} @@ -131,6 +136,8 @@ rm -rf %{buildroot} %{_datadir}/lxc/* %config(noreplace) %{_sysconfdir}/lxc/* +/lib/systemd/system/* + %files libs %defattr(-,root,root) %{_libdir}/*.so.* @@ -140,6 +147,7 @@ rm -rf %{buildroot} %endif %{_localstatedir}/* %attr(4555,root,root) %{_libexecdir}/%{name}/lxc-init +%attr(555,root,root) %{_libexecdir}/%{name}/lxc-devsetup %if %{with_lua} %files lua diff --git a/src/lxc/lxc-devsetup b/src/lxc/lxc-devsetup new file mode 100755 index 000..583a001 --- /dev/null +++ b/src/lxc/lxc-devsetup @@ -0,0 +1,26 @@ +#!/bin/sh - + +# lxc.devsetup - Setup host /dev for container /dev subdirectories. + +if [[ ! -d /dev/.lxc ]] +then +echo "Creating /dev/.lxc" +mkdir /dev/.lxc +chmod 755 /dev/.lxc +fi + +if grep -q "/dev devtmpfs " /proc/self/mounts +then +echo "/dev is devtmpfs" +else +echo "/dev is not devtmpfs - mounting tmpfs on .lxc" +mount -t tmpfs tmpfs /dev/.lxc +fi + +if [[ ! -d /dev/.lxc/user ]] +then +echo "Creating /dev/.lxc/user" +mkdir /dev/.lxc/user +chmod 1777 /dev/.lxc/user +fi + diff --git a/src/lxc/lxc.service b/src/lxc/lxc.service new file mode 100644 index 000..d3d3238 --- /dev/null +++ b/src/lxc/lxc.service @@ -0,0 +1,18 @@ +[Unit] +Description=LXC Container Initialization and Autoboot Code +After=syslog.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStartPre=/usr/libexec/lxc/lxc-devsetup +ExecStart=/usr/libexec/lxc/lxc-startup start +ExecStop=/usr/libexec/lxc/lxc-startup stop +# Environment=BOOTUP=serial +# Environment=CONSOLETYPE=serial +StandardOutput=syslog +StandardError=syslog + +[Install] +WantedBy=multi-user.target + -- 1.8.3.1 -- Michael H. Warfield (AI4NB) | (770) 978-7061 | m...@wittsend.com /\/\|=mhw=|\/\/ | (678) 463-0932 | http://www.wittsend.com/mhw/ NIC whois: MHW9 | An optimist believes we live in the best of all PGP Key: 0x674627FF| possible worlds. A pessimist is sure of it! signature.asc Description: This is a digitally signed message part -- November Webinars for C, C++, Fortran Developers Accelerate application performance with scalable programming models. Explore techniques for threading, error checking, porting, and tuning. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] Not a Patch: 03/02... The follow-on script...
Ok all... This is my 3rd piece. It's "my script" that runs with "my setup" to start up containers at boot with systemd on Fedora. I don't want to step on the valuable work that Stéphane is doing in this area but I hope this provides him with ideas. Installed in /usr/libexec/lxc/lxc-startup, it provides the additional functionality to start containers when Fedora restarts. Out of respect for other people's work right now, I'm not offering this as a patch to the source tree. It's just a suggestion how I would do this. There are a lot of things in this script that is very maliable and it depends on a couple of things that need to be refined (such as LXC_PATH). In this script, a formalized way of obtaining a list of containers (and configuration files) qualified to be autobooted would be good. I currently use the output of lxc-ls in combination of an arbitrary LCM_PATH of /var/lib/lxc, neither of which may be optimal Offered with the proviso that "it works for me"... Attached below the jump. Regards, Mike -- Michael H. Warfield (AI4NB) | (770) 978-7061 | m...@wittsend.com /\/\|=mhw=|\/\/ | (678) 463-0932 | http://www.wittsend.com/mhw/ NIC whois: MHW9 | An optimist believes we live in the best of all PGP Key: 0x674627FF| possible worlds. A pessimist is sure of it! -- #!/bin/sh - # lxc-startup # Start up a list of containers... # lxc-run [-b] [-f] [-h] [vm list] # Wrapper script to run a bunch of containers optionally at boot time # #-l n: Boot all stopped containers with bootlevel >= n #: default 0 #-b : Only start the container if onboot is true #: equivalent to "-l 1" (also sets -q) #-F : Force boot a container even if disabled is true #: equivalent to "-l -1" #-h : Print this message and exit #-q : Quiet (disable ECHO) #-v : Enable debug prints (enable ECHO) #-n : Optional individual VM (maybe be used multiple times) # [vm list] - list of VM's to start. Default is any that are not disabled. # # Authors: # Michael H. Warfield # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA declare -i VERBOSITY=1 START_LEVEL=0 LASTCONFIG=undefined # Not sure what the deal is but it seems to be a problem if we # start kicking off containers too soon and this is non-blocking # anyways, so let's just give the system a little time to catch # it's breath before kicking these babies off... # This is a variable to start next delay and is fed from the configuration # files... # # This sets the initial delay... DELAY=5 DELAY_DEFAULT=2 # A few generic ECHO commands for verbosity... # Most of these are not currently used... ECHO_OFF=": echo" ECHO=": echo" ECHO1=": echo" ECHO2=": echo" ECHO3=": echo" ECHO4=": echo" # BOOTLIST will be a newline delimited prioritized list of our # containers to be processed. # # Currently, this list is space delimited. This is not good if # we allow white space in container names or paths. A '/' may # be better as a delimiter just because it screws up pathnames # and nobody in their right mind would use it in a name. # # Fields: # Priority # Post Start Delay # Container Name # Container Config file BOOTLIST= function usage() { echo "usage: $0 [-b] [-F] [-h] [-q] [-v] [-l n] [-n VM] [--] [VM list]" } function help() { usage echo " Run one or more containers with a halt monitor Register a new container if necessary Options: -b : Only start the container if lxc.onboot is true -F : Force boot a container even if lxc.disabled is true -l n: Boot containers with bootlevel >= n -h : Print this message and exit -q : Quiet (disable ECHO) -v : Enable debug prints (enable ECHO) -n : Optional individual VM (maybe be used multiple times) VM list : Optional list of VM's to start If the list of VM names is empty, it defaults to all available subject to boot and force options. " } # Rotate log based on date # argvs == logfile to rotate... function log_rotate() { local STAMP=$(date +%F-%T) while [[ ${1} != "" ]] do local FNAME=$1 if [[ ${FNAME} != "" && -f ${FNAME} && ! -f ${FNAME}-${STAMP} ]]