lxccontainer.c revision 12a50cc6ab5c8a4aa0bcb7ddcd7095265f7bb62b
290N/A * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>. 290N/A * Copyright © 2012 Canonical Ltd. 290N/A * This program is free software; you can redistribute it and/or modify 290N/A * it under the terms of the GNU General Public License version 2, as 290N/A * published by the Free Software Foundation. 290N/A * This program is distributed in the hope that it will be useful, 290N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of 290N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 290N/A * GNU General Public License for more details. 290N/A * You should have received a copy of the GNU General Public License along 290N/A * with this program; if not, write to the Free Software Foundation, Inc., 290N/A * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 290N/A * c->privlock protects the struct lxc_container from multiple threads. 290N/A * c->slock protects the on-disk container data 290N/A * NOTHING mutexes two independent programs with their own struct 290N/A * lxc_container for the same c->name, between API calls. For instance, 290N/A * c->config_read(); c->start(); Between those calls, data on disk 383N/A * could change (which shouldn't bother the caller unless for instance 290N/A * the rootfs get moved). c->config_read(); update; c->config_write(); 290N/A * Two such updaters could race. The callers should therefore check their 290N/A * results. Trying to prevent that would necessarily expose us to deadlocks 290N/A * due to hung callers. So I prefer to keep the locks only within our own 290N/A * functions, not across functions. 290N/A * If you're going to fork while holding a lxccontainer, increment 290N/A * c->numthreads (under privlock) before forking. When deleting, 465N/A * decrement numthreads under privlock, then if it hits 0 you can delete. 465N/A * Do not ever use a lxccontainer whose numthreads you did not bump. 290N/A // bail without trying to unlock, bc the privlock is now probably 395N/A /* we'll probably want to make this timeout configurable? */ 290N/A * our child is going to fork again, then exit. reap the 395N/A DEBUG(
"failed waiting for first dual-fork child");
290N/A * I can't decide if it'd be more convenient for callers if we accept '...', 290N/A * or a null-terminated array (i.e. execl vs execv) 395N/A /* container has been setup */ 506N/A /* is this app meant to be run through lxcinit, as in lxc-execute? */ 395N/A * say, I'm not sure - what locks do we want here? Any? 290N/A * Is liblxc's locking enough here to protect the on disk 395N/A * container? We don't want to exclude things like lxc_info 395N/A * while container is running... 290N/A /* second fork to be reparented by init */ 465N/A /* like daemon(), chdir to / and redirect 0,1,2 to /dev/null */ 383N/A * note there MUST be an ending NULL 422N/A /* build array of arguments if any */ 383N/A /* add trailing NULL */ 290N/A * create the standard expected container dir 613N/A * backing stores not (yet) supported 290N/A * for ->create, argv contains the arguments to pass to the template, 430N/A * terminated by NULL. If no arguments, you can just pass NULL. 395N/A /* we're going to fork. but since we'll wait for our child, we 395N/A don't need to lxc_container_get */ 395N/A SYSERROR(
"failed to fork task for container creation template\n");
691N/A * create our new array, pre-pend the template name and for (i =
3; i <
nargs; i++)
// we could set an error code and string inside the // container_struct here if we like ERROR(
"container creation template exited abnormally\n");
ERROR(
"container creation template for %s exited with %d\n",
// now clear out the lxc_conf we have, reload from the created retv = c->
wait(c,
"STOPPED", 0);
// 0 means don't wait * since we're going to wait for create to finish, I don't think we * need to get a copy of the arguments. * Support 'lxc.network.<idx>', i.e. 'lxc.network.0' * This is an intelligent result to show which keys are valid given /* default config file - should probably come through autoconf */ return false;
// should we write to stdout if no file is specified? // we could set an error code and string inside the // container_struct here if we like // assign the member functions /* we'll allow the caller to update these later */ * default configuration file is $LXCPATH/$NAME/config