Attached is a simple program that uses the clone() function to create a
container. This is not intended as a patch - just an example of what
creating a Linux Container looks like. Something along these lines will
be used by the Linux Container driver to start the domain. The code run
within this container is really simple. It just mounts the /proc file
system and then dumps the ps output to a file showing that the container
is in separate process space.
To run this you will need to have PID namespaces support enabled. Turn
on CONFIG_PID_NS when compiling the kernel. You must run the program as
root or the clone() call will fail.
Any questions or comments are welcome. Thanks!
--
Best Regards,
Dave Leskovec
IBM Linux Technology Center
Open Virtualization
/*
* Copyright IBM Corp. 2008
*
* lxc_exec.c: example on creating a linux container
*
* Authors:
* David L. Leskovec <dlesko at linux.vnet.ibm.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* System includes */
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <unistd.h>
/* Supporting includes */
/* Component includes */
/* Defines */
/* These will eventually be defined in clone.h */
#define CLONE_NEWPID 0x20000000
#define CLONE_NEWNS 0x00020000
/* Global Variables */
/* Types and structs */
/* Functions */
static void
exec_child()
{
FILE *cdfp;
int rc;
cdfp = fopen("/tmp/child.log", "w");
if (cdfp == NULL)
{
/* Log to syslog */
exit(1);
}
/* mount /proc */
rc = mount("lxcproc", "/proc", "proc", 0, NULL);
if(0 != rc)
{
fprintf(cdfp, "mount failed with rc = %d and errno = %d\n", rc, errno);
fflush(cdfp);
exit(1);
}
else
{
fprintf(cdfp, "mount successful\n"); fflush(cdfp);
}
system("ps -aef > /tmp/container_ps.out");
/* sleep a bit just so we don't exit right away */
sleep(10);
fclose(cdfp);
}
int main(int argc, char *argv[])
{
FILE *dfp;
int cpid;
void *childstack, *stack;
int flags;
int stacksize = getpagesize() * 4;
dfp = fopen("/tmp/parent.log", "w");
if(dfp == NULL)
{
perror("parent.log");
exit(1);
}
/* allocate a stack for the container */
stack = malloc(stacksize);
if(!stack)
{
fprintf(dfp, "malloc() failed, %s\n", strerror(errno));
fflush(dfp);
exit(1);
}
/* point to "top" of stack */
childstack = stack + stacksize;
/* call clone to create the container */
flags = CLONE_NEWPID|CLONE_NEWNS;
fprintf(dfp, "Parent: Clone() flags %lx, pagesize %d...\n",
flags, getpagesize());
fflush(dfp);
cpid = clone(exec_child, childstack, flags, (void *)argv);
printf("cpid: %d\n", cpid);
if(cpid < 0)
{
fprintf(dfp, "Parent: clone() failed, %s\n",
strerror(errno));
fflush(dfp);
exit(1);
}
fprintf(dfp, "Parent sleeping, 20 seconds\n"); fflush(dfp);
sleep(20);
return 0;
}